NodeCanvas Forums › Custom Nodes & Tasks › How to access PlayerController component
Tagged: Player Controller
Im switching over my actions from an old FSM I made to NodeCanvas. So this might not be the best practice for this asset but would still like to know how to do this and if theres a better way let me know.
So i have an FSM with a couple action states, only using “Default” state for the time being to test:
The Default state will have more than one action and I would like to access the PlayerController class on the player like so (Move action class):
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 |
using UnityEngine; using NodeCanvas.Framework; public class Move : ActionTask { public PlayerController player; protected override void OnUpdate() { // For running bool running = player.input.Sprint; // Move player float targetVelocityX = (running ? player.runSpeed : player.walkSpeed) * player.input.Move.X; player.velocity.x = Mathf.SmoothDamp(player.velocity.x, targetVelocityX, ref player.velocityXSmoothing, (player.characterController.isGrounded ? player.accelerationGrounded : player.accelerationAirborne)); player.velocity.y += player.gravity * Time.deltaTime; player.characterController.Move(player.velocity * Time.deltaTime); // Reset X velocity so it doesnt decrement to a really low number if (Mathf.Abs(player.velocity.x) <= 0.01f) player.velocity.x = 0; EndAction(true); } } |
Would this be the best way about doing so, dragging over the player class into the serialized Player field every time I need an action to access the PlayerController class? Preferably would like to cache the player class once and be able to access if I had to along all the states.
Hey,
There are definetely easier ways to go about this 🙂
Probably the best way (and an important feature of NodeCanvas Custom Tasks), would be to derive your Move ActionTask from the generic version of ActionTask<T>
, instead of just ActionTask
, with T being the Component which the task requires to work with, thus in this case:
public class Move : ActionTask<PlayerController>
.
Doing so, and on initialization of the task, the PlayerController component will be fetched (with GetComponent) from the “agent” (The FSMOwner gameobject) and automatically be cached.
To access the PlayerController within the task’s code, you will then need to use the .agent
property, which will already be of type PlayerController since you derived the generic ActionTask version. Thus your custom task code will end up like this in the end:
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 |
using UnityEngine; using NodeCanvas.Framework; public class Move : ActionTask<PlayerController> { protected override void OnUpdate() { // For running bool running = agent.input.Sprint; // Move agent float targetVelocityX = (running ? agent.runSpeed : agent.walkSpeed) * agent.input.Move.X; agent.velocity.x = Mathf.SmoothDamp(agent.velocity.x, targetVelocityX, ref agent.velocityXSmoothing, (agent.characterController.isGrounded ? agent.accelerationGrounded : agent.accelerationAirborne)); agent.velocity.y += agent.gravity * Time.deltaTime; agent.characterController.Move(agent.velocity * Time.deltaTime); // Reset X velocity so it doesnt decrement to a really low number if (Mathf.Abs(agent.velocity.x) <= 0.01f) agent.velocity.x = 0; EndAction(true); } } |
Another benefit of deriving from the generic version of ActionTask as you will see, is that within the inspector of your Move ActionTask, you will (optionally) be able to override (with the checkbox) the “target” agent, or in other words, the PlayerController in this case which you want the task to use. Most of the times though, leaving the option to the default “Use Self” is what you will need.
Thus, deriving from the generic version of ActionTasks where T would be the the Component type you want the action to use, allows you to “not care” about caching or assigning and just use the component directly without worries, through the .agent
property.
Please let me know if the above helps and if that is indeed what your question was about.
Thanks!
Join us on Discord: https://discord.gg/97q2Rjh
Please let me know if the above helps and if that is indeed what your question was about.
Thanks!
Thanks for the fast response and help! That’s exactly what I needed.