first commit

This commit is contained in:
Chris
2025-03-12 14:22:16 -04:00
commit 0ad0c01249
1999 changed files with 189708 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
using NodeCanvas.Framework;
namespace NodeCanvas.DialogueTrees
{
public class DTConnection : Connection
{
}
}

View File

@@ -0,0 +1,22 @@
fileFormatVersion: 2
guid: f681a39730ae5674fb66c8f78d455170
labels:
- Node
- visualscripting
- dialogue
- Graph
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/DTConnection.cs
uploadId: 704937

View File

@@ -0,0 +1,90 @@
using NodeCanvas.Framework;
using ParadoxNotion;
using ParadoxNotion.Design;
using UnityEngine;
namespace NodeCanvas.DialogueTrees
{
///<summary> Base class for DialogueTree nodes that can live within a DialogueTree Graph.</summary>
abstract public class DTNode : Node
{
[SerializeField] private string _actorName = DialogueTree.INSTIGATOR_NAME;
[SerializeField] private string _actorParameterID;
public override string name {
get
{
if ( requireActorSelection ) {
if ( DLGTree.definedActorParameterNames.Contains(actorName) ) {
return string.Format("{0}", actorName);
}
return string.Format("<color=#d63e3e>* {0} *</color>", _actorName);
}
return base.name;
}
}
virtual public bool requireActorSelection { get { return true; } }
public override int maxInConnections { get { return -1; } }
public override int maxOutConnections { get { return 1; } }
sealed public override System.Type outConnectionType { get { return typeof(DTConnection); } }
sealed public override bool allowAsPrime { get { return true; } }
sealed public override bool canSelfConnect { get { return false; } }
sealed public override Alignment2x2 commentsAlignment { get { return Alignment2x2.Right; } }
sealed public override Alignment2x2 iconAlignment { get { return Alignment2x2.Bottom; } }
protected DialogueTree DLGTree {
get { return (DialogueTree)graph; }
}
///<summary>The key name actor parameter to be used for this node</summary>
public string actorName {
get
{
var result = DLGTree.GetParameterByID(_actorParameterID);
return result != null ? result.name : _actorName;
}
private set
{
if ( _actorName != value && !string.IsNullOrEmpty(value) ) {
_actorName = value;
var param = DLGTree.GetParameterByName(value);
_actorParameterID = param != null ? param.ID : null;
}
}
}
///<summary>The DialogueActor that will execute the node</summary>
public IDialogueActor finalActor {
get
{
var result = DLGTree.GetActorReferenceByID(_actorParameterID);
return result != null ? result : DLGTree.GetActorReferenceByName(_actorName);
}
}
///----------------------------------------------------------------------------------------------
///---------------------------------------UNITY EDITOR-------------------------------------------
#if UNITY_EDITOR
protected override void OnNodeInspectorGUI() {
if ( requireActorSelection ) {
GUI.backgroundColor = Colors.lightBlue;
actorName = EditorUtils.Popup<string>(actorName, DLGTree.definedActorParameterNames);
GUI.backgroundColor = Color.white;
}
base.OnNodeInspectorGUI();
}
protected override UnityEditor.GenericMenu OnContextMenu(UnityEditor.GenericMenu menu) {
menu.AddItem(new GUIContent("Breakpoint"), isBreakpoint, () => { isBreakpoint = !isBreakpoint; });
return menu;
}
#endif
}
}

View File

@@ -0,0 +1,22 @@
fileFormatVersion: 2
guid: 59103b2c12660b043b15b0ee459da1a7
labels:
- Node
- visualscripting
- dialogue
- Graph
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/DTNode.cs
uploadId: 704937

View File

@@ -0,0 +1,25 @@
using System.Collections.Generic;
using NodeCanvas.Framework;
using ParadoxNotion.Design;
using UnityEngine;
using NodeCanvas.Framework.Internal;
namespace NodeCanvas.DialogueTrees
{
[Category("SubGraphs")]
[Color("ffe4e1")]
abstract public class DTNodeNested<T> : DTNode, IGraphAssignable<T> where T : Graph
{
[SerializeField] private List<BBMappingParameter> _variablesMap;
abstract public T subGraph { get; set; }
abstract public BBParameter subGraphParameter { get; }
public T currentInstance { get; set; }
public Dictionary<Graph, Graph> instances { get; set; }
public List<BBMappingParameter> variablesMap { get { return _variablesMap; } set { _variablesMap = value; } }
Graph IGraphAssignable.subGraph { get { return subGraph; } set { subGraph = (T)value; } }
Graph IGraphAssignable.currentInstance { get { return currentInstance; } set { currentInstance = (T)value; } }
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 70cdf8977a971ee47a8430c3c38cf92f
MonoImporter:
externalObjects: {}
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/DTNodeNested.cs
uploadId: 704937

View File

@@ -0,0 +1,65 @@
using UnityEngine;
namespace NodeCanvas.DialogueTrees
{
///<summary> A DialogueActor Component.</summary>
[AddComponentMenu("NodeCanvas/Dialogue Actor")]
public class DialogueActor : MonoBehaviour, IDialogueActor
{
[SerializeField]
protected string _name;
[SerializeField]
protected Texture2D _portrait;
[SerializeField]
protected Color _dialogueColor = Color.white;
[SerializeField]
protected Vector3 _dialogueOffset;
private Sprite _portraitSprite;
new public string name {
get { return _name; }
}
public Texture2D portrait {
get { return _portrait; }
}
public Sprite portraitSprite {
get
{
if ( _portraitSprite == null && portrait != null )
_portraitSprite = Sprite.Create(portrait, new Rect(0, 0, portrait.width, portrait.height), new Vector2(0.5f, 0.5f));
return _portraitSprite;
}
}
public Color dialogueColor {
get { return _dialogueColor; }
}
public Vector3 dialoguePosition {
get { return transform.TransformPoint(_dialogueOffset); }
}
//IDialogueActor.transform is implemented by inherited MonoBehaviour.transform
///----------------------------------------------------------------------------------------------
///---------------------------------------UNITY EDITOR-------------------------------------------
#if UNITY_EDITOR
void Reset() {
_name = gameObject.name;
}
void OnDrawGizmos() {
Gizmos.DrawLine(transform.position, dialoguePosition);
}
#endif
}
}

View File

@@ -0,0 +1,22 @@
fileFormatVersion: 2
guid: 3d71fb7c52372e244baf2e69a9d0d116
labels:
- Node
- visualscripting
- dialogue
- Graph
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/DialogueActor.cs
uploadId: 704937

View File

@@ -0,0 +1,32 @@
using UnityEngine;
namespace NodeCanvas.DialogueTrees
{
///<summary> A DialogueActor Asset.</summary>
[CreateAssetMenu(menuName = "ParadoxNotion/NodeCanvas/Dialogue Actor")]
public class DialogueActorAsset : ScriptableObject, IDialogueActor
{
[SerializeField] protected string _name;
[SerializeField] protected Texture2D _portrait;
[SerializeField] protected Color _dialogueColor = Color.white;
[SerializeField] protected Vector3 _dialogueOffset;
private Sprite _portraitSprite;
new public string name => _name;
public Texture2D portrait => _portrait;
public Color dialogueColor => _dialogueColor;
public Vector3 dialoguePosition => Vector3.zero;
public Transform transform => null;
public Sprite portraitSprite {
get
{
if ( _portraitSprite == null && portrait != null )
_portraitSprite = Sprite.Create(portrait, new Rect(0, 0, portrait.width, portrait.height), new Vector2(0.5f, 0.5f));
return _portraitSprite;
}
}
}
}

View File

@@ -0,0 +1,22 @@
fileFormatVersion: 2
guid: c2ec6ea76fcc78b46b0f170b5cf8b8a2
labels:
- Node
- visualscripting
- dialogue
- Graph
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/DialogueActorAsset.cs
uploadId: 704937

View File

@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
namespace NodeCanvas.DialogueTrees
{
///<summary>Send along with a OnSubtitlesRequest event. Holds info about the actor speaking, the statement that being said as well as a callback to be called when dialogue is done showing</summary>
public class SubtitlesRequestInfo
{
///<summary>The actor speaking</summary>
public IDialogueActor actor;
///<summary>The statement said</summary>
public IStatement statement;
///<summary>Call this to Continue the DialogueTree</summary>
public Action Continue;
public SubtitlesRequestInfo(IDialogueActor actor, IStatement statement, Action callback) {
this.actor = actor;
this.statement = statement;
this.Continue = callback;
}
}
///<summary>Send along with a OnMultipleChoiceRequest event. Holds information of the options, time available as well as a callback to be called providing the selected option</summary>
public class MultipleChoiceRequestInfo
{
///<summary>The actor related. This is usually the actor that will also say the options</summary>
public IDialogueActor actor;
///<summary>The available choice option. Key: The statement, Value: the child index of the option</summary>
public Dictionary<IStatement, int> options;
///<summary>The available time for a choice</summary>
public float availableTime;
///<summary>Should the previous statement be shown along the options?</summary>
public bool showLastStatement;
///<summary>Call this with to select the option to continue with in the DialogueTree</summary>
public Action<int> SelectOption;
public MultipleChoiceRequestInfo(IDialogueActor actor, Dictionary<IStatement, int> options, float availableTime, bool showLastStatement, Action<int> callback) {
this.actor = actor;
this.options = options;
this.availableTime = availableTime;
this.showLastStatement = showLastStatement;
this.SelectOption = callback;
}
public MultipleChoiceRequestInfo(IDialogueActor actor, Dictionary<IStatement, int> options, float availableTime, Action<int> callback) {
this.actor = actor;
this.options = options;
this.availableTime = availableTime;
this.SelectOption = callback;
}
}
}

View File

@@ -0,0 +1,22 @@
fileFormatVersion: 2
guid: 99be78178d3274c46b4d5dc851d694df
labels:
- Node
- visualscripting
- dialogue
- Graph
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/DialogueEventArguments.cs
uploadId: 704937

View File

@@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: 39761394fbf3ea346a5e66e5798c11ae
folderAsset: yes
DefaultImporter:
userData:

View File

@@ -0,0 +1,836 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &100000
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 22400000}
- component: {fileID: 22200000}
- component: {fileID: 11400000}
m_Layer: 5
m_Name: Portrait
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &22400000
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100000}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 22400002}
m_RootOrder: 4
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 59.8, y: 58.326}
m_SizeDelta: {x: 100, y: 100}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &22200000
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100000}
m_CullTransparentMesh: 0
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100000}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 0}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &100002
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 22400002}
- component: {fileID: 22200002}
- component: {fileID: 11400002}
m_Layer: 5
m_Name: SubtitlesGroup
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &22400002
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100002}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224000012677293416}
- {fileID: 22451302}
- {fileID: 22400008}
- {fileID: 22400006}
- {fileID: 22400000}
m_Father: {fileID: 22400010}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 0}
m_AnchoredPosition: {x: 0, y: 6.5}
m_SizeDelta: {x: -167, y: 69}
m_Pivot: {x: 0.5, y: 0}
--- !u!222 &22200002
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100002}
m_CullTransparentMesh: 0
--- !u!114 &11400002
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100002}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0, g: 0, b: 0, a: 0.7607843}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 0}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &100004
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 22400004}
- component: {fileID: 22200004}
- component: {fileID: 11400004}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &22400004
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100004}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 22400014}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &22200004
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100004}
m_CullTransparentMesh: 0
--- !u!114 &11400004
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100004}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.196, g: 0.196, b: 0.196, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 14
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 10
m_MaxSize: 40
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: Choice
--- !u!1 &100006
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 22400006}
- component: {fileID: 22200006}
- component: {fileID: 11400006}
m_Layer: 5
m_Name: Name
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &22400006
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100006}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 22400002}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 1}
m_AnchorMax: {x: 0.5, y: 1}
m_AnchoredPosition: {x: 0, y: 14.7}
m_SizeDelta: {x: 267, y: 29.4}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &22200006
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100006}
m_CullTransparentMesh: 0
--- !u!114 &11400006
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100006}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8993915, g: 1, b: 0.5441177, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 18
m_FontStyle: 1
m_BestFit: 0
m_MinSize: 10
m_MaxSize: 40
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 1
m_VerticalOverflow: 1
m_LineSpacing: 1
m_Text: Actor Name
--- !u!1 &100008
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 22400008}
- component: {fileID: 22200008}
- component: {fileID: 11400008}
m_Layer: 5
m_Name: Speech
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &22400008
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100008}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 22400002}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0.5}
m_AnchorMax: {x: 1, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 74.8}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &22200008
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100008}
m_CullTransparentMesh: 0
--- !u!114 &11400008
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100008}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: 'subtitles
subtitles'
--- !u!1 &100010
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 22400010}
- component: {fileID: 22300000}
- component: {fileID: 11400012}
- component: {fileID: 11400010}
m_Layer: 5
m_Name: '@DialogueUGUI'
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &22400010
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100010}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 22400002}
- {fileID: 22400012}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 0}
--- !u!223 &22300000
Canvas:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100010}
m_Enabled: 1
serializedVersion: 3
m_RenderMode: 0
m_Camera: {fileID: 0}
m_PlaneDistance: 100
m_PixelPerfect: 0
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_AdditionalShaderChannelsFlag: 25
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
--- !u!114 &11400012
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100010}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreReversedGraphics: 1
m_BlockingObjects: 0
m_BlockingMask:
serializedVersion: 2
m_Bits: 4294967295
--- !u!114 &11400010
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100010}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 8a2b17e84c4df7d4c890f25c7c265c11, type: 3}
m_Name:
m_EditorClassIdentifier:
skipOnInput: 0
waitForInput: 1
subtitlesGroup: {fileID: 22400002}
actorSpeech: {fileID: 11400008}
actorName: {fileID: 11400006}
actorPortrait: {fileID: 11400000}
waitInputIndicator: {fileID: 224000012677293416}
subtitleDelays:
characterDelay: 0.05
sentenceDelay: 0.5
commaDelay: 0.1
finalDelay: 1.2
typingSounds:
- {fileID: 8300000, guid: a0d9ccf1ea0e87d4794965b3fa230c65, type: 3}
- {fileID: 8300000, guid: 5e5452015663bd141a0af3ff478c7272, type: 3}
- {fileID: 8300000, guid: 5d3613a99f5e0ac43a2acdfd87d61a4e, type: 3}
optionsGroup: {fileID: 22400012}
optionButton: {fileID: 11400016}
--- !u!1 &100012
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 22400012}
- component: {fileID: 22200012}
- component: {fileID: 11400014}
m_Layer: 5
m_Name: DialogueOptionsGroup
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &22400012
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100012}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 22400014}
m_Father: {fileID: 22400010}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 0}
m_AnchoredPosition: {x: 0, y: 6.5}
m_SizeDelta: {x: -167, y: 47}
m_Pivot: {x: 0.5, y: 0}
--- !u!222 &22200012
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100012}
m_CullTransparentMesh: 0
--- !u!114 &11400014
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100012}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0, g: 0, b: 0, a: 0.7607843}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 0}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &100014
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 22400014}
- component: {fileID: 22200014}
- component: {fileID: 11400018}
- component: {fileID: 11400016}
m_Layer: 5
m_Name: Button
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &22400014
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100014}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 22400004}
m_Father: {fileID: 22400012}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0.000015258789, y: -23.35}
m_SizeDelta: {x: -51.8, y: 30}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &22200014
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100014}
m_CullTransparentMesh: 0
--- !u!114 &11400018
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100014}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 0.588}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!114 &11400016
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 100014}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 0.5019608, g: 0.5019608, b: 0.5019608, a: 0.5019608}
m_HighlightedColor: {r: 0.5019608, g: 0.5019608, b: 0.5019608, a: 0.69803923}
m_PressedColor: {r: 0.34509805, g: 0.34509805, b: 0.34509805, a: 0.69803923}
m_SelectedColor: {r: 0.5019608, g: 0.5019608, b: 0.5019608, a: 0.69803923}
m_DisabledColor: {r: 0.2509804, g: 0.2509804, b: 0.2509804, a: 0.5019608}
m_ColorMultiplier: 2
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Highlighted
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 11400018}
m_OnClick:
m_PersistentCalls:
m_Calls: []
--- !u!1 &172602
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 22451302}
- component: {fileID: 22281560}
- component: {fileID: 11429452}
m_Layer: 5
m_Name: NameBG
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &22451302
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 172602}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 22400002}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 16.763}
m_SizeDelta: {x: 0, y: 34}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &22281560
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 172602}
m_CullTransparentMesh: 0
--- !u!114 &11429452
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 172602}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.16176468, g: 0.16176468, b: 0.16176468, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 0}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &1000010693599660
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 224000012677293416}
- component: {fileID: 222000010095227342}
- component: {fileID: 114000011374680962}
m_Layer: 5
m_Name: WaitInput
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &224000012677293416
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1000010693599660}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 22400002}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 0}
m_AnchorMax: {x: 1, y: 0}
m_AnchoredPosition: {x: -19.549988, y: 15}
m_SizeDelta: {x: 39.1, y: 29.9}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &222000010095227342
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1000010693599660}
m_CullTransparentMesh: 0
--- !u!114 &114000011374680962
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1000010693599660}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 14
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 10
m_MaxSize: 40
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: '[...]'

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: ea4f45f1433c2404197edc445210b679
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 14914
packageName: NodeCanvas
packageVersion: 3.3.1
assetPath: Assets/ParadoxNotion/NodeCanvas/Modules/DialogueTrees/DialogueGUI/@DialogueUGUI.prefab
uploadId: 704937

View File

@@ -0,0 +1,295 @@
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.EventSystems;
namespace NodeCanvas.DialogueTrees.UI.Examples
{
public class DialogueUGUI : MonoBehaviour, IPointerClickHandler
{
[System.Serializable]
public class SubtitleDelays
{
public float characterDelay = 0.05f;
public float sentenceDelay = 0.5f;
public float commaDelay = 0.1f;
public float finalDelay = 1.2f;
}
//Options...
[Header("Input Options")]
public bool skipOnInput;
public bool waitForInput;
//Group...
[Header("Subtitles")]
public RectTransform subtitlesGroup;
public Text actorSpeech;
public Text actorName;
public Image actorPortrait;
public RectTransform waitInputIndicator;
public SubtitleDelays subtitleDelays = new SubtitleDelays();
public List<AudioClip> typingSounds;
private AudioSource playSource;
//Group...
[Header("Multiple Choice")]
public RectTransform optionsGroup;
public Button optionButton;
private Dictionary<Button, int> cachedButtons;
private Vector2 originalSubsPosition;
private bool isWaitingChoice;
private AudioSource _localSource;
private AudioSource localSource {
get { return _localSource != null ? _localSource : _localSource = gameObject.AddComponent<AudioSource>(); }
}
private bool anyKeyDown;
public void OnPointerClick(PointerEventData eventData) => anyKeyDown = true;
void LateUpdate() => anyKeyDown = false;
void Awake() { Subscribe(); Hide(); }
void OnEnable() { UnSubscribe(); Subscribe(); }
void OnDisable() { UnSubscribe(); }
void Subscribe() {
DialogueTree.OnDialogueStarted += OnDialogueStarted;
DialogueTree.OnDialoguePaused += OnDialoguePaused;
DialogueTree.OnDialogueFinished += OnDialogueFinished;
DialogueTree.OnSubtitlesRequest += OnSubtitlesRequest;
DialogueTree.OnMultipleChoiceRequest += OnMultipleChoiceRequest;
}
void UnSubscribe() {
DialogueTree.OnDialogueStarted -= OnDialogueStarted;
DialogueTree.OnDialoguePaused -= OnDialoguePaused;
DialogueTree.OnDialogueFinished -= OnDialogueFinished;
DialogueTree.OnSubtitlesRequest -= OnSubtitlesRequest;
DialogueTree.OnMultipleChoiceRequest -= OnMultipleChoiceRequest;
}
void Hide() {
subtitlesGroup.gameObject.SetActive(false);
optionsGroup.gameObject.SetActive(false);
optionButton.gameObject.SetActive(false);
waitInputIndicator.gameObject.SetActive(false);
originalSubsPosition = subtitlesGroup.transform.position;
}
void OnDialogueStarted(DialogueTree dlg) {
//nothing special...
}
void OnDialoguePaused(DialogueTree dlg) {
subtitlesGroup.gameObject.SetActive(false);
optionsGroup.gameObject.SetActive(false);
StopAllCoroutines();
if ( playSource != null ) playSource.Stop();
}
void OnDialogueFinished(DialogueTree dlg) {
subtitlesGroup.gameObject.SetActive(false);
optionsGroup.gameObject.SetActive(false);
if ( cachedButtons != null ) {
foreach ( var tempBtn in cachedButtons.Keys ) {
if ( tempBtn != null ) {
Destroy(tempBtn.gameObject);
}
}
cachedButtons = null;
}
StopAllCoroutines();
if ( playSource != null ) playSource.Stop();
}
///----------------------------------------------------------------------------------------------
void OnSubtitlesRequest(SubtitlesRequestInfo info) {
StartCoroutine(Internal_OnSubtitlesRequestInfo(info));
}
IEnumerator Internal_OnSubtitlesRequestInfo(SubtitlesRequestInfo info) {
var text = info.statement.text;
var audio = info.statement.audio;
var actor = info.actor;
subtitlesGroup.gameObject.SetActive(true);
subtitlesGroup.position = originalSubsPosition;
actorSpeech.text = "";
actorName.text = actor.name;
actorSpeech.color = actor.dialogueColor;
actorPortrait.gameObject.SetActive(actor.portraitSprite != null);
actorPortrait.sprite = actor.portraitSprite;
if ( audio != null ) {
var actorSource = actor.transform != null ? actor.transform.GetComponent<AudioSource>() : null;
playSource = actorSource != null ? actorSource : localSource;
playSource.clip = audio;
playSource.Play();
actorSpeech.text = text;
var timer = 0f;
while ( timer < audio.length ) {
if ( skipOnInput && anyKeyDown ) {
playSource.Stop();
break;
}
timer += Time.deltaTime;
yield return null;
}
}
if ( audio == null ) {
var tempText = "";
var inputDown = false;
if ( skipOnInput ) {
StartCoroutine(CheckInput(() => { inputDown = true; }));
}
for ( int i = 0; i < text.Length; i++ ) {
if ( skipOnInput && inputDown ) {
actorSpeech.text = text;
yield return null;
break;
}
if ( subtitlesGroup.gameObject.activeSelf == false ) {
yield break;
}
char c = text[i];
tempText += c;
yield return StartCoroutine(DelayPrint(subtitleDelays.characterDelay));
PlayTypeSound();
if ( c == '.' || c == '!' || c == '?' ) {
yield return StartCoroutine(DelayPrint(subtitleDelays.sentenceDelay));
PlayTypeSound();
}
if ( c == ',' ) {
yield return StartCoroutine(DelayPrint(subtitleDelays.commaDelay));
PlayTypeSound();
}
actorSpeech.text = tempText;
}
if ( !waitForInput ) {
yield return StartCoroutine(DelayPrint(subtitleDelays.finalDelay));
}
}
if ( waitForInput ) {
waitInputIndicator.gameObject.SetActive(true);
while ( !anyKeyDown ) {
yield return null;
}
waitInputIndicator.gameObject.SetActive(false);
}
yield return null;
subtitlesGroup.gameObject.SetActive(false);
info.Continue();
}
void PlayTypeSound() {
if ( typingSounds.Count > 0 ) {
var sound = typingSounds[Random.Range(0, typingSounds.Count)];
if ( sound != null ) {
localSource.PlayOneShot(sound, Random.Range(0.6f, 1f));
}
}
}
IEnumerator CheckInput(System.Action Do) {
while ( !anyKeyDown ) {
yield return null;
}
Do();
}
IEnumerator DelayPrint(float time) {
var timer = 0f;
while ( timer < time ) {
timer += Time.deltaTime;
yield return null;
}
}
///----------------------------------------------------------------------------------------------
void OnMultipleChoiceRequest(MultipleChoiceRequestInfo info) {
optionsGroup.gameObject.SetActive(true);
var buttonHeight = optionButton.GetComponent<RectTransform>().rect.height;
optionsGroup.sizeDelta = new Vector2(optionsGroup.sizeDelta.x, ( info.options.Values.Count * buttonHeight ) + 20);
cachedButtons = new Dictionary<Button, int>();
int i = 0;
foreach ( KeyValuePair<IStatement, int> pair in info.options ) {
var btn = (Button)Instantiate(optionButton);
btn.gameObject.SetActive(true);
btn.transform.SetParent(optionsGroup.transform, false);
btn.transform.localPosition = (Vector3)optionButton.transform.localPosition - new Vector3(0, buttonHeight * i, 0);
btn.GetComponentInChildren<Text>().text = pair.Key.text;
cachedButtons.Add(btn, pair.Value);
btn.onClick.AddListener(() => { Finalize(info, cachedButtons[btn]); });
i++;
}
if ( info.showLastStatement ) {
subtitlesGroup.gameObject.SetActive(true);
var newY = optionsGroup.position.y + optionsGroup.sizeDelta.y + 1;
subtitlesGroup.position = new Vector3(subtitlesGroup.position.x, newY, subtitlesGroup.position.z);
}
if ( info.availableTime > 0 ) {
StartCoroutine(CountDown(info));
}
}
IEnumerator CountDown(MultipleChoiceRequestInfo info) {
isWaitingChoice = true;
var timer = 0f;
while ( timer < info.availableTime ) {
if ( isWaitingChoice == false ) {
yield break;
}
timer += Time.deltaTime;
SetMassAlpha(optionsGroup, Mathf.Lerp(1, 0, timer / info.availableTime));
yield return null;
}
if ( isWaitingChoice ) {
Finalize(info, info.options.Values.Last());
}
}
void Finalize(MultipleChoiceRequestInfo info, int index) {
isWaitingChoice = false;
SetMassAlpha(optionsGroup, 1f);
optionsGroup.gameObject.SetActive(false);
subtitlesGroup.gameObject.SetActive(false);
foreach ( var tempBtn in cachedButtons.Keys ) {
Destroy(tempBtn.gameObject);
}
info.SelectOption(index);
}
void SetMassAlpha(RectTransform root, float alpha) {
foreach ( var graphic in root.GetComponentsInChildren<CanvasRenderer>() ) {
graphic.SetAlpha(alpha);
}
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 8a2b17e84c4df7d4c890f25c7c265c11
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: -50
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 14914
packageName: NodeCanvas
packageVersion: 3.3.1
assetPath: Assets/ParadoxNotion/NodeCanvas/Modules/DialogueTrees/DialogueGUI/DialogueUGUI.cs
uploadId: 704937

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 308fd16ad36adda41800985165b4ebf1
folderAsset: yes
timeCreated: 1485179025
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,29 @@
fileFormatVersion: 2
guid: a0d9ccf1ea0e87d4794965b3fa230c65
timeCreated: 1485179020
licenseType: Store
AudioImporter:
serializedVersion: 6
defaultSettings:
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
preloadAudioData: 1
loadInBackground: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 14914
packageName: NodeCanvas
packageVersion: 3.3.1
assetPath: Assets/ParadoxNotion/NodeCanvas/Modules/DialogueTrees/DialogueGUI/Sounds/Keyboard-1.wav
uploadId: 704937

View File

@@ -0,0 +1,29 @@
fileFormatVersion: 2
guid: 5e5452015663bd141a0af3ff478c7272
timeCreated: 1485179020
licenseType: Store
AudioImporter:
serializedVersion: 6
defaultSettings:
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
preloadAudioData: 1
loadInBackground: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 14914
packageName: NodeCanvas
packageVersion: 3.3.1
assetPath: Assets/ParadoxNotion/NodeCanvas/Modules/DialogueTrees/DialogueGUI/Sounds/Keyboard-2.wav
uploadId: 704937

View File

@@ -0,0 +1,29 @@
fileFormatVersion: 2
guid: 5d3613a99f5e0ac43a2acdfd87d61a4e
timeCreated: 1485179019
licenseType: Store
AudioImporter:
serializedVersion: 6
defaultSettings:
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
preloadAudioData: 1
loadInBackground: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 14914
packageName: NodeCanvas
packageVersion: 3.3.1
assetPath: Assets/ParadoxNotion/NodeCanvas/Modules/DialogueTrees/DialogueGUI/Sounds/Keyboard-3.wav
uploadId: 704937

View File

@@ -0,0 +1,299 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NodeCanvas.Framework;
using ParadoxNotion;
using UnityEngine;
using Logger = ParadoxNotion.Services.Logger;
namespace NodeCanvas.DialogueTrees
{
///<summary> Use DialogueTrees to create Dialogues between Actors</summary>
[GraphInfo(
packageName = "NodeCanvas",
docsURL = "https://nodecanvas.paradoxnotion.com/documentation/",
resourcesURL = "https://nodecanvas.paradoxnotion.com/downloads/",
forumsURL = "https://nodecanvas.paradoxnotion.com/forums-page/"
)]
[CreateAssetMenu(menuName = "ParadoxNotion/NodeCanvas/Dialogue Tree Asset")]
public class DialogueTree : Graph
{
///----------------------------------------------------------------------------------------------
[System.Serializable]
class DerivedSerializationData
{
public List<ActorParameter> actorParameters;
}
public override object OnDerivedDataSerialization() {
var data = new DerivedSerializationData();
data.actorParameters = this.actorParameters;
return data;
}
public override void OnDerivedDataDeserialization(object data) {
if ( data is DerivedSerializationData ) {
this.actorParameters = ( (DerivedSerializationData)data ).actorParameters;
}
}
///----------------------------------------------------------------------------------------------
///<summary>An Actor Parameter</summary>
[System.Serializable]
public class ActorParameter
{
[SerializeField] private string _keyName;
[SerializeField] private string _id;
[SerializeField] private UnityEngine.Object _actorObject;
[System.NonSerialized] private IDialogueActor _actor;
///<summary>Key name of the parameter</summary>
public string name {
get { return _keyName; }
set { _keyName = value; }
}
///<summary>ID of the parameter</summary>
public string ID => string.IsNullOrEmpty(_id) ? _id = System.Guid.NewGuid().ToString() : _id;
///<summary>The reference actor of the parameter</summary>
public IDialogueActor actor {
get
{
if ( _actor == null ) {
_actor = _actorObject as IDialogueActor;
}
return _actor;
}
set
{
_actor = value;
_actorObject = value as UnityEngine.Object;
}
}
public ActorParameter() { }
public ActorParameter(string name) { this.name = name; }
public ActorParameter(string name, IDialogueActor actor) {
this.name = name;
this.actor = actor;
}
public override string ToString() { return name; }
}
///----------------------------------------------------------------------------------------------
///<summary>The string used for the starting actor"</summary>
public const string INSTIGATOR_NAME = "SELF";
///<summary>The dialogue actor parameters. We let Unity serialize this as well</summary>
[SerializeField] public List<ActorParameter> actorParameters = new List<ActorParameter>();
private bool enterStartNodeFlag;
public static event Action<DialogueTree> OnDialogueStarted;
public static event Action<DialogueTree> OnDialoguePaused;
public static event Action<DialogueTree> OnDialogueFinished;
public static event Action<SubtitlesRequestInfo> OnSubtitlesRequest;
public static event Action<MultipleChoiceRequestInfo> OnMultipleChoiceRequest;
///<summary>The current DialogueTree running</summary>
public static DialogueTree currentDialogue { get; private set; }
///<summary>The previous DialogueTree running</summary>
public static DialogueTree previousDialogue { get; private set; }
///<summary>The current node of this DialogueTree</summary>
public DTNode currentNode { get; private set; }
///----------------------------------------------------------------------------------------------
public override System.Type baseNodeType => typeof(DTNode);
public override bool requiresAgent => false;
public override bool requiresPrimeNode => true;
public override bool isTree => true;
public override bool allowBlackboardOverrides => true;
sealed public override bool canAcceptVariableDrops => false;
public sealed override PlanarDirection flowDirection => PlanarDirection.Vertical;
///----------------------------------------------------------------------------------------------
///<summary>A list of the defined names for the involved actor parameters</summary>
public List<string> definedActorParameterNames {
get
{
var list = actorParameters.Select(r => r.name).ToList();
list.Insert(0, INSTIGATOR_NAME);
return list;
}
}
///<summary>Returns the ActorParameter by id</summary>
public ActorParameter GetParameterByID(string id) {
return actorParameters.Find(p => p.ID == id);
}
///<summary>Returns the ActorParameter by name</summary>
public ActorParameter GetParameterByName(string paramName) {
return actorParameters.Find(p => p.name == paramName);
}
///<summary>Returns the actor by parameter id.</summary>
public IDialogueActor GetActorReferenceByID(string id) {
var param = GetParameterByID(id);
return param != null ? GetActorReferenceByName(param.name) : null;
}
///<summary>Resolves and gets an actor based on the key name</summary>
public IDialogueActor GetActorReferenceByName(string paramName) {
//Check for INSTIGATOR selection
if ( paramName == INSTIGATOR_NAME ) {
//return it directly if it implements IDialogueActor
if ( agent is IDialogueActor ) {
return (IDialogueActor)agent;
}
//Otherwise use the default actor and set name and transform from agent
if ( agent != null ) {
return new ProxyDialogueActor(agent.gameObject.name, agent.transform);
}
return new ProxyDialogueActor("NO ACTOR", null);
}
//Check for non INSTIGATOR selection. If there IS an actor reference return it
var refData = actorParameters.Find(r => r.name == paramName);
if ( refData != null && refData.actor != null ) {
return refData.actor;
}
//Otherwise use the default actor and set the name to the key and null transform
Logger.Log(string.Format("An actor entry '{0}' on DialogueTree has no reference. A dummy Actor will be used with the entry Key for name", paramName), "Dialogue Tree", this);
return new ProxyDialogueActor(paramName, null);
}
///<summary>Set the target IDialogueActor for the provided key parameter name</summary>
public void SetActorReference(string paramName, IDialogueActor actor) {
var param = actorParameters.Find(p => p.name == paramName);
if ( param == null ) {
Logger.LogError(string.Format("There is no defined Actor key name '{0}'", paramName), "Dialogue Tree", this);
return;
}
param.actor = actor;
}
///<summary>Set all target IDialogueActors at once by provided dictionary</summary>
public void SetActorReferences(Dictionary<string, IDialogueActor> actors) {
foreach ( var pair in actors ) {
var param = actorParameters.Find(p => p.name == pair.Key);
if ( param == null ) {
Logger.LogWarning(string.Format("There is no defined Actor key name '{0}'. Seting actor skiped", pair.Key), "Dialogue Tree", this);
continue;
}
param.actor = pair.Value;
}
}
///<summary>Continues the DialogueTree at provided child connection index of currentNode</summary>
public void Continue(int index = 0) {
if ( index < 0 || index > currentNode.outConnections.Count - 1 ) {
Stop(true);
return;
}
currentNode.outConnections[index].status = Status.Success; //editor vis
EnterNode((DTNode)currentNode.outConnections[index].targetNode);
}
///<summary>Enters the provided node</summary>
public void EnterNode(DTNode node) {
currentNode = node;
currentNode.Reset(false);
if ( currentNode.Execute(agent, blackboard) == Status.Error ) {
Stop(false);
}
}
///<summary>Raise the OnSubtitlesRequest event</summary>
public static void RequestSubtitles(SubtitlesRequestInfo info) {
if ( OnSubtitlesRequest != null )
OnSubtitlesRequest(info);
else Logger.LogWarning("Subtitle Request event has no subscribers. Make sure to add the default '@DialogueGUI' prefab or create your own GUI.", "Dialogue Tree");
}
///<summary>Raise the OnMultipleChoiceRequest event</summary>
public static void RequestMultipleChoices(MultipleChoiceRequestInfo info) {
if ( OnMultipleChoiceRequest != null )
OnMultipleChoiceRequest(info);
else Logger.LogWarning("Multiple Choice Request event has no subscribers. Make sure to add the default '@DialogueGUI' prefab or create your own GUI.", "Dialogue Tree");
}
protected override void OnGraphStarted() {
previousDialogue = currentDialogue;
currentDialogue = this;
Logger.Log(string.Format("Dialogue Started '{0}'", this.name), "Dialogue Tree", this);
if ( OnDialogueStarted != null ) {
OnDialogueStarted(this);
}
if ( !( agent is IDialogueActor ) ) {
Logger.Log("Agent used in DialogueTree does not implement IDialogueActor. A dummy actor will be used.", "Dialogue Tree", this);
}
enterStartNodeFlag = true;
}
protected override void OnGraphUpdate() {
if ( enterStartNodeFlag ) {
//use a flag so that other nodes can do stuff on graph started
enterStartNodeFlag = false;
EnterNode(currentNode != null ? currentNode : (DTNode)primeNode);
}
if ( currentNode is IUpdatable ) {
( currentNode as IUpdatable ).Update();
}
}
protected override void OnGraphStoped() {
currentDialogue = previousDialogue;
previousDialogue = null;
currentNode = null;
Logger.Log(string.Format("Dialogue Finished '{0}'", this.name), "Dialogue Tree", this);
if ( OnDialogueFinished != null ) {
OnDialogueFinished(this);
}
}
protected override void OnGraphPaused() {
Logger.Log(string.Format("Dialogue Paused '{0}'", this.name), "Dialogue Tree", this);
if ( OnDialoguePaused != null ) {
OnDialoguePaused(this);
}
}
protected override void OnGraphUnpaused() {
EnterNode(currentNode != null ? currentNode : (DTNode)primeNode);
Logger.Log(string.Format("Dialogue Resumed '{0}'", this.name), "Dialogue Tree", this);
if ( OnDialogueStarted != null ) {
OnDialogueStarted(this);
}
}
///----------------------------------------------------------------------------------------------
///---------------------------------------UNITY EDITOR-------------------------------------------
#if UNITY_EDITOR
[UnityEditor.MenuItem("Tools/ParadoxNotion/NodeCanvas/Create/Dialogue Tree Object", false, 2)]
static void Editor_CreateGraph() {
var dt = new GameObject("DialogueTree").AddComponent<DialogueTreeController>();
UnityEditor.Selection.activeObject = dt;
}
#endif
}
}

View File

@@ -0,0 +1,23 @@
fileFormatVersion: 2
guid: 2c3f478ef69fbe04fa9ed3664a8a443e
labels:
- Node
- visualscripting
- dialogue
- Graph
MonoImporter:
externalObjects: {}
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/DialogueTree.cs
uploadId: 704937

View File

@@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using NodeCanvas.Framework;
using ParadoxNotion;
namespace NodeCanvas.DialogueTrees
{
[AddComponentMenu("NodeCanvas/Dialogue Tree Controller")]
public class DialogueTreeController : GraphOwner<DialogueTree>, IDialogueActor
{
string IDialogueActor.name => name;
Texture2D IDialogueActor.portrait => null;
Sprite IDialogueActor.portraitSprite => null;
Color IDialogueActor.dialogueColor => Color.white;
Vector3 IDialogueActor.dialoguePosition => Vector3.zero;
Transform IDialogueActor.transform => transform;
///<summary>Start the DialogueTree without an Instigator</summary>
public void StartDialogue() {
StartDialogue(this, null);
}
///<summary>Start the DialogueTree with a callback for when its finished</summary>
public void StartDialogue(Action<bool> callback) {
StartDialogue(this, callback);
}
///<summary>Start the DialogueTree with provided actor as Instigator</summary>
public void StartDialogue(IDialogueActor instigator) {
StartDialogue(instigator, null);
}
///<summary>Assign a new DialogueTree and Start it</summary>
public void StartDialogue(DialogueTree newTree, IDialogueActor instigator, Action<bool> callback) {
graph = newTree;
StartDialogue(instigator, callback);
}
///<summary>Start the already assgined DialogueTree with provided actor as instigator and callback</summary>
public void StartDialogue(IDialogueActor instigator, Action<bool> callback) {
graph = GetInstance(graph);
graph.StartGraph(instigator is Component ? (Component)instigator : instigator.transform, blackboard, updateMode, callback);
}
///<summary>Pause the DialogueTree</summary>
public void PauseDialogue() {
graph.Pause();
}
///<summary>Stop the DialogueTree</summary>
public void StopDialogue() {
graph.Stop();
}
///<summary>Set an actor reference by parameter name</summary>
public void SetActorReference(string paramName, IDialogueActor actor) {
if ( behaviour != null ) {
behaviour.SetActorReference(paramName, actor);
}
}
///<summary>Set all actor reference parameters at once</summary>
public void SetActorReferences(Dictionary<string, IDialogueActor> actors) {
if ( behaviour != null ) {
behaviour.SetActorReferences(actors);
}
}
///<summary>Get the actor reference by parameter name</summary>
public IDialogueActor GetActorReferenceByName(string paramName) {
return behaviour != null ? behaviour.GetActorReferenceByName(paramName) : null;
}
///----------------------------------------------------------------------------------------------
///---------------------------------------UNITY EDITOR-------------------------------------------
#if UNITY_EDITOR
new void Reset() {
base.enableAction = EnableAction.DoNothing;
base.disableAction = DisableAction.DoNothing;
blackboard = gameObject.GetAddComponent<Blackboard>();
SetBoundGraphReference(ScriptableObject.CreateInstance<DialogueTree>());
}
#endif
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: c32e4b851ebd8fa4ea0645b99be1cf97
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: b5eeec78a0081094cb8dfeb83808d762, type: 3}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 14914
packageName: NodeCanvas
packageVersion: 3.3.1
assetPath: Assets/ParadoxNotion/NodeCanvas/Modules/DialogueTrees/DialogueTreeController.cs
uploadId: 704937

View File

@@ -0,0 +1,55 @@
using UnityEngine;
namespace NodeCanvas.DialogueTrees
{
///<summary> An interface to use for DialogueActors within a DialogueTree.</summary>
public interface IDialogueActor
{
string name { get; }
Texture2D portrait { get; }
Sprite portraitSprite { get; }
Color dialogueColor { get; }
Vector3 dialoguePosition { get; }
Transform transform { get; }
}
///<summary>A basic rather limited implementation of IDialogueActor</summary>
[System.Serializable]
public class ProxyDialogueActor : IDialogueActor
{
private string _name;
private Transform _transform;
public string name {
get { return _name; }
}
public Texture2D portrait {
get { return null; }
}
public Sprite portraitSprite {
get { return null; }
}
public Color dialogueColor {
get { return Color.white; }
}
public Vector3 dialoguePosition {
get { return Vector3.zero; }
}
public Transform transform {
get { return _transform; }
}
public ProxyDialogueActor(string name, Transform transform) {
this._name = name;
this._transform = transform;
}
}
}

View File

@@ -0,0 +1,22 @@
fileFormatVersion: 2
guid: b6fede26f3152e541ab8baad9585549a
labels:
- Node
- visualscripting
- dialogue
- Graph
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/IDialogueActor.cs
uploadId: 704937

View File

@@ -0,0 +1,87 @@
using ParadoxNotion;
using NodeCanvas.Framework;
using UnityEngine;
using System.Linq;
namespace NodeCanvas.DialogueTrees
{
///<summary>An interface to use for whats being said by a dialogue actor</summary>
public interface IStatement
{
string text { get; }
AudioClip audio { get; }
string meta { get; }
}
///<summary>Holds data of what's being said usualy by an actor</summary>
[System.Serializable]
public class Statement : IStatement
{
[SerializeField] private string _text = string.Empty;
[SerializeField] private AudioClip _audio;
[SerializeField] private string _meta = string.Empty;
public string text {
get { return _text; }
set { _text = value; }
}
public AudioClip audio {
get { return _audio; }
set { _audio = value; }
}
public string meta {
get { return _meta; }
set { _meta = value; }
}
//required
public Statement() { }
public Statement(string text) {
this.text = text;
}
public Statement(string text, AudioClip audio) {
this.text = text;
this.audio = audio;
}
public Statement(string text, AudioClip audio, string meta) {
this.text = text;
this.audio = audio;
this.meta = meta;
}
///<summary>Replace the text of the statement found in brackets, with blackboard variables ToString and returns a Statement copy</summary>
public IStatement BlackboardReplace(IBlackboard bb) {
var copy = ParadoxNotion.Serialization.JSONSerializer.Clone<Statement>(this);
copy.text = copy.text.ReplaceWithin('[', ']', (input) =>
{
object o = null;
if ( bb != null ) { //referenced blackboard replace
var v = bb.GetVariable(input, typeof(object));
if ( v != null ) { o = v.value; }
}
if ( input.Contains("/") ) { //global blackboard replace
var globalBB = GlobalBlackboard.Find(input.Split('/').First());
if ( globalBB != null ) {
var v = globalBB.GetVariable(input.Split('/').Last(), typeof(object));
if ( v != null ) { o = v.value; }
}
}
return o != null ? o.ToString() : input;
});
return copy;
}
public override string ToString() {
return text;
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 964dda7a8c6ffe64496a9912416eee06
MonoImporter:
externalObjects: {}
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/IStatement.cs
uploadId: 704937

View File

@@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: da9036d563304ce4bb5c20ba24986360
folderAsset: yes
DefaultImporter:
userData:

View File

@@ -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();
}
}
}

View File

@@ -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

View File

@@ -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
}
}

View File

@@ -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

View File

@@ -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
}
}

View File

@@ -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

View File

@@ -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
}
}

View File

@@ -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

View File

@@ -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
}
}

View File

@@ -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

View File

@@ -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
}
}

View File

@@ -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

View File

@@ -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
}
}

View File

@@ -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

View File

@@ -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
}
}

View File

@@ -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

View File

@@ -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
}
}

View File

@@ -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