NodeCanvas Forums › Support › Various questions
Hi,
Thanks in advance for any help you can provide. I have a series of requirements for my game and want to know your best recommendations.
1. I have a function called MoveTo on my npc. I want to call this once then have the behaviour tree wait until it’s complete. Currently, it keeps calling the behaviour regardless if its complete or not.
2. I would like to reset or control the behaviour tree from my scripts, it doesn’t seem possible?
3. I would like to mix dialogue and classic behaviours in the same tree, is that possible?
Thanks for any help.
OK… hours later worked it out 😛
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
using UnityEngine; using NodeCanvas.Variables; namespace NodeCanvas.Actions{ [Category("Simian Squared")] [AgentType(typeof(Bala))] public class MoveTo:ActionTask { public Transform target; public float speed = 1; [GetFromAgent] private Bala npc; protected override string OnInit() { return null; } protected override void OnExecute() { npc.MoveTo(target, speed); //EndAction(true); } protected override void OnUpdate() { if (!npc.processing) { EndAction(true); } } protected override void OnStop(){ } protected override void OnPause(){ } } } |
— let me know if this is correct please. I’m a bit worried about how many get components that is, but I really needed it to just do it’s thing without moving onto the next until the processing variable was true.
Hello,
To answer your questions:
1. If the MoveTo function in your npc is an IEnumerator, you can use ExecuteFunction to execute it as a coroutine, without the need to write a custom task.
Regarding your custom task code, it is correct although it can be improved. For example, within a Task, you always have access to the agent with the inherited ‘agent’ property. The ‘agent’ property returns a Component type. When using the [AgentType] attribute like you have done here, that Component is certain to be of the type you specified. So you already have a reference of BALA and you don’t really need to also use [GetFromAgent], although it’s certainly possible.
Furthermore you can use BBVariables instead of normal variables, if you want to be allowed to assign the variables from the Blackboard. Here is the improved code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
using UnityEngine; using NodeCanvas.Variables; namespace NodeCanvas.Actions{ [Category("Simian Squared")] [AgentType(typeof(Bala))] public class MoveTo:ActionTask { //use BBTransform to allow dynamic change of the variable through the blackboard public BBTransform target; public float speed = 1; //agent is certaint to be of the type provided by the [AgentType] attribute private Bala npc { get {return (Bala)agent;} } protected override void OnExecute() { npc.MoveTo(target, speed); } protected override void OnUpdate() { if (!npc.processing) { EndAction(true); } } } } |
Also dont worry about get component since that is done only in initialize and is cached.
2. You can Start/Resume, Stop, Pause a behaviour with relative functions that are in the BehaviourTreeOwner class.
Please take a look here: http://nodecanvas.com/documentation/node-systems/behaviour-trees/control/
3. You can either use Nested DialogueTrees, or use this action to make a DialogueActor say something without the need of creating a nested dialogue tree.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
using UnityEngine; using NodeCanvas.DialogueTrees; namespace NodeCanvas.Actions{ [AgentType(typeof(DialogueActor))] [Category("Dialogue")] [Description("Makes a Dialogue Actor talk. You can use variable names in square brackets to make the text more dynamicneg [varName]")] public class SayDialogue : ActionTask { public Statement statement = new Statement("this is a dialogue text"); protected override string info{ get { var displayText = statement.text.Length > 20? statement.text.Substring(0, 20) + "..." : statement.text; return "' <i>" + displayText + "</i> '"; } } protected override void OnExecute(){ (agent as DialogueActor).Say(statement.BlackboardReplace(blackboard), EndAction); } protected override void OnStop(){ (agent as DialogueActor).StopTalking(); } //////////////////////////////////////// ///////////GUI AND EDITOR STUFF///////// //////////////////////////////////////// #if UNITY_EDITOR protected override void OnTaskInspectorGUI(){ statement.text = UnityEditor.EditorGUILayout.TextArea(statement.text, GUILayout.Height(80)); statement.audio = UnityEditor.EditorGUILayout.ObjectField("Audio", statement.audio, typeof(AudioClip), true) as AudioClip; statement.meta = UnityEditor.EditorGUILayout.TextField("Meta", statement.meta); } #endif } } |
Is this what you mean?
Cheers
Join us on Discord: https://discord.gg/97q2Rjh
Hi,
Thanks for the amazing support and attention! I feel confident with this asset. I’m still working my way around understanding behaviour trees in general (I followed the links you’ve supplied elsewhere, but still… learning curve).
What I meant was typically our npcs will be following patrol routes but at certain times of the day, they will pack up and go home until it is dawn again. But you can stop an an npc at any time and have a chat. I’d like to integrate some fairly complicated behaviours in here (think quests) which might include dialogue.
For example:
1. npc patrols or goes home (this is a looped ongoing behaviour)
2. another npc might collide with this npc, which triggers a custom response, an animation perhaps.
3. another npc might “broadcast” an event to all npcs nearby which cause them to flee or congregate.
4. you might initiate a dialogue with an npc, and you’ll chat with multiple choice answers and branches depending on your inventory, for example he might ask for an apple and you’ll be able to give it to him, or hand a quest in. But when you give him the apple, he runs off with it and places it in a basket and then returns to resume the dialogue.
This is pretty complicated behaviour which I could code of course, but I want to use your behaviour trees to absolute maximum effect, so any advice to this end in general is really welcome. I’m trying to gain an insight to how you think, and how you expect users to use nodecanvas in a situation like this.
Thanks 🙂
Hello,
You are welcome and thanks a lot 🙂
I like your example scenario. There are various ways to do it, but instead of providing a text answer, I’d like to create something based on that example and post it here.
I am currently away from office (weekend), but I will post back to you tomorrow as soon as I get back 🙂
Cheers!
Join us on Discord: https://discord.gg/97q2Rjh