NodeCanvas Forums › Support › Scenario with Nodecanvas
Hi,
I’m trying to figure out the best way to use Nodecanvas for my project.
It is a virtual trainer where you have to do a number of tasks in a certain order to learn the procedure. So it is:
Scenario Step 1:
– Click an object (or an UI-button)
– Get a message if it is the wrong object for this step
– Start one or more animations if it is the right object
– Go to the next step
Scenario Step 2:
etc…
Should I use Behavior trees for this ? Or FSM’s ?
Which nodes should I use ?
Regards,
Wilbert Blom
Hello,
My suggestion would be to use FSMs in this case. The reason why is, because you have a series of definete steps, which can easily be translated to states.
The way I would probably set this up, would be to have one state for each step, as well as the wrong inbetween steps.
Then each step/state, OnEnter, would play some animations like you need and once that is complete, show the UI buttons relevant to this step towards the next that were previously hidden (I’m just making a suggestion here).
Each button could then correspond to a state transition going to the next step/state, or a wrong inbetween one. Checking the buttons can easily be done the the “UGUI/Button Clicked” Condition attached on the transitions.
If you need a screenshot of what I mean, by all means let me know 🙂
But, I definetely suggest FSM in this case over BTs.
Thanks!
Join us on Discord: https://discord.gg/97q2Rjh
Thank you for your reply. I’ll start experimenting with a FSM.
How would I do a check if a clicked gameobject is the current scenario gameobject and then animate another object (set Mecanim state)?
The ‘current’ gameobject is a List with scenariosteps (a custom class) that looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class clScenarioStep { public GameObject goScenarioObject,goActionObject; public string strObjectState; public clScenarioStep(GameObject goNewScenarioObject, GameObject goNewActionObject, string strNewObjectState) { goScenarioObject = goNewScenarioObject;//clicked object goActionObject = goNewActionObject;//object to animate strObjectState = strNewObjectState;//state trigger } } |
(A screenshot would be nice, I’m more a designer than a programmer and thus more a visual person (also the reason why I think NodeCanvas is great 😉
Sorry for the late reply.
Can you please provide more info on the setup?
Is that a list on the blackboard for example, or a list you have on some MonoBehaviour on one of your gameobjects?
Thanks!
Join us on Discord: https://discord.gg/97q2Rjh
It is a (simplified version of a) standalone script that is called to create the List of scenario-steps now. (I believe it is called a constructor in programming terms ?)
I make a List to hold these ScenarioStep objects with the data to which ScenarioObjects
to interacts with (Click on mostly) and the ActionObjects
that have to be animated to perform the actions by setting the Mecanin state with the ObjectState
trigger
So to create the scenario I fill a List with these ScenarioStep Objects on StartUp
1 2 3 |
List<clScenarioStep> liNewScenario = new List<clScenarioStep>(); liNewScenario.Add(new clScenarioStep(gobtPrestart, goControlPanel1, "trCP1ScreenPrestart")); |
This would create a scenariostep that will trigger the “trCP1ScreenPrestart” state on the goControlPanel1 gameobject when the gobtPrestart gameobject is clicked.
A ScenarioManager script is then running in the scene that steps through the list and checks if an object that is clicked is the “current ScenarioObject” if it is the correct object it fires the Trigger and goes to the next step in the List. If it isn’t it shows an error message.
https://www.youtube.com/watch?v=XgPSaYkTZY4
My main idea is that with Nodecanvas I can turn these ScenarioSteps into nodes and by connecting them in a FSM I have a more visually and easier way to create and run these scenario’s.
I hope this makes it a is bit more clear to you ?
Hello and thanks for info.
If you are willing to do some redesing, you could implement the steps as FSM state actions.
For example, you can have a custom action (ScenatioStep), that has a GameObject variable which is the scenarioObject that needs to be clicked. Then in the action’s update check if that object is clicked and send and event to the FSM “Corrent” otherwise “Wrong” for example. Here is what I did. You can expand on this if you want to add more funcitonality.
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 |
using NodeCanvas.Framework; using ParadoxNotion.Design; using UnityEngine; namespace NodeCanvas{ public class ScenarioStep : ActionTask{ public GameObject scenarioObject; private RaycastHit hit; //just some info for convenience protected override string info{ get {return scenarioObject != null? scenarioObject.name : "null";} } protected override void OnExecute(){ //you can do some stuff here if you like when the state enters } protected override void OnUpdate(){ if (Input.GetMouseButtonDown(0)){ if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, Mathf.Infinity)){ if (hit.collider.gameObject == scenarioObject){ SendEvent("Corrent"); } else { SendEvent("Wrong"); } EndAction(); } } } protected override void OnStop(){ //you can do some stuff here if you like when the state exits } } } |
Then I add this action in each state that represents a scenario step and add a “Check Event” condition on it’s transitions to check whether the event send from the action is “Correct” or “Wrong”.
So, if I click in order Sphere1, Sphere2, Sphere3, then everything will go through the “Correct” path.
Let me know if this works for you, or you had something different in mind.
Thanks.
Join us on Discord: https://discord.gg/97q2Rjh
I think this is exactly what I had in mind. I’l start experimenting with it.
THX!