- Home /
Handling input, movement, animation with scripts?
This is quite an open question however I think there is value to the answers to it.
So lets take a simple and common scenario, we have a player character and some NPCs all of them share the same animations, npcs move via pathfinding and the player moves via input.
Now ideally it makes sense to somehow share the animation controller and logic (i.e setting mecanim vars), the movement logic will differ so ideally the animation needs to be driven by the movement logic and the player also needs to be aware of input (be it raw keys or absracted input frameworks).
So the simplest and least flexible way to do it is to give 1 script to npcs and 1 to players which would do something like:
if(Input.GetButtonDown("W"))
{
transform.position += transform.forward * MoveSpeed * Time.deltaTime;
animation.Play( "walk_cycle" );
}
However then there is no shared logic and if you need to change the animation names or keys etc it is a difficult job.
So I was thinking that it would be better to have some sort of eventing system so basically there would be a script to handle animation based upon movement which would be notified, so when an input happens it would notify the objects listening then when the player processes that and lets say moves forward then it raises an event of some sort for a shared animation script to listen to on each enity.
Anyway there are lots of ways to solve this problem but I wanted to see what everyone else would say is best practice on this as I find it very hard to find the unity best practices.
This is a better topic for the forums, since it's not really a "Question" but a "lets discuss ideas".
However, I would suggest making one animator for each main thing. If all NPCs are alike, then one for them is fine, but I would shy away from making some sort of universal animator. I tried that in my game, and it's not as good as it sounds, it actually is causing me problems. It's not hard to copy a current one and make simple modifications to make it unique.
Agreed; this is better placed in the forums. When you create a thread there, post the link here so others can find it.
It's very common to use a high level animation controller that abstracts away all the $$anonymous$$ecanim details. Another layer on top of that usually controls higher-level character states and gets its input from a "virtual controller". The player sets the virtual controller's values from physical input hardware. NPCs set the virtual controller values from an AI layer.
I was originally thinking about putting it in the forums but whenever I search for these sort of topics I always find the best answers in the unity answers sections so put it in here, but like you say there is no SINGLE right answer, so will put this post in the forums and leave a link to this.
Answer by JusticeAShearing · Jul 12, 2014 at 04:01 PM
Here's my java-script for movement. I think that it suits your purposes. It also holds animation code, gravity, rotation and jumping.
var speed : float = 6.0;
var twiceSpeed : float = 10.0;
var jumpSpeed : float = 8.0;
var gravity : float = 20.0;
var rotateSpeed : float = 3.0;
private var moveDirection : Vector3 = Vector3.zero;
function Update() {
var controller : CharacterController = GetComponent(CharacterController);
if (controller.isGrounded) {
//Grounded, so recalculate
//Move directly from axes
moveDirection = Vector3(0, 0, Input.GetAxis("Vertical"));
//Rotation Code
transform.Rotate(0, Input.GetAxis("Horizontal") * rotateSpeed, 0);
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
if (Input.GetButton ("Jump")) {
moveDirection.y = jumpSpeed;
}
//Animation Code
if (Input.GetKeyDown("w"))
{
animation.Play("Full Walk");
}
else if (Input.GetKeyUp("w"))
{
animation.Stop();
animation.Play("Idle");
}
}
//Apply Gravity
moveDirection.y -= gravity * Time.deltaTime;
//Move Controller
controller.Move(moveDirection * Time.deltaTime);
}
Yes this is the normal sort of approach but I do not think it is best practice to put it all in one script as it means your animation and movement etc is driven by specific key presses not events. What if you are in a menu or your character should not be moveable etc, if you split it out into different chunks of logic which drive each other its easier to test and refactor when needed. A valid answer though.
Okay, tell me if you can't split it into different scripts. I think that one could also write a bit of Java-Script to make it so that all of the variables become nothing when the menu is brought up.
Besides, I have the game pausable recently, and there were no problems. Also, errors tend to specify which lines that it occurred on.