Last active
March 18, 2017 06:20
-
-
Save sam-kelly-dev/6adee7804bd032d48a26 to your computer and use it in GitHub Desktop.
# Unity3D 5.0 - Mecanim Third Person Character Controller Scripts # A BaseController to act as a hub for character actions, and a PlayerController to accept input and make it available to the state machine.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using UnityEngine; | |
| using System.Collections; | |
| //You must add the following Components to the object or else this script will fail. | |
| [RequireComponent(typeof(Rigidbody))] | |
| [RequireComponent(typeof(CapsuleCollider))] | |
| [RequireComponent(typeof(Animator))] | |
| //Provides a set of default values to instance and build on top of. | |
| public class Movement{ | |
| public float walkSpeed = 2; | |
| public float runSpeed = 5; | |
| public float turnSpeed = 1; | |
| public float strafeSpeed = 3.5f; | |
| } | |
| public class BaseController : MonoBehaviour { | |
| protected Vector3 _moveDir = Vector3.zero; | |
| public Vector3 moveDir{ | |
| get{ | |
| return _moveDir; | |
| } | |
| } | |
| protected Movement movement; | |
| public float speed{ | |
| get{ | |
| return this.movement.walkSpeed; | |
| } | |
| } | |
| public float rotationSpeed{ | |
| get{ | |
| return this.movement.turnSpeed; | |
| } | |
| } | |
| //It was giving me warnings without the "new"... Unity5 maybe? Never seen that before. | |
| protected new Camera camera; | |
| protected new Rigidbody rigidbody; | |
| // Use this for initialization | |
| protected virtual void Start () { | |
| movement = new Movement(); //Create a new Movement object. | |
| Initialize (); | |
| } | |
| protected virtual void Update(){} //We're not doing anything here in the Base class. | |
| protected virtual void Initialize (){ | |
| this.camera = Camera.main; //We might need this later. | |
| } | |
| protected virtual float GetSpeed(){ | |
| return this.movement.walkSpeed; //We'll expand on this later to allow for movement modifiers. | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using UnityEngine; | |
| using System.Collections; | |
| public class LocomotionBehavior : StateMachineBehaviour { | |
| protected GameObject gameObject; | |
| protected Transform transform; | |
| protected Rigidbody rigidbody; | |
| protected Animator _animator; | |
| protected BaseController _controller; | |
| protected Vector3 _moveDir; | |
| public void Start(){} | |
| // OnStateEnter is called when a transition starts and the state machine starts to evaluate this state. | |
| override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { | |
| _animator = animator; | |
| gameObject = _animator.gameObject; | |
| transform = gameObject.transform; | |
| rigidbody = gameObject.GetComponent<Rigidbody> (); | |
| _controller = gameObject.GetComponent<BaseController> (); | |
| } | |
| // OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks. | |
| override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { | |
| HandleMovement (); | |
| HandleAnimation (); | |
| } | |
| // OnStateExit is called when a transition ends and the state machine finishes evaluating this state. | |
| override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { | |
| } | |
| // OnStateMove is called right after Animator.OnAnimatorMove(). Code that processes and affects root motion should be implemented here. | |
| override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { | |
| } | |
| // OnStateIK is called right after Animator.OnAnimatorIK(). Code that sets up animation IK (inverse kinematics) should be implemented here. | |
| override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { | |
| } | |
| private void HandleMovement () { | |
| _moveDir = _controller.moveDir; // Get our current movement direction from _controller. | |
| _moveDir.y = 0; // Set Y to zero because we're not moving up or down, the rigidbody physics takes care of that for us. | |
| transform.LookAt (transform.position + _moveDir); // Look in the direction we're trying to go. | |
| } | |
| private void HandleAnimation () { | |
| _animator.SetFloat ("h", 0); // We can set this to our Input X-Axis if we have good run left/right animations, otherwise leave it at 0. | |
| _animator.SetFloat ("v", _moveDir.sqrMagnitude); // Set our vertical speed so that the character knows to run forward. | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using UnityEngine; | |
| using System.Collections; | |
| public class PlayerController : BaseController { | |
| // Use this for initialization | |
| protected Animator animator; | |
| protected override void Start () { | |
| base.Start (); // Call BaseController.Start, which will call Initialize. | |
| animator = GetComponent<Animator> (); | |
| } | |
| // Update is called once per frame | |
| protected new virtual void Update () { //We do a new virtual here so that we can call the base, but anything else that calls "base.Update" will refer to this. | |
| GetInput (); // Get the player's input BEFORE we Update. | |
| base.Update (); // Call BaseController.Update(), even though it's empty. | |
| } | |
| protected override void Initialize(){ | |
| base.Initialize (); // Call the Base of Initialize. | |
| } | |
| void GetInput(){ | |
| float h = Input.GetAxis ("Horizontal"); | |
| float v = Input.GetAxis ("Vertical"); | |
| Vector3 moveInput = new Vector3 (h, 0, v); | |
| _moveDir = this.camera.transform.TransformDirection (moveInput); // Modify _moveDirection to be relative to the camera. | |
| Debug.DrawRay (transform.position, _moveDir * 5, Color.red); //Display which way we're trying to go for Debug purposes in the Scene view. | |
| } | |
| } |
I experience the same issue, the player does not move, it just animates on the spot but does turn. What code is missing please?
Same here, no motions are animated. The character will rotate or glide forward. The image of the Blend Tree inputs is to small.
Can't tell what the settings actually are. I do get a warning that two or more of the positions are too close to each other with the
settings I guessed at... Idle: 0,0, 0.1 Left: -1,0,1 Right: 1, 0, 1 and Run: 0, 0, 1 What are the correct Blend Tree settings? Is this
what's keeping the character from animating? Also I put the Base Controller on the character because you didn't exactly mention
where to put it.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Why did you remove the rigidbody.MovePosition() part? Without it, the model won't move.