Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Translate third person controller into C#

Discussion in 'Scripting' started by raycosantana, Jan 16, 2013.

  1. raycosantana

    raycosantana

    Joined:
    Dec 23, 2012
    Posts:
    319
    Oh yeah baby! third person controller now in full 3D....Ooops I mean... C#


    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. [AddComponentMenu("Rayco's scripts/third person controller")]
    4. public class ThirdPersonShooter : MonoBehaviour {
    5.     public AnimationClip idleAnimation;
    6.     public AnimationClip walkAnimation;
    7.     public AnimationClip runAnimation;
    8.     public AnimationClip jumpPoseAnimation;
    9.    
    10.     public float walkMaxAnimationSpeed = 0.75F;
    11.     public float trotMaxAnimationSpeed = 1F;
    12.     public float runMaxAnimationSpeed = 1F;
    13.     public float jumpAnimationSpeed = 1F;
    14.     public float landAnimationSpeed =1F;
    15.    
    16.     private Animation _animation;
    17.    
    18.     enum CharacterState {
    19.         Idle = 0,
    20.         Walking = 1,
    21.         Trotting = 2,
    22.         Running = 3,
    23.         Jumping = 4,   
    24.     }
    25.     private CharacterState _characterState;
    26.     // The speed when walking
    27.     public float walkSpeed = 2.0F;
    28.     // after trotAfterSeconds of walking we trot with trotSpeed
    29.     public float trotSpeed = 4.0F;
    30.     // when pressing "Fire3" button (cmd) we start running
    31.     public float runSpeed = 6.0F;
    32.  
    33.     public float inAirControlAcceleration = 3.0F;
    34.  
    35.     // How high do we jump when pressing jump and letting go immediately
    36.     public float jumpHeight = 0.5F;
    37.  
    38.     // The gravity for the character
    39.     public float gravity = 20.0F;
    40.     // The gravity in controlled descent mode
    41.     public float speedSmoothing = 10.0F;
    42.     public float rotateSpeed = 500.0F;
    43.     public float trotAfterSeconds = 3.0F;
    44.    
    45.     public bool canJump= true;
    46.    
    47. private float jumpRepeatTime = 0.05F;
    48. private float jumpTimeout = 0.15F;
    49. private float groundedTimeout = 0.25F;
    50.  
    51. // The camera doesnt start following the target immediately but waits for a split second to avoid too much waving around.
    52. private float lockCameraTimer = 0.0F;
    53.  
    54. // The current move direction in x-z
    55. private Vector3 moveDirection = Vector3.zero;
    56. // The current vertical speed
    57. private float verticalSpeed = 0.0F;
    58. // The current x-z move speed
    59. private float moveSpeed = 0.0F;
    60.    
    61.     // The last collision flags returned from controller.Move
    62. private CollisionFlags collisionFlags ;
    63.  
    64. // Are we jumping? (Initiated with jump button and not grounded yet)
    65. private bool jumping = false;
    66. private bool jumpingReachedApex = false;
    67.  
    68. // Are we moving backwards (This locks the camera to not do a 180 degree spin)
    69. private bool movingBack = false;
    70. // Is the user pressing any keys?
    71. private bool isMoving = false;
    72. // When did the user start walking (Used for going into trot after a while)
    73. private float walkTimeStart = 0.0F;
    74. // Last time the jump button was clicked down
    75. private float lastJumpButtonTime = -10.0F;
    76. // Last time we performed a jump
    77. private float lastJumpTime = -1.0F;
    78.  
    79.  
    80. // the height we jumped from (Used to determine for how long to apply extra jump power after jumping.)
    81. private float lastJumpStartHeight = 0.0F;
    82.  
    83.  
    84. private Vector3 inAirVelocity = Vector3.zero;
    85.  
    86. private float lastGroundedTime = 0.0F;
    87.  
    88.  
    89. private bool isControllable = true;
    90.  
    91.     // Use this for initialization
    92.     void  Awake (){
    93.     moveDirection = transform.TransformDirection(Vector3.forward);
    94.    
    95.     _animation = GetComponent<Animation>();
    96.     if(!_animation)
    97.         Debug.Log("The character you would like to control doesn't have animations. Moving her might look weird.");
    98.    
    99.     /*
    100. public AnimationClip idleAnimation;
    101. public AnimationClip walkAnimation;
    102. public AnimationClip runAnimation;
    103. public AnimationClip jumpPoseAnimation;
    104.     */
    105.     if(!idleAnimation) {
    106.         _animation = null;
    107.         Debug.Log("No idle animation found. Turning off animations.");
    108.     }
    109.     if(!walkAnimation) {
    110.         _animation = null;
    111.         Debug.Log("No walk animation found. Turning off animations.");
    112.     }
    113.     if(!runAnimation) {
    114.         _animation = null;
    115.         Debug.Log("No run animation found. Turning off animations.");
    116.     }
    117.     if(!jumpPoseAnimation  canJump) {
    118.         _animation = null;
    119.         Debug.Log("No jump animation found and the character has canJump enabled. Turning off animations.");
    120.     }
    121.            
    122. }
    123.     void  UpdateSmoothedMovementDirection (){
    124.     Transform cameraTransform = Camera.main.transform;
    125.     bool grounded = IsGrounded();
    126.    
    127.     // Forward vector relative to the camera along the x-z plane   
    128.     Vector3 forward= cameraTransform.TransformDirection(Vector3.forward);
    129.     forward.y = 0;
    130.     forward = forward.normalized;
    131.  
    132.     // Right vector relative to the camera
    133.     // Always orthogonal to the forward vector
    134.      Vector3 right= new Vector3(forward.z, 0, -forward.x);
    135.  
    136.     float v= Input.GetAxisRaw("Vertical");
    137.     float h= Input.GetAxisRaw("Horizontal");
    138.  
    139.     // Are we moving backwards or looking backwards
    140.     if (v < -0.2f)
    141.         movingBack = true;
    142.     else
    143.         movingBack = false;
    144.    
    145.     bool wasMoving= isMoving;
    146.     isMoving = Mathf.Abs (h) > 0.1f || Mathf.Abs (v) > 0.1f;
    147.        
    148.     // Target direction relative to the camera
    149.     Vector3 targetDirection= h * right + v * forward;
    150.    
    151.     // Grounded controls
    152.     if (grounded)
    153.     {
    154.         // Lock camera for short period when transitioning moving  standing still
    155.         lockCameraTimer += Time.deltaTime;
    156.         if (isMoving != wasMoving)
    157.             lockCameraTimer = 0.0f;
    158.  
    159.         // We store speed and direction seperately,
    160.         // so that when the character stands still we still have a valid forward direction
    161.         // moveDirection is always normalized, and we only update it if there is user input.
    162.         if (targetDirection != Vector3.zero)
    163.         {
    164.             // If we are really slow, just snap to the target direction
    165.             if (moveSpeed < walkSpeed * 0.9f  grounded)
    166.             {
    167.                 moveDirection = targetDirection.normalized;
    168.             }
    169.             // Otherwise smoothly turn towards it
    170.             else
    171.             {
    172.                 moveDirection = Vector3.RotateTowards(moveDirection, targetDirection, rotateSpeed * Mathf.Deg2Rad * Time.deltaTime, 1000);
    173.                
    174.                 moveDirection = moveDirection.normalized;
    175.             }
    176.         }
    177.        
    178.         // Smooth the speed based on the current target direction
    179.         float curSmooth= speedSmoothing * Time.deltaTime;
    180.        
    181.         // Choose target speed
    182.         //* We want to support analog input but make sure you cant walk faster diagonally than just forward or sideways
    183.         float targetSpeed= Mathf.Min(targetDirection.magnitude, 1.0f);
    184.    
    185.         _characterState = CharacterState.Idle;
    186.        
    187.         // Pick speed modifier
    188.         if (Input.GetKey (KeyCode.LeftShift) || Input.GetKey (KeyCode.RightShift))
    189.         {
    190.             targetSpeed *= runSpeed;
    191.             _characterState = CharacterState.Running;
    192.         }
    193.         else if (Time.time - trotAfterSeconds > walkTimeStart)
    194.         {
    195.             targetSpeed *= trotSpeed;
    196.             _characterState = CharacterState.Trotting;
    197.         }
    198.         else
    199.         {
    200.             targetSpeed *= walkSpeed;
    201.             _characterState = CharacterState.Walking;
    202.         }
    203.        
    204.         moveSpeed = Mathf.Lerp(moveSpeed, targetSpeed, curSmooth);
    205.        
    206.         // Reset walk time start when we slow down
    207.         if (moveSpeed < walkSpeed * 0.3f)
    208.             walkTimeStart = Time.time;
    209.     }
    210.     // In air controls
    211.     else
    212.     {
    213.         // Lock camera while in air
    214.         if (jumping)
    215.             lockCameraTimer = 0.0f;
    216.  
    217.         if (isMoving)
    218.             inAirVelocity += targetDirection.normalized * Time.deltaTime * inAirControlAcceleration;
    219.     }
    220.    
    221.  
    222.        
    223. }
    224. void  ApplyJumping (){
    225.     // Prevent jumping too fast after each other
    226.     if (lastJumpTime + jumpRepeatTime > Time.time)
    227.         return;
    228.  
    229.     if (IsGrounded()) {
    230.         // Jump
    231.         // - Only when pressing the button down
    232.         // - With a timeout so you can press the button slightly before landing    
    233.         if (canJump  Time.time < lastJumpButtonTime + jumpTimeout) {
    234.             verticalSpeed = CalculateJumpVerticalSpeed (jumpHeight);
    235.             SendMessage("DidJump", SendMessageOptions.DontRequireReceiver);
    236.         }
    237.     }
    238. }
    239. void  ApplyGravity (){
    240.     if (isControllable) // don't move player at all if not controllable.
    241.     {
    242.         // Apply gravity
    243.         bool jumpButton= Input.GetButton("Jump");
    244.        
    245.        
    246.         // When we reach the apex of the jump we send out a message
    247.         if (jumping  !jumpingReachedApex  verticalSpeed <= 0.0f)
    248.         {
    249.             jumpingReachedApex = true;
    250.             SendMessage("DidJumpReachApex", SendMessageOptions.DontRequireReceiver);
    251.         }
    252.    
    253.         if (IsGrounded ())
    254.             verticalSpeed = 0.0f;
    255.         else
    256.             verticalSpeed -= gravity * Time.deltaTime;
    257.     }
    258. }
    259. float  CalculateJumpVerticalSpeed ( float targetJumpHeight  ){
    260.     // From the jump height and gravity we deduce the upwards speed
    261.     // for the character to reach at the apex.
    262.     return Mathf.Sqrt(2 * targetJumpHeight * gravity);
    263. }  
    264. void  DidJump (){
    265.     jumping = true;
    266.     jumpingReachedApex = false;
    267.     lastJumpTime = Time.time;
    268.     lastJumpStartHeight = transform.position.y;
    269.     lastJumpButtonTime = -10;
    270.    
    271.     _characterState = CharacterState.Jumping;
    272. }
    273. void  Update (){
    274.    
    275.     if (!isControllable)
    276.     {
    277.         // kill all inputs if not controllable.
    278.         Input.ResetInputAxes();
    279.     }
    280.  
    281.     if (Input.GetButtonDown ("Jump"))
    282.     {
    283.         lastJumpButtonTime = Time.time;
    284.     }
    285.  
    286.     UpdateSmoothedMovementDirection();
    287.    
    288.     // Apply gravity
    289.     // - extra power jump modifies gravity
    290.     // - controlledDescent mode modifies gravity
    291.     ApplyGravity ();
    292.  
    293.     // Apply jumping logic
    294.     ApplyJumping ();
    295.    
    296.     // Calculate actual motion
    297.     Vector3 movement= moveDirection * moveSpeed + new Vector3 (0, verticalSpeed, 0) + inAirVelocity;
    298.     movement *= Time.deltaTime;
    299.    
    300.     // Move the controller
    301.     CharacterController controller = GetComponent<CharacterController>();
    302.     collisionFlags = controller.Move(movement);
    303.    
    304.     // ANIMATION sector
    305.     if(_animation) {
    306.         if(_characterState == CharacterState.Jumping)
    307.         {
    308.             if(!jumpingReachedApex) {
    309.                 _animation[jumpPoseAnimation.name].speed = jumpAnimationSpeed;
    310.                 _animation[jumpPoseAnimation.name].wrapMode = WrapMode.ClampForever;
    311.                 _animation.CrossFade(jumpPoseAnimation.name);
    312.             } else {
    313.                 _animation[jumpPoseAnimation.name].speed = -landAnimationSpeed;
    314.                 _animation[jumpPoseAnimation.name].wrapMode = WrapMode.ClampForever;
    315.                 _animation.CrossFade(jumpPoseAnimation.name);              
    316.             }
    317.         }
    318.         else
    319.         {
    320.             if(controller.velocity.sqrMagnitude < 0.1f) {
    321.                 _animation.CrossFade(idleAnimation.name);
    322.             }
    323.             else
    324.             {
    325.                 if(_characterState == CharacterState.Running) {
    326.                     _animation[runAnimation.name].speed = Mathf.Clamp(controller.velocity.magnitude, 0.0f, runMaxAnimationSpeed);
    327.                     _animation.CrossFade(runAnimation.name);   
    328.                 }
    329.                 else if(_characterState == CharacterState.Trotting) {
    330.                     _animation[walkAnimation.name].speed = Mathf.Clamp(controller.velocity.magnitude, 0.0f, trotMaxAnimationSpeed);
    331.                     _animation.CrossFade(walkAnimation.name);  
    332.                 }
    333.                 else if(_characterState == CharacterState.Walking) {
    334.                     _animation[walkAnimation.name].speed = Mathf.Clamp(controller.velocity.magnitude, 0.0f, walkMaxAnimationSpeed);
    335.                     _animation.CrossFade(walkAnimation.name);  
    336.                 }
    337.                
    338.             }
    339.         }
    340.     }
    341.     // ANIMATION sector
    342.    
    343.     // Set rotation to the move direction
    344.     if (IsGrounded())
    345.     {
    346.        
    347.         transform.rotation = Quaternion.LookRotation(moveDirection);
    348.            
    349.     }  
    350.     else
    351.     {
    352.         Vector3 xzMove= movement;
    353.         xzMove.y = 0;
    354.         if (xzMove.sqrMagnitude > 0.001f)
    355.         {
    356.             transform.rotation = Quaternion.LookRotation(xzMove);
    357.         }
    358.     }  
    359.    
    360.     // We are in jump mode but just became grounded
    361.     if (IsGrounded())
    362.     {
    363.         lastGroundedTime = Time.time;
    364.         inAirVelocity = Vector3.zero;
    365.         if (jumping)
    366.         {
    367.             jumping = false;
    368.             SendMessage("DidLand", SendMessageOptions.DontRequireReceiver);
    369.         }
    370.     }
    371. }
    372. void  OnControllerColliderHit ( ControllerColliderHit hit   ){
    373. //  Debug.DrawRay(hit.point, hit.normal);
    374.     if (hit.moveDirection.y > 0.01f)
    375.         return;
    376. }  
    377.     float  GetSpeed (){
    378.     return moveSpeed;
    379. }
    380.  
    381. bool  IsJumping (){
    382.     return jumping;
    383. }
    384.  
    385. bool  IsGrounded (){
    386.     return (collisionFlags  CollisionFlags.CollidedBelow) != 0;
    387. }
    388.  
    389. Vector3  GetDirection (){
    390.     return moveDirection;
    391. }
    392.  
    393. bool  IsMovingBackwards (){
    394.     return movingBack;
    395. }
    396.  
    397. float  GetLockCameraTimer (){
    398.     return lockCameraTimer;
    399. }
    400.  
    401. bool IsMoving (){
    402.      return Mathf.Abs(Input.GetAxisRaw("Vertical")) + Mathf.Abs(Input.GetAxisRaw("Horizontal")) > 0.5f;
    403. }
    404.  
    405. bool  HasJumpReachedApex (){
    406.     return jumpingReachedApex;
    407. }
    408.  
    409. bool  IsGroundedWithTimeout (){
    410.     return lastGroundedTime + groundedTimeout > Time.time;
    411. }
    412.  
    413. void  Reset (){
    414.     gameObject.tag = "Player";
    415. }
    416.  
    417. }
    418.  
    419.  
    420.  
    421.  
    took me a fair amount of time (like 3-4 hours non stop) I did this because I read somewhere calling javascript from C# its no good and im coding in C# so this will help avoid headaches in the future.
    I started coding last week so if you find any errors please tell me, but so far it works like it should.
     
    Last edited: Jan 16, 2013
  2. ElementFire

    ElementFire

    Joined:
    Jan 16, 2013
    Posts:
    1
    Estou com problemas na animação, eu não consegui voltar ao estado idle, e o meu avatar está com os braços abertos, como posso resolver isso? conto com a sua ajuda, obrigado.

    I have problems in the animation, I could not return to the idle state, and my avatar is with open arms, how can I solve this? I count on your help, thank you.
     
  3. raycosantana

    raycosantana

    Joined:
    Dec 23, 2012
    Posts:
    319
    That happened to me once I think , select your character in the assets forlder and mark your character rig as "legacy".
     
  4. raycosantana

    raycosantana

    Joined:
    Dec 23, 2012
    Posts:
    319
    Im not actually asking for help to translate it, I already translated it, its the code right there. I made this thread in case anyone needs it.
     
  5. rbarbosa

    rbarbosa

    Joined:
    Jun 20, 2012
    Posts:
    61
    @raycosantana ... this is awesome. Thanks for the community contribution. Even if it's free, you might want to put this out on the Asset Store.

    Thanks!
    --RB
     
  6. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    Thanks a lot yo! this helps a lot.
     
  7. Dinrae

    Dinrae

    Joined:
    Dec 19, 2012
    Posts:
    29
    Thanks!
     
  8. Spoking

    Spoking

    Joined:
    Nov 21, 2012
    Posts:
    2
    Thanks a lot man! I really needed this =)
     
  9. marcin107

    marcin107

    Joined:
    Aug 9, 2014
    Posts:
    5
    If someone is still looking at the topic, why there are no logic operators in ifs? Like in 117 line?

    @solved
    Simply all the "&" had gone.
     
  10. Pizzalord

    Pizzalord

    Joined:
    Jun 7, 2014
    Posts:
    1
    Thanks Just what I was hoping for XD
     
  11. fullmando

    fullmando

    Joined:
    Mar 7, 2014
    Posts:
    8

    Thanks for the code, however I have an error: CS0116: A namespace can only contain types and namespace declaration, sorry to be such a noob.

    void UpdateSmoothedMovementDirection (){
    Transform cameraTransform = Camera.main.transform;
    bool grounded = IsGrounded();
     
  12. Barry100

    Barry100

    Joined:
    Nov 12, 2014
    Posts:
    200
    i get a parse error just before void UpdateSmoothedMovementDirection (){
    i have tried to put in curly braces but no joy!
     
  13. fullmando

    fullmando

    Joined:
    Mar 7, 2014
    Posts:
    8
    Post your code, I will take a look.
     
  14. Pipeweed

    Pipeweed

    Joined:
    May 20, 2014
    Posts:
    1
    karanghost likes this.
  15. itsapainfulworld

    itsapainfulworld

    Joined:
    Jan 21, 2015
    Posts:
    1
    Not sure if anyone is still browsing this thread, but I get an error with the "fixed" version that Pipeweed posted, it appears that the Third Person Controller script included isn't referencing the test cube I attached it to. The expanded Error in the Console's log is as follows.

    NullReferenceException: Object reference not set to an instance of an object
    ThirdPersonController.UpdateSmoothedMovementDirection () (at Assets/ThirdPersonController.cs:137)
    ThirdPersonController.Update () (at Assets/ThirdPersonController.cs:310)

    Unfortunately I don't see a field in the editor to specify it's object reference....
     
  16. rofikcoga

    rofikcoga

    Joined:
    Apr 8, 2015
    Posts:
    6
  17. Deleted User

    Deleted User

    Guest

    if your going to post a script modification, post the whole thing and then note where the changes are made. Second, this "Script" conversion is full of errors.

    like;
    (118,34): error CS1525: Unexpected symbol `canJump'
    (166,54): error CS1525: Unexpected symbol `grounded'
    (124,11): error CS0116: A namespace can only contain types and namespace declarations
    (212,5): error CS8025: Parsing error

    and true to form, there isn't any explanations.
     
  18. Tolufoyeh

    Tolufoyeh

    Joined:
    Nov 13, 2014
    Posts:
    16
    So did anyone end up correcting this script to remove all errors?
     
  19. InjectWare

    InjectWare

    Joined:
    Mar 6, 2015
    Posts:
    6
    Da fehlen über all die (&&) Zeichen alter und (&) ^^
     
  20. CloudFire

    CloudFire

    Joined:
    Dec 8, 2015
    Posts:
    33
    @raycosantana yours Coding is Superb and Excellent. Congratulations.........For your Good Work ....

    Here i have rectified the error. The Error is Very Very Simple.. Any how i have corrected this code For basic programmers.


    Here is the code
    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. [AddComponentMenu("Rayco's scripts/third person controller")]
    5. public class NewBehaviourScript : MonoBehaviour {
    6.     public AnimationClip idleAnimation;
    7.     public AnimationClip walkAnimation;
    8.     public AnimationClip runAnimation;
    9.     public AnimationClip jumpPoseAnimation;
    10.    
    11.     public float walkMaxAnimationSpeed = 0.75F;
    12.     public float trotMaxAnimationSpeed = 1F;
    13.     public float runMaxAnimationSpeed = 1F;
    14.     public float jumpAnimationSpeed = 1F;
    15.     public float landAnimationSpeed =1F;
    16.    
    17.     private Animation _animation;
    18.    
    19.     enum CharacterState {
    20.         Idle = 0,
    21.         Walking = 1,
    22.         Trotting = 2,
    23.         Running = 3,
    24.         Jumping = 4,  
    25.     }
    26.     private CharacterState _characterState;
    27.     // The speed when walking
    28.     public float walkSpeed = 2.0F;
    29.     // after trotAfterSeconds of walking we trot with trotSpeed
    30.     public float trotSpeed = 4.0F;
    31.     // when pressing "Fire3" button (cmd) we start running
    32.     public float runSpeed = 6.0F;
    33.    
    34.     public float inAirControlAcceleration = 3.0F;
    35.    
    36.     // How high do we jump when pressing jump and letting go immediately
    37.     public float jumpHeight = 0.5F;
    38.    
    39.     // The gravity for the character
    40.     public float gravity = 20.0F;
    41.     // The gravity in controlled descent mode
    42.     public float speedSmoothing = 10.0F;
    43.     public float rotateSpeed = 500.0F;
    44.     public float trotAfterSeconds = 3.0F;
    45.    
    46.     public bool canJump= true;
    47.    
    48.     private float jumpRepeatTime = 0.05F;
    49.     private float jumpTimeout = 0.15F;
    50.     private float groundedTimeout = 0.25F;
    51.    
    52.     // The camera doesnt start following the target immediately but waits for a split second to avoid too much waving around.
    53.     private float lockCameraTimer = 0.0F;
    54.    
    55.     // The current move direction in x-z
    56.     private Vector3 moveDirection = Vector3.zero;
    57.     // The current vertical speed
    58.     private float verticalSpeed = 0.0F;
    59.     // The current x-z move speed
    60.     private float moveSpeed = 0.0F;
    61.    
    62.     // The last collision flags returned from controller.Move
    63.     private CollisionFlags collisionFlags ;
    64.    
    65.     // Are we jumping? (Initiated with jump button and not grounded yet)
    66.     private bool jumping = false;
    67.     private bool jumpingReachedApex = false;
    68.    
    69.     // Are we moving backwards (This locks the camera to not do a 180 degree spin)
    70.     private bool movingBack = false;
    71.     // Is the user pressing any keys?
    72.     private bool isMoving = false;
    73.     // When did the user start walking (Used for going into trot after a while)
    74.     private float walkTimeStart = 0.0F;
    75.     // Last time the jump button was clicked down
    76.     private float lastJumpButtonTime = -10.0F;
    77.     // Last time we performed a jump
    78.     private float lastJumpTime = -1.0F;
    79.    
    80.    
    81.     // the height we jumped from (Used to determine for how long to apply extra jump power after jumping.)
    82.     private float lastJumpStartHeight = 0.0F;
    83.    
    84.    
    85.     private Vector3 inAirVelocity = Vector3.zero;
    86.    
    87.     private float lastGroundedTime = 0.0F;
    88.    
    89.    
    90.     private bool isControllable = true;
    91.    
    92.     // Use this for initialization
    93.     void  Awake (){
    94.         moveDirection = transform.TransformDirection(Vector3.forward);
    95.        
    96.         _animation = GetComponent<Animation>();
    97.         if(!_animation)
    98.             Debug.Log("The character you would like to control doesn't have animations. Moving her might look weird.");
    99.        
    100.         /*
    101. public AnimationClip idleAnimation;
    102. public AnimationClip walkAnimation;
    103. public AnimationClip runAnimation;
    104. public AnimationClip jumpPoseAnimation;
    105.     */
    106.         if(!idleAnimation) {
    107.             _animation = null;
    108.             Debug.Log("No idle animation found. Turning off animations.");
    109.         }
    110.         if(!walkAnimation) {
    111.             _animation = null;
    112.             Debug.Log("No walk animation found. Turning off animations.");
    113.         }
    114.         if(!runAnimation) {
    115.             _animation = null;
    116.             Debug.Log("No run animation found. Turning off animations.");
    117.         }
    118.         if(!jumpPoseAnimation && canJump) {
    119.             _animation = null;
    120.             Debug.Log("No jump animation found and the character has canJump enabled. Turning off animations.");
    121.         }
    122.        
    123.     }
    124.     void  UpdateSmoothedMovementDirection (){
    125.         Transform cameraTransform = Camera.main.transform;
    126.         bool grounded = IsGrounded();
    127.        
    128.         // Forward vector relative to the camera along the x-z plane  
    129.         Vector3 forward= cameraTransform.TransformDirection(Vector3.forward);
    130.         forward.y = 0;
    131.         forward = forward.normalized;
    132.        
    133.         // Right vector relative to the camera
    134.         // Always orthogonal to the forward vector
    135.         Vector3 right= new Vector3(forward.z, 0, -forward.x);
    136.        
    137.         float v= Input.GetAxisRaw("Vertical");
    138.         float h= Input.GetAxisRaw("Horizontal");
    139.        
    140.         // Are we moving backwards or looking backwards
    141.         if (v < -0.2f)
    142.             movingBack = true;
    143.         else
    144.             movingBack = false;
    145.        
    146.         bool wasMoving= isMoving;
    147.         isMoving = Mathf.Abs (h) > 0.1f || Mathf.Abs (v) > 0.1f;
    148.        
    149.         // Target direction relative to the camera
    150.         Vector3 targetDirection= h * right + v * forward;
    151.        
    152.         // Grounded controls
    153.         if (grounded)
    154.         {
    155.             // Lock camera for short period when transitioning moving  standing still
    156.             lockCameraTimer += Time.deltaTime;
    157.             if (isMoving != wasMoving)
    158.                 lockCameraTimer = 0.0f;
    159.            
    160.             // We store speed and direction seperately,
    161.             // so that when the character stands still we still have a valid forward direction
    162.             // moveDirection is always normalized, and we only update it if there is user input.
    163.             if (targetDirection != Vector3.zero)
    164.             {
    165.                 // If we are really slow, just snap to the target direction
    166.                 if (moveSpeed < walkSpeed * 0.9f && grounded)
    167.                 {
    168.                     moveDirection = targetDirection.normalized;
    169.                 }
    170.                 // Otherwise smoothly turn towards it
    171.                 else
    172.                 {
    173.                     moveDirection = Vector3.RotateTowards(moveDirection, targetDirection, rotateSpeed * Mathf.Deg2Rad * Time.deltaTime, 1000);
    174.                    
    175.                     moveDirection = moveDirection.normalized;
    176.                 }
    177.             }
    178.            
    179.             // Smooth the speed based on the current target direction
    180.             float curSmooth= speedSmoothing * Time.deltaTime;
    181.            
    182.             // Choose target speed
    183.             //* We want to support analog input but make sure you cant walk faster diagonally than just forward or sideways
    184.             float targetSpeed= Mathf.Min(targetDirection.magnitude, 1.0f);
    185.            
    186.             _characterState = CharacterState.Idle;
    187.            
    188.             // Pick speed modifier
    189.             if (Input.GetKey (KeyCode.LeftShift) || Input.GetKey (KeyCode.RightShift))
    190.             {
    191.                 targetSpeed *= runSpeed;
    192.                 _characterState = CharacterState.Running;
    193.             }
    194.             else if (Time.time - trotAfterSeconds > walkTimeStart)
    195.             {
    196.                 targetSpeed *= trotSpeed;
    197.                 _characterState = CharacterState.Trotting;
    198.             }
    199.             else
    200.             {
    201.                 targetSpeed *= walkSpeed;
    202.                 _characterState = CharacterState.Walking;
    203.             }
    204.            
    205.             moveSpeed = Mathf.Lerp(moveSpeed, targetSpeed, curSmooth);
    206.            
    207.             // Reset walk time start when we slow down
    208.             if (moveSpeed < walkSpeed * 0.3f)
    209.                 walkTimeStart = Time.time;
    210.         }
    211.         // In air controls
    212.         else
    213.         {
    214.             // Lock camera while in air
    215.             if (jumping)
    216.                 lockCameraTimer = 0.0f;
    217.            
    218.             if (isMoving)
    219.                 inAirVelocity += targetDirection.normalized * Time.deltaTime * inAirControlAcceleration;
    220.         }
    221.        
    222.        
    223.        
    224.     }
    225.     void  ApplyJumping (){
    226.         // Prevent jumping too fast after each other
    227.         if (lastJumpTime + jumpRepeatTime > Time.time)
    228.             return;
    229.        
    230.         if (IsGrounded()) {
    231.             // Jump
    232.             // - Only when pressing the button down
    233.             // - With a timeout so you can press the button slightly before landing  
    234.             if (canJump && Time.time < lastJumpButtonTime + jumpTimeout) {
    235.                 verticalSpeed = CalculateJumpVerticalSpeed (jumpHeight);
    236.                 SendMessage("DidJump", SendMessageOptions.DontRequireReceiver);
    237.             }
    238.         }
    239.     }
    240.     void  ApplyGravity (){
    241.         if (isControllable) // don't move player at all if not controllable.
    242.         {
    243.             // Apply gravity
    244.             bool jumpButton= Input.GetButton("Jump");
    245.            
    246.            
    247.             // When we reach the apex of the jump we send out a message
    248.             if (jumping && !jumpingReachedApex && verticalSpeed <= 0.0f)
    249.             {
    250.                 jumpingReachedApex = true;
    251.                 SendMessage("DidJumpReachApex", SendMessageOptions.DontRequireReceiver);
    252.             }
    253.            
    254.             if (IsGrounded ())
    255.                 verticalSpeed = 0.0f;
    256.             else
    257.                 verticalSpeed -= gravity * Time.deltaTime;
    258.         }
    259.     }
    260.     float  CalculateJumpVerticalSpeed ( float targetJumpHeight  ){
    261.         // From the jump height and gravity we deduce the upwards speed
    262.         // for the character to reach at the apex.
    263.         return Mathf.Sqrt(2 * targetJumpHeight * gravity);
    264.     }
    265.     void  DidJump (){
    266.         jumping = true;
    267.         jumpingReachedApex = false;
    268.         lastJumpTime = Time.time;
    269.         lastJumpStartHeight = transform.position.y;
    270.         lastJumpButtonTime = -10;
    271.        
    272.         _characterState = CharacterState.Jumping;
    273.     }
    274.     void  Update (){
    275.        
    276.         if (!isControllable)
    277.         {
    278.             // kill all inputs if not controllable.
    279.             Input.ResetInputAxes();
    280.         }
    281.        
    282.         if (Input.GetButtonDown ("Jump"))
    283.         {
    284.             lastJumpButtonTime = Time.time;
    285.         }
    286.        
    287.         UpdateSmoothedMovementDirection();
    288.        
    289.         // Apply gravity
    290.         // - extra power jump modifies gravity
    291.         // - controlledDescent mode modifies gravity
    292.         ApplyGravity ();
    293.        
    294.         // Apply jumping logic
    295.         ApplyJumping ();
    296.        
    297.         // Calculate actual motion
    298.         Vector3 movement= moveDirection * moveSpeed + new Vector3 (0, verticalSpeed, 0) + inAirVelocity;
    299.         movement *= Time.deltaTime;
    300.        
    301.         // Move the controller
    302.         CharacterController controller = GetComponent<CharacterController>();
    303.         collisionFlags = controller.Move(movement);
    304.        
    305.         // ANIMATION sector
    306.         if(_animation) {
    307.             if(_characterState == CharacterState.Jumping)
    308.             {
    309.                 if(!jumpingReachedApex) {
    310.                     _animation[jumpPoseAnimation.name].speed = jumpAnimationSpeed;
    311.                     _animation[jumpPoseAnimation.name].wrapMode = WrapMode.ClampForever;
    312.                     _animation.CrossFade(jumpPoseAnimation.name);
    313.                 } else {
    314.                     _animation[jumpPoseAnimation.name].speed = -landAnimationSpeed;
    315.                     _animation[jumpPoseAnimation.name].wrapMode = WrapMode.ClampForever;
    316.                     _animation.CrossFade(jumpPoseAnimation.name);            
    317.                 }
    318.             }
    319.             else
    320.             {
    321.                 if(controller.velocity.sqrMagnitude < 0.1f) {
    322.                     _animation.CrossFade(idleAnimation.name);
    323.                 }
    324.                 else
    325.                 {
    326.                     if(_characterState == CharacterState.Running) {
    327.                         _animation[runAnimation.name].speed = Mathf.Clamp(controller.velocity.magnitude, 0.0f, runMaxAnimationSpeed);
    328.                         _animation.CrossFade(runAnimation.name);  
    329.                     }
    330.                     else if(_characterState == CharacterState.Trotting) {
    331.                         _animation[walkAnimation.name].speed = Mathf.Clamp(controller.velocity.magnitude, 0.0f, trotMaxAnimationSpeed);
    332.                         _animation.CrossFade(walkAnimation.name);
    333.                     }
    334.                     else if(_characterState == CharacterState.Walking) {
    335.                         _animation[walkAnimation.name].speed = Mathf.Clamp(controller.velocity.magnitude, 0.0f, walkMaxAnimationSpeed);
    336.                         _animation.CrossFade(walkAnimation.name);
    337.                     }
    338.                    
    339.                 }
    340.             }
    341.         }
    342.         // ANIMATION sector
    343.        
    344.         // Set rotation to the move direction
    345.         if (IsGrounded())
    346.         {
    347.            
    348.             transform.rotation = Quaternion.LookRotation(moveDirection);
    349.            
    350.         }
    351.         else
    352.         {
    353.             Vector3 xzMove= movement;
    354.             xzMove.y = 0;
    355.             if (xzMove.sqrMagnitude > 0.001f)
    356.             {
    357.                 transform.rotation = Quaternion.LookRotation(xzMove);
    358.             }
    359.         }
    360.        
    361.         // We are in jump mode but just became grounded
    362.         if (IsGrounded())
    363.         {
    364.             lastGroundedTime = Time.time;
    365.             inAirVelocity = Vector3.zero;
    366.             if (jumping)
    367.             {
    368.                 jumping = false;
    369.                 SendMessage("DidLand", SendMessageOptions.DontRequireReceiver);
    370.             }
    371.         }
    372.     }
    373.     void  OnControllerColliderHit ( ControllerColliderHit hit   ){
    374.         //  Debug.DrawRay(hit.point, hit.normal);
    375.         if (hit.moveDirection.y > 0.01f)
    376.             return;
    377.     }
    378.     float  GetSpeed (){
    379.         return moveSpeed;
    380.     }
    381.    
    382.     bool  IsJumping (){
    383.         return jumping;
    384.     }
    385.    
    386.     bool  IsGrounded (){
    387.         return (CollisionFlags.CollidedBelow) != 0;
    388.     }
    389.    
    390.     Vector3  GetDirection (){
    391.         return moveDirection;
    392.     }
    393.    
    394.     bool  IsMovingBackwards (){
    395.         return movingBack;
    396.     }
    397.    
    398.     float  GetLockCameraTimer (){
    399.         return lockCameraTimer;
    400.     }
    401.    
    402.     bool IsMoving (){
    403.         return Mathf.Abs(Input.GetAxisRaw("Vertical")) + Mathf.Abs(Input.GetAxisRaw("Horizontal")) > 0.5f;
    404.     }
    405.    
    406.     bool  HasJumpReachedApex (){
    407.         return jumpingReachedApex;
    408.     }
    409.    
    410.     bool  IsGroundedWithTimeout (){
    411.         return lastGroundedTime + groundedTimeout > Time.time;
    412.     }
    413.    
    414.     void  Reset (){
    415.         gameObject.tag = "Player";
    416.     }
    417.    
    418. }
    419.  
    420.  
     
  21. GeminiGamerGames

    GeminiGamerGames

    Joined:
    Aug 4, 2015
    Posts:
    1
    Hey Man...!! I am here in May 21 and this code helps me a lot. Thanks man. btw, there needs to be && in various places according to the current unity version.