IndieGame/client/Assets/ParadoxNotion/NodeCanvas/Modules/DialogueTrees/Nodes/SubDialogueTree.cs

113 lines
4.6 KiB
C#
Raw Normal View History

2024-10-11 10:12:15 +08:00
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
}
}