first commit
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 041e18f0c8aec704cb1d5550618b04c5
|
||||
folderAsset: yes
|
||||
timeCreated: 1435255793
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,119 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Serialization;
|
||||
|
||||
namespace NodeCanvas
|
||||
{
|
||||
|
||||
[AddComponentMenu("NodeCanvas/Standalone Action List (Bonus)")]
|
||||
public class ActionListPlayer : MonoBehaviour, ITaskSystem, ISerializationCallbackReceiver
|
||||
{
|
||||
|
||||
public bool playOnAwake;
|
||||
|
||||
[SerializeField] private string _serializedList;
|
||||
[SerializeField] private List<UnityEngine.Object> _objectReferences;
|
||||
[SerializeField] private Blackboard _blackboard;
|
||||
|
||||
[System.NonSerialized]
|
||||
private ActionList _actionList;
|
||||
|
||||
private float timeStarted;
|
||||
|
||||
void ISerializationCallbackReceiver.OnBeforeSerialize() {
|
||||
// if ( ParadoxNotion.Services.Threader.applicationIsPlaying ) { return; }
|
||||
_objectReferences = new List<UnityEngine.Object>();
|
||||
_serializedList = JSONSerializer.Serialize(typeof(ActionList), _actionList, _objectReferences);
|
||||
}
|
||||
|
||||
void ISerializationCallbackReceiver.OnAfterDeserialize() {
|
||||
_actionList = JSONSerializer.Deserialize<ActionList>(_serializedList, _objectReferences);
|
||||
if ( _actionList == null ) _actionList = (ActionList)Task.Create(typeof(ActionList), this);
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
|
||||
public ActionList actionList => _actionList;
|
||||
public float elapsedTime => Time.time - timeStarted;
|
||||
public float deltaTime => Time.deltaTime;
|
||||
Object ITaskSystem.contextObject => this;
|
||||
Component ITaskSystem.agent => this;
|
||||
|
||||
public IBlackboard blackboard {
|
||||
get { return _blackboard; }
|
||||
set
|
||||
{
|
||||
if ( !ReferenceEquals(_blackboard, value) ) {
|
||||
_blackboard = (Blackboard)(object)value;
|
||||
UpdateTasksOwner();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
|
||||
public static ActionListPlayer Create() {
|
||||
return new GameObject("ActionList").AddComponent<ActionListPlayer>();
|
||||
}
|
||||
|
||||
protected void Awake() {
|
||||
UpdateTasksOwner();
|
||||
if ( playOnAwake ) {
|
||||
Play();
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateTasksOwner() {
|
||||
actionList.SetOwnerSystem(this);
|
||||
foreach ( var a in actionList.actions ) {
|
||||
a.SetOwnerSystem(this);
|
||||
BBParameter.SetBBFields(a, blackboard);
|
||||
}
|
||||
}
|
||||
|
||||
void ITaskSystem.SendEvent(string name, object value, object sender) {
|
||||
ParadoxNotion.Services.Logger.LogWarning("Sending events to standalone action lists has no effect", LogTag.EXECUTION, this);
|
||||
}
|
||||
void ITaskSystem.SendEvent<T>(string name, T value, object sender) {
|
||||
ParadoxNotion.Services.Logger.LogWarning("Sending events to standalone action lists has no effect", LogTag.EXECUTION, this);
|
||||
}
|
||||
|
||||
[ContextMenu("Play")]
|
||||
public void Play() { Play(this, this.blackboard, null); }
|
||||
public void Play(System.Action<Status> OnFinish) { Play(this, this.blackboard, OnFinish); }
|
||||
public void Play(Component agent, IBlackboard blackboard, System.Action<Status> OnFinish) {
|
||||
if ( Application.isPlaying ) {
|
||||
timeStarted = Time.time;
|
||||
actionList.ExecuteIndependent(agent, blackboard, OnFinish);
|
||||
}
|
||||
}
|
||||
|
||||
public Status Execute() { return actionList.Execute(this, blackboard); }
|
||||
public Status Execute(Component agent) { return actionList.Execute(agent, blackboard); }
|
||||
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
[UnityEditor.MenuItem("Tools/ParadoxNotion/NodeCanvas/Create/Standalone Action List", false, 3)]
|
||||
static void CreateActionListPlayer() {
|
||||
UnityEditor.Selection.activeObject = Create();
|
||||
}
|
||||
|
||||
void Reset() {
|
||||
var bb = GetComponent<Blackboard>();
|
||||
_blackboard = bb != null ? bb : gameObject.AddComponent<Blackboard>();
|
||||
_actionList = (ActionList)Task.Create(typeof(ActionList), this);
|
||||
}
|
||||
|
||||
void OnValidate() {
|
||||
if ( !Application.isPlaying && !UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode ) {
|
||||
UpdateTasksOwner();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 771e8d04ad23ec04ca6178c3be664c99
|
||||
timeCreated: 1435079338
|
||||
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/ActionListPlayer/ActionListPlayer.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3e4c919d6c8ace54abe33fbe755d92f0
|
||||
folderAsset: yes
|
||||
timeCreated: 1448983354
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,12 @@
|
||||
using NodeCanvas.Framework;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
///<summary>The connection object for BehaviourTree nodes</summary>
|
||||
public class BTConnection : Connection
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a30540c2f2ef9254686deec5ba838b26
|
||||
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/BehaviourTrees/BTConnection.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,52 @@
|
||||
using ParadoxNotion;
|
||||
using NodeCanvas.Framework;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
///<summary> Super Base class for BehaviourTree nodes that can live within a BehaviourTree Graph.</summary>
|
||||
abstract public class BTNode : Node
|
||||
{
|
||||
|
||||
sealed public override System.Type outConnectionType { get { return typeof(BTConnection); } }
|
||||
sealed public override bool allowAsPrime { get { return true; } }
|
||||
sealed public override bool canSelfConnect { get { return false; } }
|
||||
public override Alignment2x2 commentsAlignment { get { return Alignment2x2.Bottom; } }
|
||||
public override Alignment2x2 iconAlignment { get { return Alignment2x2.Default; } }
|
||||
public override int maxInConnections { get { return 1; } }
|
||||
public override int maxOutConnections { get { return 0; } }
|
||||
|
||||
///<summary>Add a child node to this node connected to the specified child index</summary>
|
||||
public T AddChild<T>(int childIndex) where T : BTNode {
|
||||
if ( outConnections.Count >= maxOutConnections && maxOutConnections != -1 ) {
|
||||
return null;
|
||||
}
|
||||
var child = graph.AddNode<T>();
|
||||
graph.ConnectNodes(this, child, childIndex);
|
||||
return child;
|
||||
}
|
||||
|
||||
///<summary>Add a child node to this node connected last</summary>
|
||||
public T AddChild<T>() where T : BTNode {
|
||||
if ( outConnections.Count >= maxOutConnections && maxOutConnections != -1 ) {
|
||||
return null;
|
||||
}
|
||||
var child = graph.AddNode<T>();
|
||||
graph.ConnectNodes(this, child);
|
||||
return child;
|
||||
}
|
||||
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
protected override UnityEditor.GenericMenu OnContextMenu(UnityEditor.GenericMenu menu) {
|
||||
menu.AddItem(new UnityEngine.GUIContent("Breakpoint"), isBreakpoint, () => { isBreakpoint = !isBreakpoint; });
|
||||
return ParadoxNotion.Design.EditorUtils.GetTypeSelectionMenu(typeof(BTDecorator), (t) => { this.DecorateWith(t); }, menu, "Decorate");
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 36c47b59831d8804eb0ff34bcb2622a7
|
||||
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/BehaviourTrees/BTNode.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,26 @@
|
||||
using System.Collections.Generic;
|
||||
using NodeCanvas.Framework;
|
||||
using NodeCanvas.Framework.Internal;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
[Category("SubGraphs")]
|
||||
[Color("ffe4e1")]
|
||||
abstract public class BTNodeNested<T> : BTNode, 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; } }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 446133630245ab947a1bef9bbc5d5aa3
|
||||
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/BehaviourTrees/BTNodeNested.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,115 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
///<summary> BehaviourTrees are used to create advanced AI and logic based on simple rules.</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/Behaviour Tree Asset")]
|
||||
public class BehaviourTree : Graph
|
||||
{
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
[System.Serializable]
|
||||
class DerivedSerializationData
|
||||
{
|
||||
public bool repeat;
|
||||
public float updateInterval;
|
||||
}
|
||||
|
||||
public override object OnDerivedDataSerialization() {
|
||||
var data = new DerivedSerializationData();
|
||||
data.repeat = this.repeat;
|
||||
data.updateInterval = this.updateInterval;
|
||||
return data;
|
||||
}
|
||||
|
||||
public override void OnDerivedDataDeserialization(object data) {
|
||||
if ( data is DerivedSerializationData ) {
|
||||
this.repeat = ( (DerivedSerializationData)data ).repeat;
|
||||
this.updateInterval = ( (DerivedSerializationData)data ).updateInterval;
|
||||
}
|
||||
}
|
||||
///----------------------------------------------------------------------------------------------
|
||||
|
||||
///<summary>Should the tree repeat forever?</summary>
|
||||
[System.NonSerialized] public bool repeat = true;
|
||||
///<summary>The frequency in seconds for the tree to repeat if set to repeat.</summary>
|
||||
[System.NonSerialized] public float updateInterval = 0;
|
||||
|
||||
///<summary>Raised when the root status of the behaviour is changed</summary>
|
||||
public static event System.Action<BehaviourTree, Status> onRootStatusChanged;
|
||||
|
||||
private float intervalCounter;
|
||||
private Status _rootStatus = Status.Resting;
|
||||
|
||||
///<summary>The last status of the root node</summary>
|
||||
public Status rootStatus {
|
||||
get { return _rootStatus; }
|
||||
private set
|
||||
{
|
||||
if ( _rootStatus != value ) {
|
||||
_rootStatus = value;
|
||||
if ( onRootStatusChanged != null ) {
|
||||
onRootStatusChanged(this, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
public override System.Type baseNodeType => typeof(BTNode);
|
||||
public override bool requiresAgent => true;
|
||||
public override bool requiresPrimeNode => true;
|
||||
public override bool isTree => true;
|
||||
public override bool allowBlackboardOverrides => true;
|
||||
sealed public override bool canAcceptVariableDrops => false;
|
||||
public override ParadoxNotion.PlanarDirection flowDirection => ParadoxNotion.PlanarDirection.Vertical;
|
||||
///----------------------------------------------------------------------------------------------
|
||||
|
||||
protected override void OnGraphStarted() {
|
||||
intervalCounter = updateInterval;
|
||||
rootStatus = primeNode.status;
|
||||
}
|
||||
|
||||
protected override void OnGraphUpdate() {
|
||||
|
||||
if ( intervalCounter >= updateInterval ) {
|
||||
intervalCounter = 0;
|
||||
if ( Tick(agent, blackboard) != Status.Running && !repeat ) {
|
||||
Stop(rootStatus == Status.Success);
|
||||
}
|
||||
}
|
||||
|
||||
if ( updateInterval > 0 ) {
|
||||
intervalCounter += Time.deltaTime;
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>Tick the tree once for the provided agent and with the provided blackboard</summary>
|
||||
Status Tick(Component agent, IBlackboard blackboard) {
|
||||
if ( rootStatus != Status.Running ) { primeNode.Reset(); }
|
||||
return rootStatus = primeNode.Execute(agent, blackboard);
|
||||
}
|
||||
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.MenuItem("Tools/ParadoxNotion/NodeCanvas/Create/Behaviour Tree Asset", false, 0)]
|
||||
static void Editor_CreateGraph() {
|
||||
var newGraph = EditorUtils.CreateAsset<BehaviourTree>();
|
||||
UnityEditor.Selection.activeObject = newGraph;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a686a47eee2fa44cb0a34b5d86e4d5e
|
||||
labels:
|
||||
- AI
|
||||
- behaviourtree
|
||||
- visualscripting
|
||||
- behaviour
|
||||
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/BehaviourTrees/BehaviourTree.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,148 @@
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using System.Collections.Generic;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using System.Linq;
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
public static class BehaviourTreeExtensions
|
||||
{
|
||||
|
||||
///<summary>Replace the node with another</summary>
|
||||
public static Node ReplaceWith(this Node node, System.Type t) {
|
||||
|
||||
var newNode = node.graph.AddNode(t, node.position);
|
||||
foreach ( var c in node.inConnections.ToArray() ) {
|
||||
c.SetTargetNode(newNode);
|
||||
}
|
||||
|
||||
foreach ( var c in node.outConnections.ToArray() ) {
|
||||
c.SetSourceNode(newNode);
|
||||
}
|
||||
|
||||
if ( node.graph.primeNode == node ) {
|
||||
node.graph.primeNode = newNode;
|
||||
}
|
||||
|
||||
if ( node is ITaskAssignable && newNode is ITaskAssignable ) {
|
||||
var assignableNode = node as ITaskAssignable;
|
||||
var assignableNewNode = newNode as ITaskAssignable;
|
||||
try { assignableNewNode.task = assignableNode.task; }
|
||||
catch { /* cant assign */ }
|
||||
}
|
||||
|
||||
node.graph.RemoveNode(node);
|
||||
return newNode;
|
||||
}
|
||||
|
||||
///<summary>Create a new SubTree out of the branch of the provided root node</summary>
|
||||
public static BehaviourTree ConvertToSubTree(this BTNode root) {
|
||||
|
||||
if ( !UnityEditor.EditorUtility.DisplayDialog("Convert to SubTree", "This will create a new SubTree out of this branch.\nAre you sure?", "Yes", "No!") ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var newBT = EditorUtils.CreateAsset<BehaviourTree>();
|
||||
if ( newBT == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var subTreeNode = root.graph.AddNode<SubTree>(root.position);
|
||||
subTreeNode.subGraph = newBT;
|
||||
|
||||
for ( var i = 0; i < root.inConnections.Count; i++ ) {
|
||||
root.inConnections[i].SetTargetNode(subTreeNode);
|
||||
}
|
||||
|
||||
root.inConnections.Clear();
|
||||
|
||||
newBT.primeNode = DuplicateBranch(root, newBT);
|
||||
DeleteBranch(root);
|
||||
|
||||
UnityEditor.AssetDatabase.SaveAssets();
|
||||
return newBT;
|
||||
}
|
||||
|
||||
///<summary>Delete the whole branch of provided root node along with the root node</summary>
|
||||
public static void DeleteBranch(this BTNode root) {
|
||||
var graph = root.graph;
|
||||
foreach ( var node in root.GetAllChildNodesRecursively(true).ToArray() ) {
|
||||
graph.RemoveNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>Duplicate a node along with all children hierarchy</summary>
|
||||
public static Node DuplicateBranch(this BTNode root, Graph targetGraph) {
|
||||
|
||||
if ( targetGraph == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var newNode = root.Duplicate(targetGraph);
|
||||
var dupConnections = new List<Connection>();
|
||||
for ( var i = 0; i < root.outConnections.Count; i++ ) {
|
||||
dupConnections.Add(root.outConnections[i].Duplicate(newNode, DuplicateBranch((BTNode)root.outConnections[i].targetNode, targetGraph)));
|
||||
}
|
||||
newNode.outConnections.Clear();
|
||||
foreach ( var c in dupConnections ) {
|
||||
newNode.outConnections.Add(c);
|
||||
}
|
||||
return newNode;
|
||||
}
|
||||
|
||||
///<summary>Decorates BT node with decorator type</summary>
|
||||
public static Node DecorateWith(this BTNode node, System.Type t) {
|
||||
var newNode = node.graph.AddNode(t, node.position + new UnityEngine.Vector2(0, -80));
|
||||
if ( node.inConnections.Count == 0 ) {
|
||||
node.graph.ConnectNodes(newNode, node);
|
||||
} else {
|
||||
var parent = node.inConnections[0].sourceNode;
|
||||
var parentConnection = node.inConnections[0];
|
||||
var index = parent.outConnections.IndexOf(parentConnection);
|
||||
node.graph.RemoveConnection(parentConnection);
|
||||
node.graph.ConnectNodes(newNode, node);
|
||||
node.graph.ConnectNodes(parent, newNode, index);
|
||||
NodeCanvas.Editor.GraphEditorUtility.activeElement = newNode;
|
||||
}
|
||||
return newNode;
|
||||
}
|
||||
|
||||
///<summary>Fetch all child nodes of the node recursively, optionaly including this. In other words, this fetches the whole branch.</summary>
|
||||
public static List<BTNode> GetAllChildNodesRecursively(this BTNode root, bool includeThis) {
|
||||
|
||||
var childList = new List<BTNode>();
|
||||
if ( includeThis ) {
|
||||
childList.Add(root);
|
||||
}
|
||||
|
||||
foreach ( BTNode child in root.outConnections.Select(c => c.targetNode) ) {
|
||||
childList.AddRange(child.GetAllChildNodesRecursively(true));
|
||||
}
|
||||
|
||||
return childList;
|
||||
}
|
||||
|
||||
///<summary>Fetch all child nodes of this node with their depth in regards to this node. So, first level children will have a depth of 1 while second level a depth of 2</summary>
|
||||
public static Dictionary<BTNode, int> GetAllChildNodesWithDepthRecursively(this BTNode root, bool includeThis, int startIndex) {
|
||||
|
||||
var childList = new Dictionary<BTNode, int>();
|
||||
if ( includeThis ) {
|
||||
childList[root] = startIndex;
|
||||
}
|
||||
|
||||
foreach ( BTNode child in root.outConnections.Select(c => c.targetNode) ) {
|
||||
foreach ( var pair in child.GetAllChildNodesWithDepthRecursively(true, startIndex + 1) ) {
|
||||
childList[pair.Key] = pair.Value;
|
||||
}
|
||||
}
|
||||
|
||||
return childList;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 274b815aabe24fb4cb3b2db61d263a82
|
||||
timeCreated: 1511235461
|
||||
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/BehaviourTrees/BehaviourTreeExtensions.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,42 @@
|
||||
using NodeCanvas.Framework;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
///<summary> Use this component on a game object to behave based on a BehaviourTree.</summary>
|
||||
[AddComponentMenu("NodeCanvas/Behaviour Tree Owner")]
|
||||
public class BehaviourTreeOwner : GraphOwner<BehaviourTree>
|
||||
{
|
||||
|
||||
///<summary>Should the assigned BT reset and re-execute after a cycle? Sets the BehaviourTree's repeat</summary>
|
||||
public bool repeat {
|
||||
get { return behaviour != null ? behaviour.repeat : true; }
|
||||
set { if ( behaviour != null ) behaviour.repeat = value; }
|
||||
}
|
||||
|
||||
///<summary>The interval in seconds to update the BT. 0 for every frame. Sets the BehaviourTree's updateInterval</summary>
|
||||
public float updateInterval {
|
||||
get { return behaviour != null ? behaviour.updateInterval : 0; }
|
||||
set { if ( behaviour != null ) behaviour.updateInterval = value; }
|
||||
}
|
||||
|
||||
///<summary>The last status of the assigned Behaviour Tree's root node (aka Start Node)</summary>
|
||||
public Status rootStatus {
|
||||
get { return behaviour != null ? behaviour.rootStatus : Status.Resting; }
|
||||
}
|
||||
|
||||
///<summary>Ticks the assigned Behaviour Tree for this owner agent and returns it's root status</summary>
|
||||
public Status Tick() {
|
||||
|
||||
if ( behaviour == null ) {
|
||||
ParadoxNotion.Services.Logger.LogWarning("There is no Behaviour Tree assigned", LogTag.EXECUTION, gameObject);
|
||||
return Status.Resting;
|
||||
}
|
||||
|
||||
UpdateBehaviour();
|
||||
return behaviour.rootStatus;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aad115aca74ce3c4891b3f6de0b4aae8
|
||||
labels:
|
||||
- AI
|
||||
- behaviourtree
|
||||
- visualscripting
|
||||
- behaviour
|
||||
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/BehaviourTrees/BehaviourTreeOwner.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 600973cdc7297f644ae02138cc4daed8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
@@ -0,0 +1,36 @@
|
||||
using ParadoxNotion;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
///<summary> Base class for BehaviourTree Composite nodes.</summary>
|
||||
abstract public class BTComposite : BTNode
|
||||
{
|
||||
|
||||
public override string name { get { return base.name.ToUpper(); } }
|
||||
|
||||
sealed public override int maxOutConnections { get { return -1; } }
|
||||
sealed public override Alignment2x2 commentsAlignment { get { return Alignment2x2.Right; } }
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
protected override UnityEditor.GenericMenu OnContextMenu(UnityEditor.GenericMenu menu) {
|
||||
menu = base.OnContextMenu(menu);
|
||||
menu = EditorUtils.GetTypeSelectionMenu(typeof(BTComposite), (t) => { this.ReplaceWith(t); }, menu, "Replace");
|
||||
menu.AddItem(new GUIContent("Convert to SubTree"), false, () => { this.ConvertToSubTree(); });
|
||||
if ( outConnections.Count > 0 ) {
|
||||
menu.AddItem(new GUIContent("Duplicate Branch"), false, () => { this.DuplicateBranch(graph); });
|
||||
menu.AddItem(new GUIContent("Delete Branch"), false, () => { this.DeleteBranch(); });
|
||||
}
|
||||
return menu;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e93e7cbdaad6ba44b9dc279b92d4aa1
|
||||
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/BehaviourTrees/Nodes/BTComposite.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,43 @@
|
||||
using ParadoxNotion;
|
||||
using NodeCanvas.Framework;
|
||||
using System.Linq;
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
///<summary> Base class for BehaviourTree Decorator nodes.</summary>
|
||||
abstract public class BTDecorator : BTNode
|
||||
{
|
||||
|
||||
sealed public override int maxOutConnections { get { return 1; } }
|
||||
sealed public override Alignment2x2 commentsAlignment { get { return Alignment2x2.Right; } }
|
||||
|
||||
///<summary>The decorated connection element</summary>
|
||||
protected Connection decoratedConnection {
|
||||
get { return outConnections.Count > 0 ? outConnections[0] : null; }
|
||||
}
|
||||
|
||||
///<summary>The decorated node element</summary>
|
||||
protected Node decoratedNode {
|
||||
get
|
||||
{
|
||||
var c = decoratedConnection;
|
||||
return c != null ? c.targetNode : null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
protected override UnityEditor.GenericMenu OnContextMenu(UnityEditor.GenericMenu menu) {
|
||||
menu = base.OnContextMenu(menu);
|
||||
menu = ParadoxNotion.Design.EditorUtils.GetTypeSelectionMenu(typeof(BTDecorator), (t) => { this.ReplaceWith(t); }, menu, "Replace");
|
||||
return menu;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db739e985051c1649a1542c75a5c0c35
|
||||
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/BehaviourTrees/Nodes/BTDecorator.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c91f78ceede3d6f4083926a34147bd51
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
@@ -0,0 +1,84 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Category("Composites")]
|
||||
[Description("Quick way to execute the left or the right child, based on a Condition Task.")]
|
||||
[ParadoxNotion.Design.Icon("Condition")]
|
||||
[Color("b3ff7f")]
|
||||
public class BinarySelector : BTNode, ITaskAssignable<ConditionTask>
|
||||
{
|
||||
|
||||
[Tooltip("If true, the condition will be re-evaluated per frame.")]
|
||||
public bool dynamic;
|
||||
|
||||
[SerializeField]
|
||||
private ConditionTask _condition;
|
||||
|
||||
private int succeedIndex;
|
||||
|
||||
public override int maxOutConnections { get { return 2; } }
|
||||
public override Alignment2x2 commentsAlignment { get { return Alignment2x2.Right; } }
|
||||
|
||||
public override string name {
|
||||
get { return base.name.ToUpper(); }
|
||||
}
|
||||
|
||||
public Task task {
|
||||
get { return condition; }
|
||||
set { condition = (ConditionTask)value; }
|
||||
}
|
||||
|
||||
private ConditionTask condition {
|
||||
get { return _condition; }
|
||||
set { _condition = value; }
|
||||
}
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
if ( condition == null || outConnections.Count < 2 ) {
|
||||
return Status.Optional;
|
||||
}
|
||||
|
||||
if ( status == Status.Resting ) {
|
||||
condition.Enable(agent, blackboard);
|
||||
}
|
||||
|
||||
if ( dynamic || status == Status.Resting ) {
|
||||
var lastIndex = succeedIndex;
|
||||
succeedIndex = condition.Check(agent, blackboard) ? 0 : 1;
|
||||
if ( succeedIndex != lastIndex ) {
|
||||
outConnections[lastIndex].Reset();
|
||||
}
|
||||
}
|
||||
|
||||
return outConnections[succeedIndex].Execute(agent, blackboard);
|
||||
}
|
||||
|
||||
protected override void OnReset() {
|
||||
if ( condition != null ) { condition.Disable(); }
|
||||
}
|
||||
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
public override string GetConnectionInfo(int i) {
|
||||
return i == 0 ? "TRUE" : "FALSE";
|
||||
}
|
||||
|
||||
protected override void OnNodeGUI() {
|
||||
if ( dynamic ) {
|
||||
GUILayout.Label("<b>DYNAMIC</b>");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 48e71e5905e9e394e83cbdce71c91feb
|
||||
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/BehaviourTrees/Nodes/Composites/BinarySelector.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,48 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Category("Composites")]
|
||||
[Description("Works like a normal Selector, but when a child returns Success, that child will be moved to the end.\nAs a result, previously Failed children will always be checked first and recently Successful children last.")]
|
||||
[ParadoxNotion.Design.Icon("FlipSelector")]
|
||||
[Color("b3ff7f")]
|
||||
public class FlipSelector : BTComposite
|
||||
{
|
||||
|
||||
private int current;
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
for ( var i = current; i < outConnections.Count; i++ ) {
|
||||
|
||||
status = outConnections[i].Execute(agent, blackboard);
|
||||
|
||||
if ( status == Status.Running ) {
|
||||
current = i;
|
||||
return Status.Running;
|
||||
}
|
||||
|
||||
if ( status == Status.Success ) {
|
||||
SendToBack(i);
|
||||
return Status.Success;
|
||||
}
|
||||
}
|
||||
|
||||
return Status.Failure;
|
||||
}
|
||||
|
||||
void SendToBack(int i) {
|
||||
var c = outConnections[i];
|
||||
outConnections.RemoveAt(i);
|
||||
outConnections.Add(c);
|
||||
}
|
||||
|
||||
protected override void OnReset() {
|
||||
current = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dcf40bac689367f4ba07b1a75299e628
|
||||
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/BehaviourTrees/Nodes/Composites/FlipSelector.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,123 @@
|
||||
using System.Collections.Generic;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Name("Parallel", 8)]
|
||||
[Category("Composites")]
|
||||
[Description("Executes all children simultaneously and return Success or Failure depending on the selected Policy.")]
|
||||
[ParadoxNotion.Design.Icon("Parallel")]
|
||||
[Color("ff64cb")]
|
||||
public class Parallel : BTComposite
|
||||
{
|
||||
|
||||
public enum ParallelPolicy
|
||||
{
|
||||
FirstFailure,
|
||||
FirstSuccess,
|
||||
FirstSuccessOrFailure
|
||||
}
|
||||
|
||||
[Tooltip("The policy determines when the Parallel node will end and return its Status.")]
|
||||
public ParallelPolicy policy = ParallelPolicy.FirstFailure;
|
||||
[Name("Repeat"), Tooltip("If true, finished children are repeated until the Policy set is met, or until all children have had a chance to finish at least once.")]
|
||||
public bool dynamic;
|
||||
|
||||
private bool[] finishedConnections;
|
||||
private int finishedConnectionsCount;
|
||||
|
||||
public override void OnGraphStarted() {
|
||||
finishedConnections = new bool[outConnections.Count];
|
||||
finishedConnectionsCount = 0;
|
||||
}
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
var defferedStatus = Status.Resting;
|
||||
for ( var i = 0; i < outConnections.Count; i++ ) {
|
||||
var connection = outConnections[i];
|
||||
var isConnectionFinished = finishedConnections[i] == true;
|
||||
|
||||
if ( !dynamic && isConnectionFinished ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( connection.status != Status.Running && isConnectionFinished ) {
|
||||
connection.Reset();
|
||||
}
|
||||
|
||||
status = connection.Execute(agent, blackboard);
|
||||
|
||||
if ( defferedStatus == Status.Resting ) {
|
||||
if ( status == Status.Failure && ( policy == ParallelPolicy.FirstFailure || policy == ParallelPolicy.FirstSuccessOrFailure ) ) {
|
||||
defferedStatus = Status.Failure;
|
||||
}
|
||||
|
||||
if ( status == Status.Success && ( policy == ParallelPolicy.FirstSuccess || policy == ParallelPolicy.FirstSuccessOrFailure ) ) {
|
||||
defferedStatus = Status.Success;
|
||||
}
|
||||
}
|
||||
|
||||
if ( status != Status.Running && !isConnectionFinished ) {
|
||||
finishedConnections[i] = true;
|
||||
finishedConnectionsCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( defferedStatus != Status.Resting ) {
|
||||
ResetRunning();
|
||||
status = defferedStatus;
|
||||
return defferedStatus;
|
||||
}
|
||||
|
||||
if ( finishedConnectionsCount == outConnections.Count ) {
|
||||
ResetRunning();
|
||||
switch ( policy ) {
|
||||
case ParallelPolicy.FirstFailure:
|
||||
return Status.Success;
|
||||
case ParallelPolicy.FirstSuccess:
|
||||
return Status.Failure;
|
||||
}
|
||||
}
|
||||
|
||||
return Status.Running;
|
||||
}
|
||||
|
||||
protected override void OnReset() {
|
||||
for ( var i = 0; i < finishedConnections.Length; i++ ) { finishedConnections[i] = false; }
|
||||
finishedConnectionsCount = 0;
|
||||
}
|
||||
|
||||
void ResetRunning() {
|
||||
for ( var i = 0; i < outConnections.Count; i++ ) {
|
||||
if ( outConnections[i].status == Status.Running ) {
|
||||
outConnections[i].Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
public override string GetConnectionInfo(int i) {
|
||||
if ( dynamic && status == Status.Running ) {
|
||||
return finishedConnections[i] ? "Repeating" : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
protected override void OnNodeGUI() {
|
||||
GUILayout.Label(( dynamic ? "<b>REPEAT</b>\n" : "" ) + policy.ToString().SplitCamelCase());
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 20bb0006fe2ddc941b3bddd6e00a1321
|
||||
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/BehaviourTrees/Nodes/Composites/Parallel.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,205 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using ParadoxNotion.Serialization.FullSerializer;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
class PrioritySelector_0 : BTComposite
|
||||
{
|
||||
[SerializeField] public List<BBParameter<float>> priorities = null;
|
||||
}
|
||||
///----------------------------------------------------------------------------------------------
|
||||
|
||||
[Category("Composites")]
|
||||
[Description("Used for Utility AI, the Priority Selector executes the child with the highest utility weight. If it fails, the Priority Selector will continue with the next highest utility weight child until one Succeeds, or until all Fail (similar to how a normal Selector does).\n\nEach child branch represents a desire, where each desire has one or more consideration which are all averaged.\nConsiderations are a pair of input value and curve, which together produce the consideration utility weight.\n\nIf Dynamic option is enabled, will continously evaluate utility weights and execute the child with the highest one regardless of what status the children return.")]
|
||||
[ParadoxNotion.Design.Icon("Priority")]
|
||||
[Color("b3ff7f")]
|
||||
[fsMigrateVersions(typeof(PrioritySelector_0))]
|
||||
public class PrioritySelector : BTComposite, IMigratable<PrioritySelector_0>
|
||||
{
|
||||
///----------------------------------------------------------------------------------------------
|
||||
void IMigratable<PrioritySelector_0>.Migrate(PrioritySelector_0 model) {
|
||||
this.desires = new List<Desire>();
|
||||
foreach ( var priority in model.priorities ) {
|
||||
var desire = new Desire();
|
||||
this.desires.Add(desire);
|
||||
var consideration = desire.AddConsideration(graphBlackboard);
|
||||
consideration.input = priority;
|
||||
}
|
||||
}
|
||||
///----------------------------------------------------------------------------------------------
|
||||
|
||||
[System.Serializable]
|
||||
public class Desire
|
||||
{
|
||||
[ParadoxNotion.Serialization.FullSerializer.fsIgnoreInBuild]
|
||||
public string name;
|
||||
[ParadoxNotion.Serialization.FullSerializer.fsIgnoreInBuild]
|
||||
public bool foldout;
|
||||
public List<Consideration> considerations = new List<Consideration>();
|
||||
|
||||
public Consideration AddConsideration(IBlackboard bb) {
|
||||
var result = new Consideration(bb);
|
||||
considerations.Add(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void RemoveConsideration(Consideration consideration) { considerations.Remove(consideration); }
|
||||
|
||||
public float GetCompoundUtility() {
|
||||
float total = 0;
|
||||
for ( var i = 0; i < considerations.Count; i++ ) {
|
||||
total += considerations[i].utility;
|
||||
}
|
||||
return total / considerations.Count;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class Consideration
|
||||
{
|
||||
public BBParameter<float> input;
|
||||
public BBParameter<AnimationCurve> function;
|
||||
public float utility => function.value != null ? function.value.Evaluate(input.value) : input.value;
|
||||
public Consideration(IBlackboard blackboard) {
|
||||
input = new BBParameter<float> { value = 1f, bb = blackboard };
|
||||
function = new BBParameter<AnimationCurve> { bb = blackboard };
|
||||
}
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
|
||||
[Tooltip("If enabled, will continously evaluate utility weights and execute the child with the highest one accordingly. In this mode child return status does not matter.")]
|
||||
public bool dynamic;
|
||||
[AutoSortWithChildrenConnections]
|
||||
public List<Desire> desires;
|
||||
|
||||
private Connection[] orderedConnections;
|
||||
private int current = 0;
|
||||
|
||||
public override void OnChildConnected(int index) {
|
||||
if ( desires == null ) { desires = new List<Desire>(); }
|
||||
if ( desires.Count < outConnections.Count ) { desires.Insert(index, new Desire()); }
|
||||
}
|
||||
|
||||
public override void OnChildDisconnected(int index) { desires.RemoveAt(index); }
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
if ( dynamic ) {
|
||||
var highestPriority = float.NegativeInfinity;
|
||||
var best = 0;
|
||||
for ( var i = 0; i < outConnections.Count; i++ ) {
|
||||
var priority = desires[i].GetCompoundUtility();
|
||||
if ( priority > highestPriority ) {
|
||||
highestPriority = priority;
|
||||
best = i;
|
||||
}
|
||||
}
|
||||
|
||||
if ( best != current ) {
|
||||
outConnections[current].Reset();
|
||||
current = best;
|
||||
}
|
||||
return outConnections[current].Execute(agent, blackboard);
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
|
||||
if ( status == Status.Resting ) {
|
||||
orderedConnections = outConnections.OrderBy(c => desires[outConnections.IndexOf(c)].GetCompoundUtility()).ToArray();
|
||||
}
|
||||
|
||||
for ( var i = orderedConnections.Length; i-- > 0; ) {
|
||||
status = orderedConnections[i].Execute(agent, blackboard);
|
||||
if ( status == Status.Success ) {
|
||||
return Status.Success;
|
||||
}
|
||||
|
||||
if ( status == Status.Running ) {
|
||||
current = i;
|
||||
return Status.Running;
|
||||
}
|
||||
}
|
||||
|
||||
return Status.Failure;
|
||||
}
|
||||
|
||||
protected override void OnReset() { current = 0; }
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
//..
|
||||
public override string GetConnectionInfo(int i) {
|
||||
var desire = desires[i];
|
||||
var desireName = string.IsNullOrEmpty(desire.name) ? "DESIRE " + i.ToString() : desire.name;
|
||||
var result = desireName.ToUpper() + "\n";
|
||||
for ( var j = 0; j < desire.considerations.Count; j++ ) {
|
||||
result += desire.considerations[j].input.ToString() + " (" + desire.considerations[j].utility.ToString("0.00") + ")" + "\n";
|
||||
}
|
||||
return result += string.Format("<b>Avg.</b> ({0})", desire.GetCompoundUtility().ToString("0.00"));
|
||||
}
|
||||
|
||||
//..
|
||||
public override void OnConnectionInspectorGUI(int i) {
|
||||
var desire = desires[i];
|
||||
var optionsB = new EditorUtils.ReorderableListOptions();
|
||||
optionsB.allowAdd = false;
|
||||
optionsB.allowRemove = true;
|
||||
EditorUtils.ReorderableList(desire.considerations, optionsB, (j, pickedB) =>
|
||||
{
|
||||
var consideration = desire.considerations[j];
|
||||
GUILayout.BeginVertical("box");
|
||||
consideration.input = (BBParameter<float>)NodeCanvas.Editor.BBParameterEditor.ParameterField("Input", consideration.input, true);
|
||||
consideration.function = (BBParameter<AnimationCurve>)NodeCanvas.Editor.BBParameterEditor.ParameterField("Curve", consideration.function);
|
||||
GUILayout.EndVertical();
|
||||
});
|
||||
|
||||
if ( GUILayout.Button("Add Consideration") ) { desire.AddConsideration(graphBlackboard); }
|
||||
EditorUtils.Separator();
|
||||
}
|
||||
|
||||
protected override void OnNodeGUI() {
|
||||
if ( dynamic ) { GUILayout.Label("<b>DYNAMIC</b>"); }
|
||||
}
|
||||
|
||||
//..
|
||||
protected override void OnNodeInspectorGUI() {
|
||||
|
||||
if ( outConnections.Count == 0 ) {
|
||||
GUILayout.Label("Make some connections first");
|
||||
return;
|
||||
}
|
||||
|
||||
dynamic = UnityEditor.EditorGUILayout.Toggle(new GUIContent("Dynamic", "If enabled, will continously evaluate utility weights and execute the child with the highest one accordingly. In this mode child return status does not matter."), dynamic);
|
||||
|
||||
EditorUtils.Separator();
|
||||
EditorUtils.CoolLabel("Desires");
|
||||
|
||||
var optionsA = new EditorUtils.ReorderableListOptions();
|
||||
optionsA.allowAdd = false;
|
||||
optionsA.allowRemove = false;
|
||||
EditorUtils.ReorderableList(desires, optionsA, (i, pickedA) =>
|
||||
{
|
||||
var desire = desires[i];
|
||||
var desireName = string.IsNullOrEmpty(desire.name) ? "DESIRE " + i.ToString() : desire.name;
|
||||
desire.foldout = UnityEditor.EditorGUILayout.Foldout(desire.foldout, new GUIContent(desireName));
|
||||
if ( desire.foldout ) {
|
||||
desire.name = UnityEditor.EditorGUILayout.TextField(" Friendly Name", desire.name);
|
||||
OnConnectionInspectorGUI(i);
|
||||
}
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39f51e3aa06f96c4399b79d7656917c6
|
||||
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/BehaviourTrees/Nodes/Composites/PrioritySelector.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,133 @@
|
||||
using System.Collections.Generic;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Category("Composites")]
|
||||
[Description("Selects a child to execute based on its chance to be selected and returns Success if the child returns Success, otherwise picks another child.\nReturns Failure if all children return Failure, or a direct 'Failure Chance' is introduced.")]
|
||||
[ParadoxNotion.Design.Icon("ProbabilitySelector")]
|
||||
[Color("b3ff7f")]
|
||||
public class ProbabilitySelector : BTComposite
|
||||
{
|
||||
|
||||
[AutoSortWithChildrenConnections, Tooltip("The weights of the children.")]
|
||||
public List<BBParameter<float>> childWeights;
|
||||
[Tooltip("A chance for the node to fail immediately.")]
|
||||
public BBParameter<float> failChance;
|
||||
|
||||
private bool[] indexFailed;
|
||||
private float[] tmpWeights;
|
||||
private float tmpFailWeight;
|
||||
private float tmpTotal;
|
||||
private float tmpDice;
|
||||
|
||||
public override void OnChildConnected(int index) {
|
||||
if ( childWeights == null ) { childWeights = new List<BBParameter<float>>(); }
|
||||
if ( childWeights.Count < outConnections.Count ) {
|
||||
childWeights.Insert(index, new BBParameter<float> { value = 1, bb = graphBlackboard });
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnChildDisconnected(int index) {
|
||||
childWeights.RemoveAt(index);
|
||||
}
|
||||
|
||||
public override void OnGraphStarted() { OnReset(); }
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
if ( status == Status.Resting ) {
|
||||
tmpDice = Random.value;
|
||||
tmpFailWeight = failChance.value;
|
||||
tmpTotal = tmpFailWeight;
|
||||
for ( var i = 0; i < childWeights.Count; i++ ) {
|
||||
var childWeight = childWeights[i].value;
|
||||
tmpTotal += childWeight;
|
||||
tmpWeights[i] = childWeight;
|
||||
}
|
||||
}
|
||||
|
||||
var prob = tmpFailWeight / tmpTotal;
|
||||
if ( tmpDice < prob ) {
|
||||
return Status.Failure;
|
||||
}
|
||||
|
||||
for ( var i = 0; i < outConnections.Count; i++ ) {
|
||||
|
||||
if ( indexFailed[i] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
prob += tmpWeights[i] / tmpTotal;
|
||||
if ( tmpDice <= prob ) {
|
||||
status = outConnections[i].Execute(agent, blackboard);
|
||||
if ( status == Status.Success || status == Status.Running ) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if ( status == Status.Failure ) {
|
||||
indexFailed[i] = true;
|
||||
tmpTotal -= tmpWeights[i];
|
||||
return Status.Running;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Status.Failure;
|
||||
}
|
||||
|
||||
protected override void OnReset() {
|
||||
tmpWeights = new float[outConnections.Count];
|
||||
indexFailed = new bool[outConnections.Count];
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
float GetTotal() {
|
||||
var total = failChance.value;
|
||||
for ( var i = 0; i < childWeights.Count; i++ ) {
|
||||
total += childWeights[i].value;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public override string GetConnectionInfo(int i) {
|
||||
return Mathf.Round(( childWeights[i].value / GetTotal() ) * 100) + "%";
|
||||
}
|
||||
|
||||
public override void OnConnectionInspectorGUI(int i) {
|
||||
NodeCanvas.Editor.BBParameterEditor.ParameterField("Weight", childWeights[i]);
|
||||
}
|
||||
|
||||
protected override void OnNodeInspectorGUI() {
|
||||
|
||||
if ( outConnections.Count == 0 ) {
|
||||
GUILayout.Label("Make some connections first");
|
||||
return;
|
||||
}
|
||||
|
||||
var total = GetTotal();
|
||||
for ( var i = 0; i < childWeights.Count; i++ ) {
|
||||
GUILayout.BeginHorizontal();
|
||||
childWeights[i] = (BBParameter<float>)NodeCanvas.Editor.BBParameterEditor.ParameterField("Weight", childWeights[i]);
|
||||
GUILayout.Label(Mathf.Round(( childWeights[i].value / total ) * 100) + "%", GUILayout.Width(38));
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
GUILayout.Space(5);
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
failChance = (BBParameter<float>)NodeCanvas.Editor.BBParameterEditor.ParameterField("Direct Failure Chance", failChance);
|
||||
GUILayout.Label(Mathf.Round(( failChance.value / total ) * 100) + "%", GUILayout.Width(38));
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 23428d321072cac43b4e9c02610e96d6
|
||||
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/BehaviourTrees/Nodes/Composites/ProbabilitySelector.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,82 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Name("Selector", 9)]
|
||||
[Category("Composites")]
|
||||
[Description("Executes its childrfen in order and returns Failure if all children return Failure. As soon as a child returns Success, the Selector will stop and return Success as well.")]
|
||||
[ParadoxNotion.Design.Icon("Selector")]
|
||||
[Color("b3ff7f")]
|
||||
public class Selector : BTComposite
|
||||
{
|
||||
|
||||
[Tooltip("If true, then higher priority children are re-evaluated per frame and if either returns Success, then the Selector will immediately stop and return Success as well.")]
|
||||
public bool dynamic;
|
||||
[Tooltip("If true, the children order of execution is shuffled each time the Selector resets.")]
|
||||
public bool random;
|
||||
|
||||
private int lastRunningNodeIndex;
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
for ( var i = dynamic ? 0 : lastRunningNodeIndex; i < outConnections.Count; i++ ) {
|
||||
|
||||
status = outConnections[i].Execute(agent, blackboard);
|
||||
|
||||
switch ( status ) {
|
||||
case Status.Running:
|
||||
|
||||
if ( dynamic && i < lastRunningNodeIndex ) {
|
||||
for ( var j = i + 1; j <= lastRunningNodeIndex; j++ ) {
|
||||
outConnections[j].Reset();
|
||||
}
|
||||
}
|
||||
|
||||
lastRunningNodeIndex = i;
|
||||
return Status.Running;
|
||||
|
||||
case Status.Success:
|
||||
|
||||
if ( dynamic && i < lastRunningNodeIndex ) {
|
||||
for ( var j = i + 1; j <= lastRunningNodeIndex; j++ ) {
|
||||
outConnections[j].Reset();
|
||||
}
|
||||
}
|
||||
|
||||
return Status.Success;
|
||||
}
|
||||
}
|
||||
|
||||
return Status.Failure;
|
||||
}
|
||||
|
||||
protected override void OnReset() {
|
||||
lastRunningNodeIndex = 0;
|
||||
if ( random ) { outConnections = outConnections.Shuffle(); }
|
||||
}
|
||||
|
||||
public override void OnChildDisconnected(int index) {
|
||||
if ( index != 0 && index == lastRunningNodeIndex ) {
|
||||
lastRunningNodeIndex--;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGraphStarted() { OnReset(); }
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void OnNodeGUI() {
|
||||
if ( dynamic ) { GUILayout.Label("<b>DYNAMIC</b>"); }
|
||||
if ( random ) { GUILayout.Label("<b>RANDOM</b>"); }
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aa1c35ff60b06c74cb9102cc2babf462
|
||||
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/BehaviourTrees/Nodes/Composites/Selector.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,80 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Name("Sequencer", 10)]
|
||||
[Category("Composites")]
|
||||
[Description("Executes its children in order and returns Success if all children return Success. As soon as a child returns Failure, the Sequencer will stop and return Failure as well.")]
|
||||
[ParadoxNotion.Design.Icon("Sequencer")]
|
||||
[Color("bf7fff")]
|
||||
public class Sequencer : BTComposite
|
||||
{
|
||||
|
||||
[Tooltip("If true, then higher priority children are re-evaluated per frame and if either returns Failure, then the Sequencer will immediately stop and return Failure as well.")]
|
||||
public bool dynamic;
|
||||
[Tooltip("If true, the children order of execution is shuffled each time the Sequencer resets.")]
|
||||
public bool random;
|
||||
|
||||
private int lastRunningNodeIndex = 0;
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
for ( var i = dynamic ? 0 : lastRunningNodeIndex; i < outConnections.Count; i++ ) {
|
||||
|
||||
status = outConnections[i].Execute(agent, blackboard);
|
||||
|
||||
switch ( status ) {
|
||||
case Status.Running:
|
||||
|
||||
if ( dynamic && i < lastRunningNodeIndex ) {
|
||||
for ( var j = i + 1; j <= lastRunningNodeIndex; j++ ) {
|
||||
outConnections[j].Reset();
|
||||
}
|
||||
}
|
||||
|
||||
lastRunningNodeIndex = i;
|
||||
return Status.Running;
|
||||
|
||||
case Status.Failure:
|
||||
|
||||
if ( dynamic && i < lastRunningNodeIndex ) {
|
||||
for ( var j = i + 1; j <= lastRunningNodeIndex; j++ ) {
|
||||
outConnections[j].Reset();
|
||||
}
|
||||
}
|
||||
|
||||
return Status.Failure;
|
||||
}
|
||||
}
|
||||
|
||||
return Status.Success;
|
||||
}
|
||||
|
||||
protected override void OnReset() {
|
||||
lastRunningNodeIndex = 0;
|
||||
if ( random ) { outConnections = outConnections.Shuffle(); }
|
||||
}
|
||||
|
||||
public override void OnChildDisconnected(int index) {
|
||||
if ( index != 0 && index == lastRunningNodeIndex ) {
|
||||
lastRunningNodeIndex--;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGraphStarted() { OnReset(); }
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
protected override void OnNodeGUI() {
|
||||
if ( dynamic ) { GUILayout.Label("<b>DYNAMIC</b>"); }
|
||||
if ( random ) { GUILayout.Label("<b>RANDOM</b>"); }
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bafebe0850f5ea84eb87e77c674123e8
|
||||
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/BehaviourTrees/Nodes/Composites/Sequencer.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,32 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Name("Step Sequencer")]
|
||||
[Category("Composites")]
|
||||
[Description("In comparison to a normal Sequencer which executes all its children until one fails, Step Sequencer executes its children one-by-one per Step Sequencer execution. The executed child status is returned regardless of Success or Failure.")]
|
||||
[ParadoxNotion.Design.Icon("StepIterator")]
|
||||
[Color("bf7fff")]
|
||||
public class StepIterator : BTComposite
|
||||
{
|
||||
|
||||
private int current;
|
||||
|
||||
public override void OnGraphStarted() {
|
||||
current = 0;
|
||||
}
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
current = current % outConnections.Count;
|
||||
return outConnections[current].Execute(agent, blackboard);
|
||||
}
|
||||
|
||||
protected override void OnReset() {
|
||||
current++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1beecc40e55bf82488985475900341fe
|
||||
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/BehaviourTrees/Nodes/Composites/StepIterator.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,137 @@
|
||||
using System.Collections.Generic;
|
||||
using NodeCanvas.Framework;
|
||||
using NodeCanvas.Framework.Internal;
|
||||
using ParadoxNotion;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Category("Composites")]
|
||||
[Description("Executes one child based on the provided int or enum case and returns its status.")]
|
||||
[ParadoxNotion.Design.Icon("IndexSwitcher")]
|
||||
[Color("b3ff7f")]
|
||||
public class Switch : BTComposite
|
||||
{
|
||||
|
||||
public enum CaseSelectionMode
|
||||
{
|
||||
IndexBased = 0,
|
||||
EnumBased = 1
|
||||
}
|
||||
|
||||
public enum OutOfRangeMode
|
||||
{
|
||||
ReturnFailure,
|
||||
LoopIndex
|
||||
}
|
||||
|
||||
[Tooltip("If true and the 'case' change while a child is running, that child will immediately be interrupted and the new child will be executed.")]
|
||||
public bool dynamic;
|
||||
[Tooltip("The selection mode used.")]
|
||||
public CaseSelectionMode selectionMode = CaseSelectionMode.IndexBased;
|
||||
|
||||
[ShowIf("selectionMode", 0)]
|
||||
public BBParameter<int> intCase;
|
||||
[ShowIf("selectionMode", 0)]
|
||||
public OutOfRangeMode outOfRangeMode = OutOfRangeMode.LoopIndex;
|
||||
|
||||
[ShowIf("selectionMode", 1), BlackboardOnly]
|
||||
public BBObjectParameter enumCase = new BBObjectParameter(typeof(System.Enum));
|
||||
private Dictionary<int, int> enumCasePairing;
|
||||
|
||||
private int current;
|
||||
private int runningIndex;
|
||||
|
||||
public override void OnGraphStarted() {
|
||||
if ( selectionMode == CaseSelectionMode.EnumBased ) {
|
||||
var enumValue = enumCase.value;
|
||||
if ( enumValue != null ) {
|
||||
enumCasePairing = new Dictionary<int, int>();
|
||||
var enumValues = System.Enum.GetValues(enumValue.GetType());
|
||||
for ( var i = 0; i < enumValues.Length; i++ ) {
|
||||
enumCasePairing[(int)enumValues.GetValue(i)] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
if ( outConnections.Count == 0 ) {
|
||||
return Status.Optional;
|
||||
}
|
||||
|
||||
if ( status == Status.Resting || dynamic ) {
|
||||
|
||||
if ( selectionMode == CaseSelectionMode.IndexBased ) {
|
||||
current = intCase.value;
|
||||
if ( outOfRangeMode == OutOfRangeMode.LoopIndex ) {
|
||||
current = Mathf.Abs(current) % outConnections.Count;
|
||||
}
|
||||
|
||||
} else {
|
||||
current = enumCasePairing[(int)enumCase.value];
|
||||
}
|
||||
|
||||
if ( runningIndex != current ) {
|
||||
outConnections[runningIndex].Reset();
|
||||
}
|
||||
|
||||
if ( current < 0 || current >= outConnections.Count ) {
|
||||
return Status.Failure;
|
||||
}
|
||||
}
|
||||
|
||||
status = outConnections[current].Execute(agent, blackboard);
|
||||
|
||||
if ( status == Status.Running ) {
|
||||
runningIndex = current;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
public override string GetConnectionInfo(int i) {
|
||||
if ( selectionMode == CaseSelectionMode.EnumBased ) {
|
||||
if ( enumCase.value == null ) {
|
||||
return "Null Enum".FormatError();
|
||||
}
|
||||
var enumNames = System.Enum.GetNames(enumCase.value.GetType());
|
||||
if ( i >= enumNames.Length ) {
|
||||
return "Never".FormatError();
|
||||
}
|
||||
return enumNames[i];
|
||||
}
|
||||
return i.ToString();
|
||||
}
|
||||
|
||||
protected override void OnNodeGUI() {
|
||||
if ( dynamic ) {
|
||||
GUILayout.Label("<b>DYNAMIC</b>");
|
||||
}
|
||||
GUILayout.Label(selectionMode == CaseSelectionMode.IndexBased ? ( "Current = " + intCase.ToString() ) : enumCase.ToString());
|
||||
}
|
||||
|
||||
protected override void OnNodeInspectorGUI() {
|
||||
base.OnNodeInspectorGUI();
|
||||
if ( selectionMode == CaseSelectionMode.EnumBased ) {
|
||||
if ( enumCase.value != null ) {
|
||||
GUILayout.BeginVertical("box");
|
||||
foreach ( var s in System.Enum.GetNames(enumCase.value.GetType()) ) {
|
||||
GUILayout.Label(s);
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d3c9285b12215614d98d6497ad391e78
|
||||
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/BehaviourTrees/Nodes/Composites/Switch.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad02d7f1f3402ef4083d1af9260f390e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
@@ -0,0 +1,88 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Name("Conditional")]
|
||||
[Category("Decorators")]
|
||||
[Description("Executes and returns the child status only if the condition is true. Returns Failure if the condition is false.")]
|
||||
[ParadoxNotion.Design.Icon("Accessor")]
|
||||
public class ConditionalEvaluator : BTDecorator, ITaskAssignable<ConditionTask>
|
||||
{
|
||||
|
||||
[Name("Dynamic"), Tooltip("If enabled, the condition is re-evaluated per frame and the child is aborted if the condition becomes false.")]
|
||||
public bool isDynamic;
|
||||
[Tooltip("The status that will be returned if the assigned condition is or becomes false.")]
|
||||
public CompactStatus conditionFailReturn = CompactStatus.Failure;
|
||||
|
||||
[SerializeField]
|
||||
private ConditionTask _condition;
|
||||
private bool accessed;
|
||||
|
||||
public Task task {
|
||||
get { return condition; }
|
||||
set { condition = (ConditionTask)value; }
|
||||
}
|
||||
|
||||
private ConditionTask condition {
|
||||
get { return _condition; }
|
||||
set { _condition = value; }
|
||||
}
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
if ( decoratedConnection == null ) {
|
||||
return Status.Optional;
|
||||
}
|
||||
|
||||
if ( condition == null ) {
|
||||
return decoratedConnection.Execute(agent, blackboard);
|
||||
}
|
||||
|
||||
if ( status == Status.Resting ) {
|
||||
condition.Enable(agent, blackboard);
|
||||
}
|
||||
|
||||
if ( isDynamic ) {
|
||||
|
||||
if ( condition.Check(agent, blackboard) ) {
|
||||
return decoratedConnection.Execute(agent, blackboard);
|
||||
}
|
||||
decoratedConnection.Reset();
|
||||
return (Status)conditionFailReturn;
|
||||
|
||||
} else {
|
||||
|
||||
if ( status != Status.Running ) {
|
||||
accessed = condition.Check(agent, blackboard);
|
||||
}
|
||||
|
||||
return accessed ? decoratedConnection.Execute(agent, blackboard) : (Status)conditionFailReturn;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnReset() {
|
||||
if ( condition != null ) { condition.Disable(); }
|
||||
accessed = false;
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
protected override void OnNodeGUI() {
|
||||
if ( isDynamic ) { GUILayout.Label("<b>DYNAMIC</b>"); }
|
||||
}
|
||||
|
||||
protected override void OnNodeInspectorGUI() {
|
||||
base.OnNodeInspectorGUI();
|
||||
EditorUtils.Separator();
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 77a4b51944584ae429faf6c94c84bc6c
|
||||
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/BehaviourTrees/Nodes/Decorators/ConditionalEvaluator.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,119 @@
|
||||
using System.Collections;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Name("Filter")]
|
||||
[Category("Decorators")]
|
||||
[Description("Filters the access of its child either a specific number of times, or every specific amount of time.")]
|
||||
[ParadoxNotion.Design.Icon("Filter")]
|
||||
public class Filter : BTDecorator
|
||||
{
|
||||
|
||||
public enum FilterMode
|
||||
{
|
||||
LimitNumberOfTimes = 0,
|
||||
CoolDown = 1
|
||||
}
|
||||
|
||||
public enum Policy
|
||||
{
|
||||
SuccessOrFailure,
|
||||
SuccessOnly,
|
||||
FailureOnly
|
||||
}
|
||||
|
||||
[Tooltip("The mode to use.")]
|
||||
public FilterMode filterMode = FilterMode.CoolDown;
|
||||
[ShowIf("filterMode", 0)]
|
||||
[Name("Max Times"), Tooltip("The max ammount of times to allow the child to execute until the tree is completely restarted.")]
|
||||
public BBParameter<int> maxCount = 1;
|
||||
[ShowIf("filterMode", 0)]
|
||||
[Name("Increase Count When"), Tooltip("Only increase count if the selected status is returned from the child.")]
|
||||
public Policy policy = Policy.SuccessOrFailure;
|
||||
[ShowIf("filterMode", 1), Tooltip("The time to disallow execution for.")]
|
||||
public BBParameter<float> coolDownTime = 5f;
|
||||
[Name("Optional When Filtered"), Tooltip("If enabled, the Filter Decorator will return an Optional status when it is filtered. Otherwise it will return Failure.")]
|
||||
public bool inactiveWhenLimited = true;
|
||||
|
||||
private int executedCount;
|
||||
private float currentTime;
|
||||
|
||||
public override void OnGraphStoped() {
|
||||
executedCount = 0;
|
||||
currentTime = 0;
|
||||
}
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
if ( decoratedConnection == null ) {
|
||||
return Status.Optional;
|
||||
}
|
||||
|
||||
switch ( filterMode ) {
|
||||
case FilterMode.CoolDown:
|
||||
|
||||
if ( currentTime > 0 ) {
|
||||
return inactiveWhenLimited ? Status.Optional : Status.Failure;
|
||||
}
|
||||
|
||||
status = decoratedConnection.Execute(agent, blackboard);
|
||||
if ( status == Status.Success || status == Status.Failure ) {
|
||||
StartCoroutine(Cooldown());
|
||||
}
|
||||
break;
|
||||
|
||||
case FilterMode.LimitNumberOfTimes:
|
||||
|
||||
if ( executedCount >= maxCount.value ) {
|
||||
return inactiveWhenLimited ? Status.Optional : Status.Failure;
|
||||
}
|
||||
|
||||
status = decoratedConnection.Execute(agent, blackboard);
|
||||
if
|
||||
(
|
||||
( status == Status.Success && policy == Policy.SuccessOnly ) ||
|
||||
( status == Status.Failure && policy == Policy.FailureOnly ) ||
|
||||
( ( status == Status.Success || status == Status.Failure ) && policy == Policy.SuccessOrFailure )
|
||||
) {
|
||||
executedCount += 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
IEnumerator Cooldown() {
|
||||
currentTime = coolDownTime.value;
|
||||
while ( currentTime > 0 ) {
|
||||
yield return null;
|
||||
currentTime -= Time.deltaTime;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
protected override void OnNodeGUI() {
|
||||
|
||||
if ( filterMode == FilterMode.CoolDown ) {
|
||||
GUILayout.Space(25);
|
||||
var pRect = new Rect(5, GUILayoutUtility.GetLastRect().y, rect.width - 10, 20);
|
||||
UnityEditor.EditorGUI.ProgressBar(pRect, currentTime / coolDownTime.value, currentTime > 0 ? "Cooling..." : "Cooled");
|
||||
} else
|
||||
if ( filterMode == FilterMode.LimitNumberOfTimes ) {
|
||||
GUILayout.Label(executedCount + " / " + maxCount.value + " Accessed Times");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb5ec2484dff28347b4302b59cdb3139
|
||||
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/BehaviourTrees/Nodes/Decorators/Filter.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,97 @@
|
||||
using System.Collections.Generic;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Name("Guard")]
|
||||
[Category("Decorators")]
|
||||
[ParadoxNotion.Design.Icon("Shield")]
|
||||
[Description("Protects the decorated child from running if another Guard with the same token is already guarding (Running) that token.\nGuarding is global for all of the agent Behaviour Trees.")]
|
||||
public class Guard : BTDecorator
|
||||
{
|
||||
|
||||
public enum GuardMode
|
||||
{
|
||||
ReturnFailure,
|
||||
WaitUntilReleased
|
||||
}
|
||||
|
||||
[Tooltip("A unique Token to use for guarding.")]
|
||||
public BBParameter<string> token;
|
||||
[Tooltip("What to return in case the token is already guarded by another Guard.")]
|
||||
public GuardMode ifGuarded = GuardMode.ReturnFailure;
|
||||
|
||||
private bool isGuarding;
|
||||
|
||||
private static readonly Dictionary<GameObject, List<Guard>> guards = new Dictionary<GameObject, List<Guard>>();
|
||||
private static List<Guard> AgentGuards(Component agent) { return guards[agent.gameObject]; }
|
||||
|
||||
public override void OnGraphStarted() {
|
||||
SetGuards(graphAgent);
|
||||
}
|
||||
|
||||
public override void OnGraphStoped() {
|
||||
foreach ( var runningGraph in Graph.runningGraphs ) {
|
||||
if ( runningGraph.agent != null && runningGraph.agent.gameObject == this.graphAgent.gameObject ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
guards.Remove(graphAgent.gameObject);
|
||||
}
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
if ( decoratedConnection == null ) {
|
||||
return Status.Optional;
|
||||
}
|
||||
|
||||
if ( agent != graphAgent ) {
|
||||
SetGuards(agent);
|
||||
}
|
||||
|
||||
for ( var i = 0; i < AgentGuards(agent).Count; i++ ) {
|
||||
var guard = AgentGuards(agent)[i];
|
||||
if ( guard != this && guard.isGuarding && guard.token.value == this.token.value ) {
|
||||
return ifGuarded == GuardMode.ReturnFailure ? Status.Failure : Status.Running;
|
||||
}
|
||||
}
|
||||
|
||||
status = decoratedConnection.Execute(agent, blackboard);
|
||||
if ( status == Status.Running ) {
|
||||
isGuarding = true;
|
||||
return Status.Running;
|
||||
}
|
||||
|
||||
isGuarding = false;
|
||||
return status;
|
||||
}
|
||||
|
||||
protected override void OnReset() {
|
||||
isGuarding = false;
|
||||
}
|
||||
|
||||
void SetGuards(Component guardAgent) {
|
||||
if ( !guards.ContainsKey(guardAgent.gameObject) ) {
|
||||
guards[guardAgent.gameObject] = new List<Guard>();
|
||||
}
|
||||
|
||||
if ( !AgentGuards(guardAgent).Contains(this) && !string.IsNullOrEmpty(token.value) ) {
|
||||
AgentGuards(guardAgent).Add(this);
|
||||
}
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
protected override void OnNodeGUI() {
|
||||
GUILayout.Label(string.Format("<b>' {0} '</b>", string.IsNullOrEmpty(token.value) ? "NONE" : token.value));
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19fc82817a5cfd94f99129e7f7a6f879
|
||||
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/BehaviourTrees/Nodes/Decorators/Guard.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,58 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Name("Interrupt")]
|
||||
[Category("Decorators")]
|
||||
[Description("Executes and returns the child status. If the condition is or becomes true, the child is interrupted and returns Failure.")]
|
||||
[ParadoxNotion.Design.Icon("Interruptor")]
|
||||
public class Interruptor : BTDecorator, 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; }
|
||||
}
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
if ( decoratedConnection == null ) {
|
||||
return Status.Optional;
|
||||
}
|
||||
|
||||
if ( condition == null ) {
|
||||
return decoratedConnection.Execute(agent, blackboard);
|
||||
}
|
||||
|
||||
if ( status == Status.Resting ) {
|
||||
condition.Enable(agent, blackboard);
|
||||
}
|
||||
|
||||
if ( condition.Check(agent, blackboard) == false ) {
|
||||
return decoratedConnection.Execute(agent, blackboard);
|
||||
}
|
||||
|
||||
if ( decoratedConnection.status == Status.Running ) {
|
||||
decoratedConnection.Reset();
|
||||
}
|
||||
|
||||
return Status.Failure;
|
||||
}
|
||||
|
||||
protected override void OnReset() {
|
||||
if ( condition != null ) { condition.Disable(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 02d64e844d954b94d94268d941ad3768
|
||||
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/BehaviourTrees/Nodes/Decorators/Interruptor.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,33 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Name("Invert")]
|
||||
[Category("Decorators")]
|
||||
[Description("Inverts Success to Failure and Failure to Success.")]
|
||||
[ParadoxNotion.Design.Icon("Remap")]
|
||||
public class Inverter : BTDecorator
|
||||
{
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
if ( decoratedConnection == null )
|
||||
return Status.Optional;
|
||||
|
||||
status = decoratedConnection.Execute(agent, blackboard);
|
||||
|
||||
switch ( status ) {
|
||||
case Status.Success:
|
||||
return Status.Failure;
|
||||
case Status.Failure:
|
||||
return Status.Success;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc5ca97b632c2a34a954b8e8937b1726
|
||||
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/BehaviourTrees/Nodes/Decorators/Inverter.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,126 @@
|
||||
using System.Collections;
|
||||
using NodeCanvas.Framework;
|
||||
using NodeCanvas.Framework.Internal;
|
||||
using ParadoxNotion.Design;
|
||||
using ParadoxNotion;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Name("Iterate")]
|
||||
[Category("Decorators")]
|
||||
[Description("Iterates a list and executes its child once for each element in that list. Keeps iterating until the Termination Policy is met or until the whole list is iterated, in which case the last iteration child status is returned.")]
|
||||
[ParadoxNotion.Design.Icon("List")]
|
||||
public class Iterator : BTDecorator
|
||||
{
|
||||
|
||||
public enum TerminationConditions
|
||||
{
|
||||
None,
|
||||
FirstSuccess,
|
||||
FirstFailure
|
||||
}
|
||||
|
||||
[RequiredField]
|
||||
[BlackboardOnly]
|
||||
[Tooltip("The list to iterate.")]
|
||||
public BBParameter<IList> targetList;
|
||||
|
||||
[BlackboardOnly]
|
||||
[Name("Current Element")]
|
||||
[Tooltip("Store the currently iterated list element in a variable.")]
|
||||
public BBObjectParameter current;
|
||||
|
||||
[BlackboardOnly]
|
||||
[Name("Current Index")]
|
||||
[Tooltip("Store the currently iterated list index in a variable.")]
|
||||
public BBParameter<int> storeIndex;
|
||||
|
||||
[Name("Termination Policy"), Tooltip("The condition for when to terminate the iteration and return status.")]
|
||||
public TerminationConditions terminationCondition = TerminationConditions.None;
|
||||
|
||||
[Tooltip("The maximum allowed iterations. Leave at -1 to iterate the whole list.")]
|
||||
public BBParameter<int> maxIteration = -1;
|
||||
|
||||
[Tooltip("Should the iteration start from the begining after the Iterator node resets?")]
|
||||
public bool resetIndex = true;
|
||||
|
||||
private int currentIndex;
|
||||
|
||||
private IList list => targetList != null ? targetList.value : null;
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
if ( decoratedConnection == null ) {
|
||||
return Status.Optional;
|
||||
}
|
||||
|
||||
if ( list == null || list.Count == 0 ) {
|
||||
return Status.Failure;
|
||||
}
|
||||
|
||||
for ( var i = currentIndex; i < list.Count; i++ ) {
|
||||
|
||||
current.value = list[i];
|
||||
storeIndex.value = i;
|
||||
status = decoratedConnection.Execute(agent, blackboard);
|
||||
|
||||
if ( status == Status.Success && terminationCondition == TerminationConditions.FirstSuccess ) {
|
||||
return Status.Success;
|
||||
}
|
||||
|
||||
if ( status == Status.Failure && terminationCondition == TerminationConditions.FirstFailure ) {
|
||||
return Status.Failure;
|
||||
}
|
||||
|
||||
if ( status == Status.Running ) {
|
||||
currentIndex = i;
|
||||
return Status.Running;
|
||||
}
|
||||
|
||||
|
||||
if ( currentIndex == list.Count - 1 || currentIndex == maxIteration.value - 1 ) {
|
||||
if ( resetIndex ) { currentIndex = 0; }
|
||||
return status;
|
||||
}
|
||||
|
||||
decoratedConnection.Reset();
|
||||
currentIndex++;
|
||||
}
|
||||
|
||||
return Status.Running;
|
||||
}
|
||||
|
||||
|
||||
protected override void OnReset() {
|
||||
if ( resetIndex ) { currentIndex = 0; }
|
||||
}
|
||||
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
protected override void OnNodeGUI() {
|
||||
|
||||
GUILayout.Label("For Each\t" + current + "\nIn\t" + targetList, Styles.leftLabel);
|
||||
if ( terminationCondition != TerminationConditions.None ) {
|
||||
GUILayout.Label("Break on " + terminationCondition.ToString());
|
||||
}
|
||||
|
||||
if ( Application.isPlaying ) {
|
||||
GUILayout.Label("Index: " + currentIndex.ToString() + " / " + ( list != null && list.Count != 0 ? ( list.Count - 1 ).ToString() : "?" ));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnNodeInspectorGUI() {
|
||||
DrawDefaultInspector();
|
||||
var argType = targetList.refType != null ? targetList.refType.GetEnumerableElementType() : null;
|
||||
if ( current.varType != argType ) { current.SetType(argType); }
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3255184fe8922814dbb5260dc3bd07dc
|
||||
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/BehaviourTrees/Nodes/Decorators/Iterator.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,21 @@
|
||||
using UnityEngine;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Name("Merge", -1)]
|
||||
[Description("Merge can accept multiple input connections and thus possible to re-use leaf nodes from multiple parents. Please note that this is experimental and can result in unexpected behaviour.")]
|
||||
[Category("Decorators")]
|
||||
public class Merge : BTDecorator
|
||||
{
|
||||
|
||||
public override int maxInConnections => -1;
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
if ( status != Status.Running ) { decoratedConnection.Reset(); }
|
||||
return decoratedConnection.Execute(agent, blackboard);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 586c7107d4ae1b346bf183aa14da0a85
|
||||
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/BehaviourTrees/Nodes/Decorators/Merge.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,94 @@
|
||||
using UnityEngine;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Category("Decorators")]
|
||||
[ParadoxNotion.Design.Icon("Eye")]
|
||||
[Description("Monitors the decorated child for a returned Status and executes an Action when that is the case.\nThe final Status returned to the parent can either be the original decorated child Status, or the new decorator Action Status.")]
|
||||
public class Monitor : BTDecorator, ITaskAssignable<ActionTask>
|
||||
{
|
||||
|
||||
public enum MonitorMode
|
||||
{
|
||||
Failure = 0,
|
||||
Success = 1,
|
||||
AnyStatus = 10,
|
||||
}
|
||||
|
||||
public enum ReturnStatusMode
|
||||
{
|
||||
OriginalDecoratedChildStatus,
|
||||
NewDecoratorActionStatus,
|
||||
}
|
||||
|
||||
[Name("Monitor"), Tooltip("The Status to monitor for.")]
|
||||
public MonitorMode monitorMode;
|
||||
[Name("Return"), Tooltip("The Status to return after (and if) the Action is executed.")]
|
||||
public ReturnStatusMode returnMode;
|
||||
|
||||
private Status decoratorActionStatus;
|
||||
|
||||
[SerializeField]
|
||||
private ActionTask _action;
|
||||
|
||||
public ActionTask action {
|
||||
get { return _action; }
|
||||
set { _action = value; }
|
||||
}
|
||||
|
||||
public Task task {
|
||||
get { return action; }
|
||||
set { action = (ActionTask)value; }
|
||||
}
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
if ( decoratedConnection == null ) {
|
||||
return Status.Optional;
|
||||
}
|
||||
|
||||
var newChildStatus = decoratedConnection.Execute(agent, blackboard);
|
||||
if ( action == null ) {
|
||||
return newChildStatus;
|
||||
}
|
||||
|
||||
if ( status != newChildStatus ) {
|
||||
var execute = false;
|
||||
execute |= newChildStatus == Status.Success && monitorMode == MonitorMode.Success;
|
||||
execute |= newChildStatus == Status.Failure && monitorMode == MonitorMode.Failure;
|
||||
execute |= monitorMode == MonitorMode.AnyStatus && newChildStatus != Status.Running;
|
||||
|
||||
if ( execute ) {
|
||||
decoratorActionStatus = action.Execute(agent, blackboard);
|
||||
if ( decoratorActionStatus == Status.Running ) {
|
||||
return Status.Running;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnMode == ReturnStatusMode.NewDecoratorActionStatus && decoratorActionStatus != Status.Resting ? decoratorActionStatus : newChildStatus;
|
||||
}
|
||||
|
||||
protected override void OnReset() {
|
||||
if ( action != null ) {
|
||||
action.EndAction(null);
|
||||
decoratorActionStatus = Status.Resting;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
protected override void OnNodeGUI() {
|
||||
GUILayout.Label(string.Format("<b>[On {0}]</b>", monitorMode.ToString()));
|
||||
}
|
||||
|
||||
#endif
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bcfd9a49dcd36a945980913e16ded47c
|
||||
timeCreated: 1495927811
|
||||
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/BehaviourTrees/Nodes/Decorators/Monitor.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,30 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Name("Optional")]
|
||||
[Category("Decorators")]
|
||||
[Description("Executes the decorated child as normal and returns an Optional status, thus making it optional to the parent node in regards to what status is returned.\nThis has the same effect as disabling the node, but instead it executes normaly.")]
|
||||
[ParadoxNotion.Design.Icon("UpwardsArrow")]
|
||||
public class Optional : BTDecorator
|
||||
{
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
if ( decoratedConnection == null ) {
|
||||
return Status.Optional;
|
||||
}
|
||||
|
||||
if ( status == Status.Resting ) {
|
||||
decoratedConnection.Reset();
|
||||
}
|
||||
|
||||
status = decoratedConnection.Execute(agent, blackboard);
|
||||
return status == Status.Running ? Status.Running : Status.Optional;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 118d0d2c1e83b3140be8151b09bb0bbc
|
||||
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/BehaviourTrees/Nodes/Decorators/Optional.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,58 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Name("Remap")]
|
||||
[Category("Decorators")]
|
||||
[Description("Remaps the child status to another status. Used to either invert the child's return status or to always return a specific status.")]
|
||||
[ParadoxNotion.Design.Icon("Remap")]
|
||||
public class Remapper : BTDecorator
|
||||
{
|
||||
|
||||
public enum RemapStatus
|
||||
{
|
||||
Failure = 0,
|
||||
Success = 1,
|
||||
}
|
||||
|
||||
public RemapStatus successRemap = RemapStatus.Success;
|
||||
public RemapStatus failureRemap = RemapStatus.Failure;
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
if ( decoratedConnection == null ) {
|
||||
return Status.Optional;
|
||||
}
|
||||
|
||||
status = decoratedConnection.Execute(agent, blackboard);
|
||||
|
||||
switch ( status ) {
|
||||
case Status.Success:
|
||||
return (Status)successRemap;
|
||||
case Status.Failure:
|
||||
return (Status)failureRemap;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
protected override void OnNodeGUI() {
|
||||
|
||||
if ( (int)successRemap != (int)Status.Success )
|
||||
GUILayout.Label("Success → " + successRemap);
|
||||
|
||||
if ( (int)failureRemap != (int)Status.Failure )
|
||||
GUILayout.Label("Failure → " + failureRemap);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b95e7194b7b2eb24fab03071e0cebf33
|
||||
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/BehaviourTrees/Nodes/Decorators/Remapper.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,105 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Name("Repeat")]
|
||||
[Category("Decorators")]
|
||||
[Description("Repeats the child either x times or until it returns the specified status, or forever.")]
|
||||
[ParadoxNotion.Design.Icon("Repeat")]
|
||||
public class Repeater : BTDecorator
|
||||
{
|
||||
|
||||
public enum RepeaterMode
|
||||
{
|
||||
RepeatTimes = 0,
|
||||
RepeatUntil = 1,
|
||||
RepeatForever = 2
|
||||
}
|
||||
|
||||
public enum RepeatUntilStatus
|
||||
{
|
||||
Failure = 0,
|
||||
Success = 1
|
||||
}
|
||||
|
||||
public RepeaterMode repeaterMode = RepeaterMode.RepeatTimes;
|
||||
[ShowIf("repeaterMode", 0)]
|
||||
public BBParameter<int> repeatTimes = 1;
|
||||
[ShowIf("repeaterMode", 1)]
|
||||
public RepeatUntilStatus repeatUntilStatus = RepeatUntilStatus.Success;
|
||||
|
||||
private int currentIteration = 1;
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
if ( decoratedConnection == null ) {
|
||||
return Status.Optional;
|
||||
}
|
||||
|
||||
if ( decoratedConnection.status != Status.Running ) {
|
||||
decoratedConnection.Reset();
|
||||
}
|
||||
|
||||
status = decoratedConnection.Execute(agent, blackboard);
|
||||
|
||||
switch ( status ) {
|
||||
case Status.Resting:
|
||||
return Status.Running;
|
||||
case Status.Running:
|
||||
return Status.Running;
|
||||
}
|
||||
|
||||
switch ( repeaterMode ) {
|
||||
case RepeaterMode.RepeatTimes:
|
||||
|
||||
if ( currentIteration >= repeatTimes.value ) {
|
||||
return status;
|
||||
}
|
||||
|
||||
currentIteration++;
|
||||
break;
|
||||
|
||||
case RepeaterMode.RepeatUntil:
|
||||
|
||||
if ( (int)status == (int)repeatUntilStatus ) {
|
||||
return status;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return Status.Running;
|
||||
}
|
||||
|
||||
protected override void OnReset() {
|
||||
currentIteration = 1;
|
||||
}
|
||||
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
protected override void OnNodeGUI() {
|
||||
|
||||
if ( repeaterMode == RepeaterMode.RepeatTimes ) {
|
||||
GUILayout.Label(repeatTimes + " Times");
|
||||
if ( Application.isPlaying )
|
||||
GUILayout.Label("Iteration: " + currentIteration.ToString());
|
||||
|
||||
} else if ( repeaterMode == RepeaterMode.RepeatUntil ) {
|
||||
|
||||
GUILayout.Label("Until " + repeatUntilStatus);
|
||||
|
||||
} else {
|
||||
|
||||
GUILayout.Label("Repeat Forever");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d74567d471af51f46a176cd123b68d72
|
||||
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/BehaviourTrees/Nodes/Decorators/Repeater.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,41 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Name("Override Agent")]
|
||||
[Category("Decorators")]
|
||||
[Description("Set another Agent for the rest of the Tree dynamicaly from this point and on. All nodes under this will be executed with the new agent. You can also use this decorator to revert back to the original graph agent.")]
|
||||
[ParadoxNotion.Design.Icon("Agent")]
|
||||
public class Setter : BTDecorator
|
||||
{
|
||||
|
||||
[Tooltip("If enabled, will revert back to the original graph agent.")]
|
||||
public bool revertToOriginal;
|
||||
[ShowIf("revertToOriginal", 0), Tooltip("The new agent to use.")]
|
||||
public BBParameter<GameObject> newAgent;
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
if ( decoratedConnection == null ) {
|
||||
return Status.Optional;
|
||||
}
|
||||
|
||||
agent = revertToOriginal ? graphAgent : newAgent.value.transform;
|
||||
return decoratedConnection.Execute(agent, blackboard);
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
protected override void OnNodeGUI() {
|
||||
GUILayout.Label(string.Format("Agent = {0}", revertToOriginal ? "Original" : newAgent.ToString()));
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f79712c85c72df64cb10e3dc32389aaa
|
||||
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/BehaviourTrees/Nodes/Decorators/Setter.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,50 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Category("Decorators")]
|
||||
[Description("Interupts decorated child node and returns Failure if the child node is still Running after the timeout period.")]
|
||||
[ParadoxNotion.Design.Icon("Timeout")]
|
||||
public class Timeout : BTDecorator
|
||||
{
|
||||
|
||||
[Tooltip("The timeout period in seconds.")]
|
||||
public BBParameter<float> timeout = 1;
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
if ( decoratedConnection == null ) {
|
||||
return Status.Optional;
|
||||
}
|
||||
|
||||
status = decoratedConnection.Execute(agent, blackboard);
|
||||
if ( status == Status.Running ) {
|
||||
if ( elapsedTime >= timeout.value ) {
|
||||
decoratedConnection.Reset();
|
||||
return Status.Failure;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
protected override void OnNodeGUI() {
|
||||
GUILayout.Space(25);
|
||||
var pRect = new Rect(5, GUILayoutUtility.GetLastRect().y, rect.width - 10, 20);
|
||||
var t = 1 - ( elapsedTime / timeout.value );
|
||||
UnityEditor.EditorGUI.ProgressBar(pRect, t, elapsedTime > 0 ? string.Format("({0})", elapsedTime.ToString("0.0")) : "Ready");
|
||||
}
|
||||
|
||||
#endif
|
||||
///----------------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 117e6954834de844b80b3610a29e4867
|
||||
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/BehaviourTrees/Nodes/Decorators/Timeout.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,65 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Category("Decorators")]
|
||||
[Description("Returns Running until the assigned condition becomes true, after which the decorated child is executed.")]
|
||||
[ParadoxNotion.Design.Icon("Halt")]
|
||||
public class WaitUntil : BTDecorator, ITaskAssignable<ConditionTask>
|
||||
{
|
||||
|
||||
[SerializeField]
|
||||
private ConditionTask _condition;
|
||||
private bool accessed;
|
||||
|
||||
public Task task {
|
||||
get { return condition; }
|
||||
set { condition = (ConditionTask)value; }
|
||||
}
|
||||
|
||||
private ConditionTask condition {
|
||||
get { return _condition; }
|
||||
set { _condition = value; }
|
||||
}
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
if ( decoratedConnection == null ) {
|
||||
//this part is so that Wait node can be used as a leaf too, by user request
|
||||
if ( condition != null ) {
|
||||
if ( status == Status.Resting ) {
|
||||
condition.Enable(agent, blackboard);
|
||||
}
|
||||
return condition.Check(agent, blackboard) ? Status.Success : Status.Running;
|
||||
}
|
||||
//-----
|
||||
return Status.Optional;
|
||||
}
|
||||
|
||||
if ( condition == null ) {
|
||||
return decoratedConnection.Execute(agent, blackboard);
|
||||
}
|
||||
|
||||
if ( status == Status.Resting ) {
|
||||
condition.Enable(agent, blackboard);
|
||||
}
|
||||
|
||||
if ( accessed ) return decoratedConnection.Execute(agent, blackboard);
|
||||
|
||||
if ( condition.Check(agent, blackboard) ) {
|
||||
accessed = true;
|
||||
}
|
||||
|
||||
return accessed ? decoratedConnection.Execute(agent, blackboard) : Status.Running;
|
||||
}
|
||||
|
||||
protected override void OnReset() {
|
||||
if ( condition != null ) { condition.Disable(); }
|
||||
accessed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1523063433aecea4cb4f75728ac09886
|
||||
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/BehaviourTrees/Nodes/Decorators/WaitUntil.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07733885d919a884faf9690060c0d1d7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
@@ -0,0 +1,58 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Name("Action")]
|
||||
[Description("Executes an action and returns Success or Failure when the action is finished.\nReturns Running until the action is finished.")]
|
||||
[ParadoxNotion.Design.Icon("Action")]
|
||||
// [Color("ff6d53")]
|
||||
public class ActionNode : BTNode, ITaskAssignable<ActionTask>
|
||||
{
|
||||
|
||||
[SerializeField]
|
||||
private ActionTask _action;
|
||||
|
||||
public Task task {
|
||||
get { return action; }
|
||||
set { action = (ActionTask)value; }
|
||||
}
|
||||
|
||||
public ActionTask action {
|
||||
get { return _action; }
|
||||
set { _action = value; }
|
||||
}
|
||||
|
||||
public override string name {
|
||||
get { return base.name.ToUpper(); }
|
||||
}
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
if ( action == null ) {
|
||||
return Status.Optional;
|
||||
}
|
||||
|
||||
if ( status == Status.Resting || status == Status.Running ) {
|
||||
return action.Execute(agent, blackboard);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
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: 4363f6a82c42c2f4db123b8c19215466
|
||||
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/BehaviourTrees/Nodes/Leafs/ActionNode.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,49 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Name("Condition")]
|
||||
[Description("Checks a condition and returns Success or Failure.")]
|
||||
[ParadoxNotion.Design.Icon("Condition")]
|
||||
// [Color("ff6d53")]
|
||||
public class ConditionNode : BTNode, ITaskAssignable<ConditionTask>
|
||||
{
|
||||
|
||||
[SerializeField]
|
||||
private ConditionTask _condition;
|
||||
|
||||
public Task task {
|
||||
get { return condition; }
|
||||
set { condition = (ConditionTask)value; }
|
||||
}
|
||||
|
||||
public ConditionTask condition {
|
||||
get { return _condition; }
|
||||
set { _condition = value; }
|
||||
}
|
||||
|
||||
public override string name {
|
||||
get { return base.name.ToUpper(); }
|
||||
}
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
if ( condition == null ) {
|
||||
return Status.Optional;
|
||||
}
|
||||
|
||||
if ( status == Status.Resting ) {
|
||||
condition.Enable(agent, blackboard);
|
||||
}
|
||||
|
||||
return condition.Check(agent, blackboard) ? Status.Success : Status.Failure;
|
||||
}
|
||||
|
||||
protected override void OnReset() {
|
||||
if ( condition != null ) { condition.Disable(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ebacb7ee0473cac4a9a9de550ee34c08
|
||||
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/BehaviourTrees/Nodes/Leafs/ConditionNode.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,55 @@
|
||||
using NodeCanvas.DialogueTrees;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Name("Sub Dialogue")]
|
||||
[Description("Executes a sub Dialogue Tree. Returns Running while the sub Dialogue Tree is active. You can Finish the Dialogue Tree with the 'Finish' node and return Success or Failure.")]
|
||||
[ParadoxNotion.Design.Icon("Dialogue")]
|
||||
[DropReferenceType(typeof(DialogueTree))]
|
||||
public class NestedDT : BTNodeNested<DialogueTree>
|
||||
{
|
||||
|
||||
[SerializeField, ExposeField, Name("Sub Tree")]
|
||||
private BBParameter<DialogueTree> _nestedDialogueTree = null;
|
||||
|
||||
public override DialogueTree subGraph { get { return _nestedDialogueTree.value; } set { _nestedDialogueTree.value = value; } }
|
||||
public override BBParameter subGraphParameter => _nestedDialogueTree;
|
||||
|
||||
//
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
if ( subGraph == null || subGraph.primeNode == null ) {
|
||||
return Status.Optional;
|
||||
}
|
||||
|
||||
if ( status == Status.Resting ) {
|
||||
status = Status.Running;
|
||||
this.TryStartSubGraph(agent, OnDLGFinished);
|
||||
}
|
||||
|
||||
if ( status == Status.Running ) {
|
||||
currentInstance.UpdateGraph(this.graph.deltaTime);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void OnDLGFinished(bool success) {
|
||||
if ( status == Status.Running ) {
|
||||
status = success ? Status.Success : Status.Failure;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnReset() {
|
||||
if ( currentInstance != null ) {
|
||||
currentInstance.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d1bc8dfa829907d4587851859ad68a5b
|
||||
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/BehaviourTrees/Nodes/Leafs/NestedDT.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,83 @@
|
||||
using System.Linq;
|
||||
using NodeCanvas.Framework;
|
||||
using NodeCanvas.StateMachines;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Name("Sub FSM")]
|
||||
[Description("Executes a sub FSM. Returns Running while the sub FSM is active. If a Success or Failure State is selected, then it will return Success or Failure as soon as the Nested FSM enters that state at which point the sub FSM will also be stoped. If the sub FSM ends otherwise, this node will return Success.")]
|
||||
[ParadoxNotion.Design.Icon("FSM")]
|
||||
[DropReferenceType(typeof(FSM))]
|
||||
public class NestedFSM : BTNodeNested<FSM>
|
||||
{
|
||||
|
||||
[SerializeField, ExposeField, Name("Sub FSM")]
|
||||
private BBParameter<FSM> _nestedFSM = null;
|
||||
|
||||
[HideInInspector] public string successState;
|
||||
[HideInInspector] public string failureState;
|
||||
|
||||
public override FSM subGraph { get { return _nestedFSM.value; } set { _nestedFSM.value = value; } }
|
||||
public override BBParameter subGraphParameter => _nestedFSM;
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
if ( subGraph == null || subGraph.primeNode == null ) {
|
||||
return Status.Optional;
|
||||
}
|
||||
|
||||
if ( status == Status.Resting ) {
|
||||
status = Status.Running;
|
||||
this.TryStartSubGraph(agent, OnFSMFinish);
|
||||
}
|
||||
|
||||
if ( status == Status.Running ) {
|
||||
currentInstance.UpdateGraph(this.graph.deltaTime);
|
||||
}
|
||||
|
||||
if ( !string.IsNullOrEmpty(successState) && currentInstance.currentStateName == successState ) {
|
||||
currentInstance.Stop(true);
|
||||
return Status.Success;
|
||||
}
|
||||
|
||||
if ( !string.IsNullOrEmpty(failureState) && currentInstance.currentStateName == failureState ) {
|
||||
currentInstance.Stop(false);
|
||||
return Status.Failure;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void OnFSMFinish(bool success) {
|
||||
if ( status == Status.Running ) {
|
||||
status = success ? Status.Success : Status.Failure;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnReset() {
|
||||
if ( currentInstance != null ) {
|
||||
currentInstance.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
protected override void OnNodeInspectorGUI() {
|
||||
base.OnNodeInspectorGUI();
|
||||
if ( subGraph != null ) {
|
||||
successState = EditorUtils.Popup<string>("Success State", successState, subGraph.GetStateNames());
|
||||
failureState = EditorUtils.Popup<string>("Failure State", failureState, subGraph.GetStateNames());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
///----------------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 029908fbea5cdb44eb8daab6ea1ce96d
|
||||
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/BehaviourTrees/Nodes/Leafs/NestedFSM.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,49 @@
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
[Name("Sub Tree")]
|
||||
[Description("Executes a sub Behaviour Tree. The status of the root node in the SubTree will be returned.")]
|
||||
[ParadoxNotion.Design.Icon("BT")]
|
||||
[DropReferenceType(typeof(BehaviourTree))]
|
||||
public class SubTree : BTNodeNested<BehaviourTree>
|
||||
{
|
||||
|
||||
[SerializeField, ExposeField]
|
||||
private BBParameter<BehaviourTree> _subTree = null;
|
||||
|
||||
public override BehaviourTree subGraph { get { return _subTree.value; } set { _subTree.value = value; } }
|
||||
public override BBParameter subGraphParameter => _subTree;
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
if ( subGraph == null || subGraph.primeNode == null ) {
|
||||
return Status.Optional;
|
||||
}
|
||||
|
||||
if ( status == Status.Resting ) {
|
||||
this.TryStartSubGraph(agent);
|
||||
}
|
||||
|
||||
currentInstance.UpdateGraph(this.graph.deltaTime);
|
||||
|
||||
if ( currentInstance.repeat && currentInstance.rootStatus != Status.Running ) {
|
||||
this.TryReadAndUnbindMappedVariables();
|
||||
}
|
||||
|
||||
return currentInstance.rootStatus;
|
||||
}
|
||||
|
||||
protected override void OnReset() {
|
||||
if ( currentInstance != null ) {
|
||||
currentInstance.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 81a47db377388e443b24ae90ce6a83c8
|
||||
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/BehaviourTrees/Nodes/Leafs/SubTree.cs
|
||||
uploadId: 704937
|
||||
@@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 401468022ced6be409de4e26417b1357
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
@@ -0,0 +1,11 @@
|
||||
using NodeCanvas.Framework;
|
||||
|
||||
|
||||
namespace NodeCanvas.DialogueTrees
|
||||
{
|
||||
|
||||
public class DTConnection : Connection
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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; } }
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39761394fbf3ea346a5e66e5798c11ae
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
@@ -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: '[...]'
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 308fd16ad36adda41800985165b4ebf1
|
||||
folderAsset: yes
|
||||
timeCreated: 1485179025
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user