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

Player movement and rotation resetting issue

Discussion in 'Scripting' started by relic1882, Mar 11, 2015.

  1. relic1882

    relic1882

    Joined:
    Mar 11, 2015
    Posts:
    45
    Ok, so hello everyone. I wanna start by saying thanks for reading this and I've been learning Unity since about a week ago. I have some C++ and BASIC programming experience but that stuff was 15+ years ago and I'm just getting back into it now.

    This is a kind of top-down 3rd person game I've started and I'm having a small degree of difficulty figuring out this issue. I have a script to control character movement on the screen via wads/arrows/controller. The player moves around just fine. The falling off the edges even works how I want it to. The problem is that I'm trying to set it up so that the player rotates into the direction of travel. The transform.LookAt function works great, but I want to get that smooth-turn-around-not-instantly animation going on, and I can't figure out how to do it right.

    If I try to use Quaternion.Lerp, the animation does work the way I want it to. The problem is that every time I let go of the input on the controller or keyboard, the rotation position defaults back to up and the player faces up every time you stop moving. I can't figure out how to prevent that. I'm sure it's something silly I'm overlooking but it's driving me nuts. Here's my code. Lines 30-42 is where the player gets moved according to input. Please help me learn. Thanks! :)

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class CharacterMovementScript : MonoBehaviour {
    6.  
    7.     public float playerSpeed = 10f;     //sets player's speed
    8.     private Vector3 moveDirection = Vector3.zero;   //initialized player movement direction values
    9.     private Vector3 fallDirection = Vector3.zero;
    10.     //private Vector3 lastMovedDirection = Vector3.zero;  //initialize variable for last known movement direction
    11.     public float gravityValue = 1; //sets value for gravity for when the player is falling off edges 1 is slower, 5+ is very fast
    12.     public float rotationSpeed = 0.5f;   //sets how fast player rotates into the direction they are walking
    13.  
    14.  
    15.     // Use this for initialization
    16.     void Start () {
    17.    
    18.     }
    19.    
    20.     // Update is called once per frame
    21.     void Update () {
    22.  
    23.         MovePlayer();       //calls function to move player in the direction of user input
    24.      
    25.     }
    26.  
    27.  
    28.     void MovePlayer()
    29.     {
    30.         //get controller
    31.         CharacterController controller = GetComponent<CharacterController>();
    32.         //grab movement direction depending on player input
    33.         moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
    34.         //rotate the player in the direction they are walking
    35.  
    36.         Quaternion rotateDirection = Quaternion.LookRotation(moveDirection);
    37.         transform.rotation = Quaternion.Lerp(transform.rotation, rotateDirection, rotationSpeed * Time.deltaTime);
    38.  
    39.         //transform.LookAt(transform.position + moveDirection);
    40.  
    41.         //move player in the direction retrieved
    42.         controller.Move(moveDirection * Time.deltaTime);
    43.  
    44.         //check if player is not on the ground. if player is not on the ground, make player fall
    45.         if(!controller.isGrounded)
    46.         {
    47.             fallDirection = new Vector3(0, -(gravityValue), 0);  //change movement direction to fall down
    48.             controller.Move(fallDirection * Time.deltaTime);    //make player fall to the ground
    49.         }
    50.  
    51.  
    52.     }
    53.  
    54.  
    55. }
    56.  
     
    srde likes this.
  2. relic1882

    relic1882

    Joined:
    Mar 11, 2015
    Posts:
    45
    aw man. Will someone please help me out? I've tried changing to a rigidbody and changing everything here earlier today and I've been at it for too long. I've gone back to the code listed above and I still can't figure it out.
     
  3. Timelog

    Timelog

    Joined:
    Nov 22, 2014
    Posts:
    528
    My guess is that the problem is this:
    Code (CSharp):
    1.  Quaternion rotateDirection = Quaternion.LookRotation(moveDirection);
    Other then that I don't see anything that strikes me as a plausible problem.

    There is one thing you might want to change though. Currently you are getting the CharacterController Component every frame. Just do that in the Start Method, as that getting it every frame is redundant and bad for performance.

    Also, it is possible to still use the physics gravity when using the CharacterController by calling Physics.gravity, you could use that instead of using your own value if you have more rigidbodies in your scene.
     
  4. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    8,934
    I used the old unity smoothLookAt here to slowly turn towards mouse:
    http://unitycoder.com/upload/demos/mDeflectorProto1/ (webplayer demo)

    code was in js though, and not sure if it would work for your situation:
    Code (JavaScript):
    1.  
    2. var damping = 6.0;
    3. private var target:Vector3;
    4.  
    5. function LateUpdate () {
    6.     var mousePos = Input.mousePosition;
    7.     var cameraDif = Camera.main.transform.position.y - transform.transform.position.y;
    8.     target = Camera.main.ScreenToWorldPoint(Vector3(mousePos.x, mousePos.y, cameraDif));
    9.     var rotation = Quaternion.LookRotation(target - transform.position);
    10.     transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * damping);
    11. }
    12.  
     
  5. relic1882

    relic1882

    Joined:
    Mar 11, 2015
    Posts:
    45
    Towards the mouse is one thing, but I'm trying to make it turn to direction that the character is going by pushing the controller axis or keyboard direction.
     
  6. relic1882

    relic1882

    Joined:
    Mar 11, 2015
    Posts:
    45

    I tried putting the character controller component retrieval in the start() function but then the other controllers down in my move functions read errors. It only works when I put it with the rest inside the moveplayer function
     
  7. Timelog

    Timelog

    Joined:
    Nov 22, 2014
    Posts:
    528
    Well, you'll need to set the variable at class level of course if you want other function to be able to reference it.
    Code (CSharp):
    1. class Example
    2. {
    3.     string classLevelVariable;
    4.  
    5.     void Start()
    6.     {
    7.         classLevelVariable = "whatever value";
    8.     }
    9.  
    10.     void Update()
    11.     {
    12.         // Logs "whatever value" in console every frame
    13.         Debug.Log(classLevelVariable);
    14.     }
    15. }
     
  8. relic1882

    relic1882

    Joined:
    Mar 11, 2015
    Posts:
    45
  9. de24danny

    de24danny

    Joined:
    Nov 10, 2018
    Posts:
    1
    I ran into same issue and i resolved it by doing the following not ran into any issues yet will keep this updated

    Change Line 37 from :
    1. transform.rotation = Quaternion.Lerp(transform.rotation, rotateDirection, rotationSpeed * Time.deltaTime);
    To :
    1. if(moveDirection != Vector3.zero) transform.rotation = Quaternion.Lerp(transform.rotation, rotateDirection, rotationSpeed * Time.deltaTime);