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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Problem while moving in camera direction

Discussion in 'Scripting' started by markblank05, Aug 23, 2015.

  1. markblank05

    markblank05

    Joined:
    Apr 2, 2015
    Posts:
    29
    Hi, I'm making a player controller and camera script but I can't fix this problem. My player turns correctly but still move in global z direction. Here is my script.

    Code (CSharp):
    1. void PlayerMovement (float horizontal, float vertical)
    2.     {
    3.         if (horizontal != 0 || vertical != 0)
    4.         {
    5.             // move
    6.             newMovement.Set (horizontal, 0f, vertical);
    7.             newMovement = newMovement.normalized * speed * Time.deltaTime;
    8.             playerRigidbody.MovePosition (transform.position + newMovement);
    9.  
    10.             // rotate
    11.             Vector3 targetDirection = new Vector3 (horizontal, 0f, vertical);
    12.             targetDirection = Camera.main.transform.TransformDirection(targetDirection);
    13.             targetDirection.y = 0.0f;
    14.  
    15.             Quaternion targetRotation = Quaternion.LookRotation (targetDirection, Vector3.up);
    16.             Quaternion newRotation = Quaternion.Lerp (playerRigidbody.rotation, targetRotation, turnSmoothing * Time.deltaTime);
    17.            
    18.             playerRigidbody.MoveRotation (newRotation);
    19.  
    20.             // animate
    21.             anim.SetBool ("isRunning", true);
    22.         }
    23.         else
    24.         {
    25.             anim.SetBool ("isRunning", false);
    26.         }
    27.     }
     
  2. markblank05

    markblank05

    Joined:
    Apr 2, 2015
    Posts:
    29
    i found a solution by using transformdirection but it's jittering whilte I turn. any idea how to fix it? here is my new code for move
    Code (CSharp):
    1. // move
    2.             newMovement.Set (horizontal, 0f, vertical);
    3.             newMovement = newMovement.normalized * speed * Time.deltaTime;
    4.             newMovement = Camera.main.transform.TransformDirection (newMovement);
    5.             playerRigidbody.MovePosition (transform.position + newMovement);
     
  3. markblank05

    markblank05

    Joined:
    Apr 2, 2015
    Posts:
    29
    bump anyone? cant fix my my character jitter or vibrate while turning.

    here is my camera script

    Code (CSharp):
    1.  void Awake ()
    2.      {
    3.          offset = new Vector3 (0f, 2f, -2f);
    4.      }
    5.      void LateUpdate ()
    6.      {
    7.          offset = Quaternion.AngleAxis (Input.GetAxis ("Mouse X") * turnSpeed, Vector3.up) * offset;
    8.          transform.position = player.position + offset;
    9.          transform.LookAt (new Vector3 (player.position.x, player.position.y + 1f, player.position.z));
    10.      }
     
  4. SomeGuy22

    SomeGuy22

    Joined:
    Jun 3, 2011
    Posts:
    722
    Your Camera is in LateUpdate() so it's moving after the PlayerMovement has already been called--assuming it's in Update(). Also probably won't make a difference but you may want to change that Quaternion.Lerp to Slerp. And of course, rigidbodies are going to be a bit jittery with rotations on surface contacts. I'd look into surface values and the colliders involved (mesh collider?) and also you may want to try rotation the object using transform.rotation = Quaternion.Slerp instead. Also take a look at this post: http://answers.unity3d.com/questions/55635/rotating-a-rigid-body-to-face-left-or-right-smooth.html you're already doing this but maybe it's better not to use MoveRotation? Finally, make sure Time.deltaTime is only in Update and LateUpdate. For FixedUpdate() use Time.fixedDeltaTime
     
  5. markblank05

    markblank05

    Joined:
    Apr 2, 2015
    Posts:
    29
    @SomeGuy22 thanks, I try everything you said. but still have some vibration when I turn. any idea or do you know similar 3rd person controller and camera script?
     
  6. SomeGuy22

    SomeGuy22

    Joined:
    Jun 3, 2011
    Posts:
    722
    Have you tried your camera script to something like this?:
    Code (CSharp):
    1. void LateUpdate()
    2. {
    3.       offset = Quaternion.AngleAxis(Input.GetAxis("Mouse X") * turnSpeed, Vector3.up) * offset;
    4.       transform.position = player.position + offset;
    5.       Vector3 newLook = player.position - transform.position;
    6.       Quaternion quat = Quaternion.identity;
    7.         if ((newLook) != Vector3.zero)
    8.         quat = Quaternion.LookRotation(newLook);
    9.       transform.rotation = Quaternion.Slerp(transform.rotation, quat, Time.deltaTime);
    10. }
    EDIT: Syntax .-.
     
  7. A.Killingbeck

    A.Killingbeck

    Joined:
    Feb 21, 2014
    Posts:
    483
    So what functionality are you actually trying to get? Just move forward in the direction the camera is facing? Or actually move toward the position of the camera?

    That doesn't make sense, you can't slerp/lerp between 2 values based on something which doesn't change.
     
  8. SomeGuy22

    SomeGuy22

    Joined:
    Jun 3, 2011
    Posts:
    722
    You mean how Time.deltaTime doesn't change? (I should've added a * 9 after that to make it faster just because time.deltaTime is way too small to be used realistically there)

    Think of it like this--exponential slerping.

    When quat changes, (considering Time.deltaTime stays relatively constant) the difference between quat and transform.rotation changes as well. For the sake of argument, lets assume Time.deltaTime is .3; lets also assume quat and transform.rotation are floats (to easier understand). For the first frame, when quat becomes 4, if transform.rotation is 1, it will move 30% of the rotation towards 4. (30% of 4 - 3 is .9, so) Transform.rotation is now 1.9! For frame 2, the difference between quat and transform.rotation is less. Time.deltaTime is .3 again. Now it is 30% of 4 - 1.9 = .63! Transform.rotation is now 1.9 + .63 = 2.53. And so on--the difference between 4 and transform.rotation is decreasing!

    So every frame, transform.rotation moves closer and closer to 4. Even though it will never reach 4 (this is exponential slerping). I've used this idea many times before, and it creates a smooth exponential rotation. If you're really worried about the fact that it will never reach 4, you can always just replace Quaternion.Slerp with Quaternion.RotateTowards. This function essentially rotates towards the Quaternion based off a speed value (not a percentage between 0 and 1 like Slerp). Unity will then ensure that the speed between changing vectors is always constant, and not exponential, and it will reach 4 in the designated speed value. :)

    EDIT: there is also a Vector3.MoveTowards which is the Vector3 equivalent of Vector3.Lerp