first commit
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
using System.Collections;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.DialogueTrees
|
||||
{
|
||||
|
||||
[Name("Task Action")]
|
||||
[Description("Execute an Action Task for the Dialogue Actor selected.")]
|
||||
public class ActionNode : DTNode, ITaskAssignable<ActionTask>
|
||||
{
|
||||
|
||||
[SerializeField]
|
||||
private ActionTask _action;
|
||||
|
||||
public ActionTask action {
|
||||
get { return _action; }
|
||||
set { _action = value; }
|
||||
}
|
||||
|
||||
public Task task {
|
||||
get { return action; }
|
||||
set { action = (ActionTask)value; }
|
||||
}
|
||||
|
||||
public override bool requireActorSelection { get { return true; } }
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard bb) {
|
||||
|
||||
if ( action == null ) {
|
||||
return Error("Action is null on Dialogue Action Node");
|
||||
}
|
||||
|
||||
status = Status.Running;
|
||||
StartCoroutine(UpdateAction(finalActor.transform));
|
||||
return status;
|
||||
}
|
||||
|
||||
IEnumerator UpdateAction(Component actionAgent) {
|
||||
while ( status == Status.Running ) {
|
||||
var actionStatus = action.Execute(actionAgent, graphBlackboard);
|
||||
if ( actionStatus != Status.Running ) {
|
||||
OnActionEnd(actionStatus == Status.Success ? true : false);
|
||||
yield break;
|
||||
}
|
||||
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
void OnActionEnd(bool success) {
|
||||
|
||||
if ( success ) {
|
||||
status = Status.Success;
|
||||
DLGTree.Continue();
|
||||
return;
|
||||
}
|
||||
|
||||
status = Status.Failure;
|
||||
DLGTree.Stop(false);
|
||||
}
|
||||
|
||||
protected override void OnReset() {
|
||||
if ( action != null )
|
||||
action.EndAction(null);
|
||||
}
|
||||
|
||||
public override void OnGraphPaused() {
|
||||
if ( action != null )
|
||||
action.Pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 856f5f12f2d3c4541a8a36720cb3bdcf
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 14914
|
||||
packageName: NodeCanvas
|
||||
packageVersion: 3.3.1
|
||||
assetPath: Assets/ParadoxNotion/NodeCanvas/Modules/DialogueTrees/Nodes/ActionNode.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,59 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.DialogueTrees
|
||||
{
|
||||
|
||||
[ParadoxNotion.Design.Icon("Condition")]
|
||||
[Name("Task Condition")]
|
||||
[Category("Branch")]
|
||||
[Description("Execute the first child node if a Condition is true, or the second one if that Condition is false. The Actor selected is used for the Condition check")]
|
||||
[Color("b3ff7f")]
|
||||
public class ConditionNode : DTNode, ITaskAssignable<ConditionTask>
|
||||
{
|
||||
|
||||
[SerializeField]
|
||||
private ConditionTask _condition;
|
||||
|
||||
public ConditionTask condition {
|
||||
get { return _condition; }
|
||||
set { _condition = value; }
|
||||
}
|
||||
|
||||
public Task task {
|
||||
get { return condition; }
|
||||
set { condition = (ConditionTask)value; }
|
||||
}
|
||||
|
||||
public override int maxOutConnections { get { return 2; } }
|
||||
public override bool requireActorSelection { get { return true; } }
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard bb) {
|
||||
|
||||
if ( outConnections.Count == 0 ) {
|
||||
return Error("There are no connections on the Dialogue Condition Node");
|
||||
}
|
||||
|
||||
if ( condition == null ) {
|
||||
return Error("There is no Conidition on the Dialoge Condition Node");
|
||||
}
|
||||
|
||||
var isSuccess = condition.CheckOnce(finalActor.transform, graphBlackboard);
|
||||
status = isSuccess ? Status.Success : Status.Failure;
|
||||
DLGTree.Continue(isSuccess ? 0 : 1);
|
||||
return status;
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
public override string GetConnectionInfo(int i) {
|
||||
return i == 0 ? "Then" : "Else";
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01a3a97a8a25c2441aa667aa238c0486
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 14914
|
||||
packageName: NodeCanvas
|
||||
packageVersion: 3.3.1
|
||||
assetPath: Assets/ParadoxNotion/NodeCanvas/Modules/DialogueTrees/Nodes/ConditionNode.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,44 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.DialogueTrees
|
||||
{
|
||||
|
||||
[Name("FINISH")]
|
||||
[Category("Control")]
|
||||
[Description("End the dialogue in Success or Failure.\nNote: A Dialogue will anyway End in Succcess if it has reached a node without child connections. Thus this node is mostly useful if you want to end a Dialogue in Failure.")]
|
||||
[ParadoxNotion.Design.Icon("Halt")]
|
||||
[Color("6ebbff")]
|
||||
public class FinishNode : DTNode
|
||||
{
|
||||
|
||||
public CompactStatus finishState = CompactStatus.Success;
|
||||
|
||||
public override int maxOutConnections { get { return 0; } }
|
||||
public override bool requireActorSelection { get { return false; } }
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard bb) {
|
||||
status = (Status)finishState;
|
||||
DLGTree.Stop(finishState == CompactStatus.Success ? true : false);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
protected override void OnNodeGUI() {
|
||||
GUILayout.Label("<b>" + finishState.ToString() + "</b>");
|
||||
}
|
||||
|
||||
protected override void OnNodeInspectorGUI() {
|
||||
DrawDefaultInspector();
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31be30c3adfc6af4a8c0750caaafa770
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 14914
|
||||
packageName: NodeCanvas
|
||||
packageVersion: 3.3.1
|
||||
assetPath: Assets/ParadoxNotion/NodeCanvas/Modules/DialogueTrees/Nodes/FinishNode.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,40 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NodeCanvas.DialogueTrees
|
||||
{
|
||||
|
||||
[Name("JUMP")]
|
||||
[Description("Select a target node to jump to.\nFor your convenience in identifying nodes in the dropdown, please give a Tag name to the nodes you want to use in this way.")]
|
||||
[Category("Control")]
|
||||
[ParadoxNotion.Design.Icon("Set")]
|
||||
[Color("6ebbff")]
|
||||
public class Jumper : DTNode, IHaveNodeReference
|
||||
{
|
||||
[ParadoxNotion.Serialization.FullSerializer.fsSerializeAs("_sourceNodeUID")]
|
||||
public NodeReference<DTNode> _targetNode;
|
||||
|
||||
INodeReference IHaveNodeReference.targetReference => _targetNode;
|
||||
private DTNode target => _targetNode?.Get(graph);
|
||||
|
||||
public override int maxOutConnections { get { return 0; } }
|
||||
public override bool requireActorSelection { get { return false; } }
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard bb) {
|
||||
if ( target == null ) { return Error("Target Node of Jumper node is null"); }
|
||||
DLGTree.EnterNode(target);
|
||||
return Status.Success;
|
||||
}
|
||||
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
protected override void OnNodeGUI() {
|
||||
GUILayout.Label(string.Format("<b>{0}</b>", target != null ? target.ToString() : "NONE"));
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f8c3b37a66cf2a241ae31bbde152af4d
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 14914
|
||||
packageName: NodeCanvas
|
||||
packageVersion: 3.3.1
|
||||
assetPath: Assets/ParadoxNotion/NodeCanvas/Modules/DialogueTrees/Nodes/Jumper.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,187 @@
|
||||
using System.Collections.Generic;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.DialogueTrees
|
||||
{
|
||||
|
||||
[ParadoxNotion.Design.Icon("List")]
|
||||
[Name("Multiple Choice")]
|
||||
[Category("Branch")]
|
||||
[Description("Prompt a Dialogue Multiple Choice. A choice will be available if the choice condition(s) are true or there is no choice conditions. The Actor selected is used for the condition checks and will also Say the selection if the option is checked.")]
|
||||
[Color("b3ff7f")]
|
||||
public class MultipleChoiceNode : DTNode
|
||||
{
|
||||
|
||||
[System.Serializable]
|
||||
public class Choice
|
||||
{
|
||||
public bool isUnfolded = true;
|
||||
public Statement statement;
|
||||
public ConditionTask condition;
|
||||
public Choice() { }
|
||||
public Choice(Statement statement) {
|
||||
this.statement = statement;
|
||||
}
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
|
||||
[SliderField(0f, 10f)]
|
||||
public float availableTime;
|
||||
public bool saySelection;
|
||||
|
||||
[SerializeField, AutoSortWithChildrenConnections]
|
||||
private List<Choice> availableChoices = new List<Choice>();
|
||||
|
||||
public override int maxOutConnections { get { return availableChoices.Count; } }
|
||||
public override bool requireActorSelection { get { return true; } }
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard bb) {
|
||||
|
||||
if ( outConnections.Count == 0 ) {
|
||||
return Error("There are no connections to the Multiple Choice Node!");
|
||||
}
|
||||
|
||||
var finalOptions = new Dictionary<IStatement, int>();
|
||||
|
||||
for ( var i = 0; i < availableChoices.Count; i++ ) {
|
||||
var condition = availableChoices[i].condition;
|
||||
if ( condition == null || condition.CheckOnce(finalActor.transform, bb) ) {
|
||||
var tempStatement = availableChoices[i].statement.BlackboardReplace(bb);
|
||||
finalOptions[tempStatement] = i;
|
||||
}
|
||||
}
|
||||
|
||||
if ( finalOptions.Count == 0 ) {
|
||||
ParadoxNotion.Services.Logger.Log("Multiple Choice Node has no available options. Dialogue Ends.", LogTag.EXECUTION, this);
|
||||
DLGTree.Stop(false);
|
||||
return Status.Failure;
|
||||
}
|
||||
|
||||
var optionsInfo = new MultipleChoiceRequestInfo(finalActor, finalOptions, availableTime, OnOptionSelected);
|
||||
optionsInfo.showLastStatement = true;
|
||||
DialogueTree.RequestMultipleChoices(optionsInfo);
|
||||
return Status.Running;
|
||||
}
|
||||
|
||||
void OnOptionSelected(int index) {
|
||||
|
||||
status = Status.Success;
|
||||
|
||||
System.Action Finalize = () => { DLGTree.Continue(index); };
|
||||
|
||||
if ( saySelection ) {
|
||||
var tempStatement = availableChoices[index].statement.BlackboardReplace(graphBlackboard);
|
||||
var speechInfo = new SubtitlesRequestInfo(finalActor, tempStatement, Finalize);
|
||||
DialogueTree.RequestSubtitles(speechInfo);
|
||||
} else {
|
||||
Finalize();
|
||||
}
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
public override void OnConnectionInspectorGUI(int i) {
|
||||
if ( i >= 0 ) { DoChoiceGUI(availableChoices[i]); }
|
||||
}
|
||||
|
||||
public override string GetConnectionInfo(int i) {
|
||||
if ( i >= availableChoices.Count ) {
|
||||
return "NOT SET";
|
||||
}
|
||||
var text = string.Format("'{0}'", availableChoices[i].statement.text);
|
||||
if ( availableChoices[i].condition == null ) {
|
||||
return text;
|
||||
}
|
||||
return string.Format("{0}\n{1}", text, availableChoices[i].condition.summaryInfo);
|
||||
}
|
||||
|
||||
protected override void OnNodeGUI() {
|
||||
|
||||
if ( availableChoices.Count == 0 ) {
|
||||
GUILayout.Label("No Options Available");
|
||||
return;
|
||||
}
|
||||
|
||||
for ( var i = 0; i < availableChoices.Count; i++ ) {
|
||||
var choice = availableChoices[i];
|
||||
var connection = i < outConnections.Count ? outConnections[i] : null;
|
||||
GUILayout.BeginHorizontal(Styles.roundedBox);
|
||||
GUILayout.Label(string.Format("{0} {1}", connection != null ? "■" : "□", choice.statement.text.CapLength(30)), Styles.leftLabel);
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
if ( availableTime > 0 ) {
|
||||
GUILayout.Label(availableTime + "' Seconds");
|
||||
}
|
||||
if ( saySelection ) {
|
||||
GUILayout.Label("Say Selection");
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
protected override void OnNodeInspectorGUI() {
|
||||
|
||||
base.OnNodeInspectorGUI();
|
||||
|
||||
if ( GUILayout.Button("Add Choice") ) {
|
||||
availableChoices.Add(new Choice(new Statement("I am a choice...")));
|
||||
}
|
||||
|
||||
if ( availableChoices.Count == 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
EditorUtils.ReorderableList(availableChoices, (i, picked) =>
|
||||
{
|
||||
var choice = availableChoices[i];
|
||||
GUILayout.BeginHorizontal("box");
|
||||
|
||||
var text = string.Format("{0} {1}", choice.isUnfolded ? "▼ " : "► ", choice.statement.text);
|
||||
if ( GUILayout.Button(text, (GUIStyle)"label", GUILayout.Width(0), GUILayout.ExpandWidth(true)) ) {
|
||||
choice.isUnfolded = !choice.isUnfolded;
|
||||
}
|
||||
|
||||
if ( GUILayout.Button("X", GUILayout.Width(20)) ) {
|
||||
availableChoices.RemoveAt(i);
|
||||
if ( i < outConnections.Count ) {
|
||||
graph.RemoveConnection(outConnections[i]);
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if ( choice.isUnfolded ) {
|
||||
DoChoiceGUI(choice);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void DoChoiceGUI(Choice choice) {
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Space(10);
|
||||
GUILayout.BeginVertical("box");
|
||||
|
||||
choice.statement.text = UnityEditor.EditorGUILayout.TextField(choice.statement.text);
|
||||
choice.statement.audio = UnityEditor.EditorGUILayout.ObjectField("Audio File", choice.statement.audio, typeof(AudioClip), false) as AudioClip;
|
||||
choice.statement.meta = UnityEditor.EditorGUILayout.TextField("Meta Data", choice.statement.meta);
|
||||
|
||||
NodeCanvas.Editor.TaskEditor.TaskFieldMulti<ConditionTask>(choice.condition, graph, (c) => { choice.condition = c; });
|
||||
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Space(10);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ff3d8c33a9aa7f349b04870043553f39
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 14914
|
||||
packageName: NodeCanvas
|
||||
packageVersion: 3.3.1
|
||||
assetPath: Assets/ParadoxNotion/NodeCanvas/Modules/DialogueTrees/Nodes/MultipleChoiceNode.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,66 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
|
||||
namespace NodeCanvas.DialogueTrees
|
||||
{
|
||||
|
||||
[ParadoxNotion.Design.Icon("Selector")]
|
||||
[Name("Multiple Task Condition")]
|
||||
[Category("Branch")]
|
||||
[Description("Will continue with the first child node which condition returns true. The Dialogue Actor selected will be used for the checks")]
|
||||
[Color("b3ff7f")]
|
||||
public class MultipleConditionNode : DTNode
|
||||
{
|
||||
|
||||
[SerializeField, AutoSortWithChildrenConnections]
|
||||
private List<ConditionTask> conditions = new List<ConditionTask>();
|
||||
|
||||
public override int maxOutConnections {
|
||||
get { return -1; }
|
||||
}
|
||||
|
||||
public override void OnChildConnected(int index) {
|
||||
if ( conditions.Count < outConnections.Count ) {
|
||||
conditions.Insert(index, null);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnChildDisconnected(int index) {
|
||||
conditions.RemoveAt(index);
|
||||
}
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard bb) {
|
||||
|
||||
if ( outConnections.Count == 0 ) {
|
||||
return Error("There are no connections on the Dialogue Condition Node");
|
||||
}
|
||||
|
||||
for ( var i = 0; i < outConnections.Count; i++ ) {
|
||||
if ( conditions[i] == null || conditions[i].CheckOnce(finalActor.transform, graphBlackboard) ) {
|
||||
DLGTree.Continue(i);
|
||||
return Status.Success;
|
||||
}
|
||||
}
|
||||
|
||||
ParadoxNotion.Services.Logger.LogWarning("No condition is true. Dialogue Ends.", LogTag.EXECUTION, this);
|
||||
DLGTree.Stop(false);
|
||||
return Status.Failure;
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
public override void OnConnectionInspectorGUI(int i) {
|
||||
NodeCanvas.Editor.TaskEditor.TaskFieldMulti<ConditionTask>(conditions[i], DLGTree, (c) => { conditions[i] = c; });
|
||||
}
|
||||
|
||||
public override string GetConnectionInfo(int i) {
|
||||
return conditions[i] != null ? conditions[i].summaryInfo : "TRUE";
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1c9cd1de76869e34a8da4b5ddd595fc6
|
||||
timeCreated: 1433450910
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 14914
|
||||
packageName: NodeCanvas
|
||||
packageVersion: 3.3.1
|
||||
assetPath: Assets/ParadoxNotion/NodeCanvas/Modules/DialogueTrees/Nodes/MultipleConditionNode.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,130 @@
|
||||
using System.Collections.Generic;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.DialogueTrees
|
||||
{
|
||||
|
||||
[Category("Branch")]
|
||||
[Description("Select a child to execute based on it's chance to be selected. An optional pre-Condition Task can be assigned to filter the child in or out of the selection probability.\nThe actor selected will be used for the condition checks.")]
|
||||
[ParadoxNotion.Design.Icon("ProbabilitySelector")]
|
||||
[Color("b3ff7f")]
|
||||
public class ProbabilitySelector : DTNode
|
||||
{
|
||||
|
||||
public class Option
|
||||
{
|
||||
public BBParameter<float> weight;
|
||||
public ConditionTask condition;
|
||||
public Option(float weightValue, IBlackboard bbValue) {
|
||||
weight = new BBParameter<float> { value = weightValue, bb = bbValue };
|
||||
condition = null;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField, AutoSortWithChildrenConnections]
|
||||
private List<Option> childOptions = new List<Option>();
|
||||
private List<int> successIndeces;
|
||||
|
||||
public override int maxOutConnections { get { return -1; } }
|
||||
|
||||
public override void OnChildConnected(int index) {
|
||||
if ( childOptions.Count < outConnections.Count ) {
|
||||
childOptions.Insert(index, new Option(1, graphBlackboard));
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnChildDisconnected(int index) {
|
||||
childOptions.RemoveAt(index);
|
||||
}
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
successIndeces = new List<int>();
|
||||
for ( var i = 0; i < outConnections.Count; i++ ) {
|
||||
var condition = childOptions[i].condition;
|
||||
if ( condition == null || condition.CheckOnce(finalActor.transform, blackboard) ) {
|
||||
successIndeces.Add(i);
|
||||
}
|
||||
}
|
||||
|
||||
var probability = Random.Range(0f, GetTotal());
|
||||
for ( var i = 0; i < outConnections.Count; i++ ) {
|
||||
|
||||
if ( !successIndeces.Contains(i) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( probability > childOptions[i].weight.value ) {
|
||||
probability -= childOptions[i].weight.value;
|
||||
continue;
|
||||
}
|
||||
|
||||
DLGTree.Continue(i);
|
||||
return Status.Success;
|
||||
}
|
||||
|
||||
return Status.Failure;
|
||||
}
|
||||
|
||||
float GetTotal() {
|
||||
var total = 0f;
|
||||
for ( var i = 0; i < childOptions.Count; i++ ) {
|
||||
var option = childOptions[i];
|
||||
if ( successIndeces == null || successIndeces.Contains(i) ) {
|
||||
total += option.weight.value;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
protected override void OnReset() {
|
||||
successIndeces = null;
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
public override string GetConnectionInfo(int i) {
|
||||
var result = childOptions[i].condition != null ? childOptions[i].condition.summaryInfo + "\n" : string.Empty;
|
||||
if ( successIndeces == null || successIndeces.Contains(i) ) {
|
||||
return result + Mathf.Round(( childOptions[i].weight.value / GetTotal() ) * 100) + "%";
|
||||
}
|
||||
return result + "Condition Failed";
|
||||
}
|
||||
|
||||
public override void OnConnectionInspectorGUI(int i) {
|
||||
DrawOptionGUI(i, GetTotal());
|
||||
}
|
||||
|
||||
protected override void OnNodeInspectorGUI() {
|
||||
|
||||
base.OnNodeInspectorGUI();
|
||||
|
||||
if ( outConnections.Count == 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var total = GetTotal();
|
||||
for ( var i = 0; i < childOptions.Count; i++ ) {
|
||||
EditorUtils.BoldSeparator();
|
||||
DrawOptionGUI(i, total);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawOptionGUI(int i, float total) {
|
||||
NodeCanvas.Editor.TaskEditor.TaskFieldMulti<ConditionTask>(childOptions[i].condition, DLGTree, (c) => { childOptions[i].condition = c; });
|
||||
EditorUtils.Separator();
|
||||
GUILayout.BeginHorizontal();
|
||||
NodeCanvas.Editor.BBParameterEditor.ParameterField("Weight", childOptions[i].weight);
|
||||
GUILayout.Label(Mathf.Round(( childOptions[i].weight.value / total ) * 100) + "%", GUILayout.Width(38));
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1229722465d0df44d958255cff25c013
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 14914
|
||||
packageName: NodeCanvas
|
||||
packageVersion: 3.3.1
|
||||
assetPath: Assets/ParadoxNotion/NodeCanvas/Modules/DialogueTrees/Nodes/ProbabilitySelector.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,41 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.DialogueTrees
|
||||
{
|
||||
|
||||
[Name("Say")]
|
||||
[Description("Make the selected Dialogue Actor talk. You can make the text more dynamic by using variable names in square brackets\ne.g. [myVarName] or [Global/myVarName]")]
|
||||
public class StatementNode : DTNode
|
||||
{
|
||||
[SerializeField]
|
||||
public Statement statement = new Statement("This is a dialogue text");
|
||||
|
||||
public override bool requireActorSelection { get { return true; } }
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard bb) {
|
||||
var tempStatement = statement.BlackboardReplace(bb);
|
||||
DialogueTree.RequestSubtitles(new SubtitlesRequestInfo(finalActor, tempStatement, OnStatementFinish));
|
||||
return Status.Running;
|
||||
}
|
||||
|
||||
void OnStatementFinish() {
|
||||
status = Status.Success;
|
||||
DLGTree.Continue();
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
protected override void OnNodeGUI() {
|
||||
GUILayout.BeginVertical(Styles.roundedBox);
|
||||
GUILayout.Label("\"<i> " + statement.text.CapLength(30) + "</i> \"");
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b588031940a278642b73f25a2279bbdd
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 14914
|
||||
packageName: NodeCanvas
|
||||
packageVersion: 3.3.1
|
||||
assetPath: Assets/ParadoxNotion/NodeCanvas/Modules/DialogueTrees/Nodes/StatementNode.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,113 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using ParadoxNotion.Serialization.FullSerializer;
|
||||
|
||||
namespace NodeCanvas.DialogueTrees
|
||||
{
|
||||
|
||||
[Name("Sub Dialogue Tree")]
|
||||
[Description("Execute a Sub Dialogue Tree. When that Dialogue Tree is finished, this node will continue either in Success or Failure if it has any connections. Useful for making reusable and self-contained Dialogue Trees.")]
|
||||
[DropReferenceType(typeof(DialogueTree))]
|
||||
[ParadoxNotion.Design.Icon("Dialogue")]
|
||||
public class SubDialogueTree : DTNodeNested<DialogueTree>, IUpdatable
|
||||
{
|
||||
|
||||
[SerializeField, ExposeField]
|
||||
private BBParameter<DialogueTree> _subTree = null;
|
||||
[fsSerializeAs("actorParametersMap")]
|
||||
private Dictionary<string, string> _actorParametersMap = null;
|
||||
|
||||
public override int maxOutConnections { get { return 2; } }
|
||||
|
||||
public override DialogueTree subGraph { get { return _subTree.value; } set { _subTree.value = value; } }
|
||||
public override BBParameter subGraphParameter => _subTree;
|
||||
|
||||
//
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard bb) {
|
||||
|
||||
if ( subGraph == null ) {
|
||||
return Error("No Sub Dialogue Tree assigned!");
|
||||
}
|
||||
|
||||
currentInstance = (DialogueTree)this.CheckInstance();
|
||||
this.TryWriteAndBindMappedVariables();
|
||||
TryWriteMappedActorParameters();
|
||||
currentInstance.StartGraph(finalActor is Component ? (Component)finalActor : finalActor.transform, bb.parent, Graph.UpdateMode.Manual, OnSubDialogueFinish);
|
||||
return Status.Running;
|
||||
}
|
||||
|
||||
void OnSubDialogueFinish(bool success) {
|
||||
this.TryReadAndUnbindMappedVariables();
|
||||
status = success ? Status.Success : Status.Failure;
|
||||
DLGTree.Continue(success ? 0 : 1);
|
||||
}
|
||||
|
||||
void IUpdatable.Update() {
|
||||
if ( currentInstance != null && status == Status.Running ) {
|
||||
currentInstance.UpdateGraph(this.graph.deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
void TryWriteMappedActorParameters() {
|
||||
if ( _actorParametersMap == null ) { return; }
|
||||
foreach ( var pair in _actorParametersMap ) {
|
||||
var targetParam = currentInstance.GetParameterByID(pair.Key);
|
||||
var sourceParam = this.DLGTree.GetParameterByID(pair.Value);
|
||||
if ( targetParam != null && sourceParam != null ) {
|
||||
currentInstance.SetActorReference(targetParam.name, sourceParam.actor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
public override string GetConnectionInfo(int i) {
|
||||
return i == 0 ? "Success" : "Failure";
|
||||
}
|
||||
|
||||
protected override void OnNodeInspectorGUI() {
|
||||
base.OnNodeInspectorGUI();
|
||||
if ( subGraph != null ) {
|
||||
ShowActorParametersMapping();
|
||||
}
|
||||
}
|
||||
|
||||
//Shows actor parameters mapping
|
||||
void ShowActorParametersMapping() {
|
||||
EditorUtils.Separator();
|
||||
EditorUtils.CoolLabel("SubGraph Actor Parameters Mapping");
|
||||
UnityEditor.EditorGUILayout.HelpBox("Map SubGraph actor parameters from this graph actor parameters. Leaving [NONE] will not affect the parameter.", UnityEditor.MessageType.Info);
|
||||
|
||||
if ( subGraph.actorParameters.Count == 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( _actorParametersMap == null ) { _actorParametersMap = new Dictionary<string, string>(); }
|
||||
|
||||
foreach ( var param in subGraph.actorParameters ) {
|
||||
if ( !_actorParametersMap.ContainsKey(param.ID) ) {
|
||||
_actorParametersMap[param.ID] = string.Empty;
|
||||
}
|
||||
var currentParam = this.DLGTree.GetParameterByID(this._actorParametersMap[param.ID]);
|
||||
var newParam = EditorUtils.Popup<DialogueTree.ActorParameter>(param.name, currentParam, this.DLGTree.actorParameters);
|
||||
if ( newParam != currentParam ) {
|
||||
this._actorParametersMap[param.ID] = newParam != null ? newParam.ID : string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( var key in _actorParametersMap.Keys.ToList() ) {
|
||||
if ( !subGraph.actorParameters.Select(p => p.ID).Contains(key) ) {
|
||||
_actorParametersMap.Remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e463f393e62a0d34093f273ea33c5b23
|
||||
labels:
|
||||
- AI
|
||||
- visualscripting
|
||||
- dialogue
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 14914
|
||||
packageName: NodeCanvas
|
||||
packageVersion: 3.3.1
|
||||
assetPath: Assets/ParadoxNotion/NodeCanvas/Modules/DialogueTrees/Nodes/SubDialogueTree.cs
|
||||
uploadId: 704937
|
||||
Reference in New Issue
Block a user