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

Question If I have a Rigidbody on my model I must rotate/scale/move it inside FixedUpdate ?

Discussion in 'Physics' started by shamenraze1988, Mar 29, 2021.

  1. shamenraze1988

    shamenraze1988

    Joined:
    Nov 24, 2020
    Posts:
    208
    and move it with the rigidbody forces ? or I can move the transform just in the Update ?
     
  2. Zergling103

    Zergling103

    Joined:
    Aug 16, 2011
    Posts:
    392
    If you're intention is to provide physically natural movement, it is best to use forces. This is done in FixedUpdate(). If this is what you want, I can provide a formula for you on how to calculate the exact forces you need.

    If you want to teleport a rigidbody that is normally subject to physics, it is best to set the rigidbody's transform position, and then the rigidbody's position afterwards. Believe it or not, I've had to do both in order to ensure that the object actually moves there completely. This can be done at any time.

    If you want to write your own custom movement entirely, you can make the rigidbody kinematic and then use MovePosition(). This can be done at any time. However, the object *will* move to the specified position regardless of whether an object is in the way. Also, the rigidbody will not react to forces (i.e. from collisions) that act upon it, but other rigidbodies will react appropriately to it.

    Lastly, you may want to use a CharacterController depending on what you're trying to do.
     
    Last edited: Mar 29, 2021
    shamenraze1988 likes this.
  3. shamenraze1988

    shamenraze1988

    Joined:
    Nov 24, 2020
    Posts:
    208

    My character (I didn't make it , I bought it) have this components :

    Animator , Rigidbody , Capsule Collider , Third Person User Control , Third Person Character.

    I'm using the keys WSAD to control the character movements. and a cinemachine free look camera using the mouse to look around.

    Then I have this script on another object that I'm trying to manipulate some rotations and movements on the character(player).

    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.UI;
    6.  
    7. public class DetectCollision : MonoBehaviour
    8. {
    9.     public Transform player;
    10.     public Transform target;
    11.     public Text currPosDistanceUiText;
    12.     public bool rotateAutomatic = false;
    13.     public bool turnOnOffPlayerAnimator = false;
    14.  
    15.     float timeElapsed = 0;
    16.     float lerpDuration = 3;
    17.     float startValue = 1;
    18.     float endValue = 0;
    19.     float valueToLerp = 0;
    20.  
    21.     private Animator playerAnimator;
    22.     private bool entered = false;
    23.     private bool prevFacing = false;
    24.     private bool stopped = false;
    25.     private bool move = true;
    26.     private bool rot = false;
    27.     private Vector3 currPos;
    28.  
    29.     // Start is called before the first frame update
    30.     void Start()
    31.     {
    32.         playerAnimator = player.GetComponent<Animator>();
    33.  
    34.         if (turnOnOffPlayerAnimator)
    35.             playerAnimator.enabled = false;
    36.     }
    37.  
    38.     // Update is called once per frame
    39.     void Update()
    40.     {
    41.         var currFacing = IsFacing(target);
    42.         if (currFacing != prevFacing)
    43.         {
    44.             // here you switched from facing to not facing or vise verca.
    45.             timeElapsed = 0;
    46.         }
    47.         prevFacing = currFacing;
    48.  
    49.         var distance = Vector3.Distance(player.position, target.position);
    50.  
    51.         if (IsFacing(target))
    52.         {
    53.             if (entered && distance > 30 && move)
    54.             {
    55.                 if (timeElapsed < lerpDuration)
    56.                 {
    57.                     valueToLerp = Mathf.Lerp(startValue, endValue, timeElapsed / lerpDuration);
    58.                     playerAnimator.SetFloat("Forward", valueToLerp);
    59.                     timeElapsed += Time.deltaTime;
    60.                 }
    61.                 playerAnimator.SetFloat("Forward", valueToLerp);
    62.                 stopped = true;
    63.                 valueToLerp = 0;
    64.             }
    65.  
    66.             if (move == false)
    67.             {
    68.                 playerAnimator.SetFloat("Forward", 0);
    69.             }
    70.  
    71.             if (playerAnimator.GetFloat("Forward") == 0 && stopped)
    72.             {
    73.                 move = false;
    74.                 rot = true;
    75.                 currPos = player.position;
    76.              
    77.                 Debug.Log("Player current position when valueToLerp value is 0 : " + currPos);
    78.             }
    79.         }
    80.         else
    81.         {
    82.             if (rotateAutomatic == false)
    83.             {
    84.                 if (valueToLerp < 0.9f)
    85.                 {
    86.                     if (timeElapsed < lerpDuration)
    87.                     {
    88.                         valueToLerp = Mathf.Lerp(endValue, startValue, timeElapsed / lerpDuration);
    89.                         playerAnimator.SetFloat("Forward", valueToLerp);
    90.                         timeElapsed += Time.deltaTime;
    91.                     }
    92.                     playerAnimator.SetFloat("Forward", valueToLerp);
    93.                 }
    94.             }
    95.  
    96.             var dist = Vector3.Distance(player.position, currPos);
    97.             currPosDistanceUiText.text = dist.ToString();
    98.             if (dist > 2)
    99.             {
    100.                 move = true;
    101.             }
    102.         }
    103.  
    104.         if (rotateAutomatic && rot)
    105.         {
    106.             StartCoroutine(ScaleOverSeconds(new Vector3(0.3f,0.3f,0.3f),
    107.                 new Vector3(0,90,0), new Vector3(player.localPosition.x + 20,0,0) , 5));
    108.             rot = false;
    109.             //StartCoroutine(AnimateRotationTowards(player, Quaternion.Euler(0, 180, 0), 5f));
    110.  
    111.             /*player.rotation = Quaternion.Lerp(player.rotation, Quaternion.Euler(0, 180, 0), Time.time * 0.0003f);
    112.  
    113.             if (timeElapsed < lerpDuration)
    114.             {
    115.                 valueToLerp = Mathf.Lerp(endValue, startValue, timeElapsed / lerpDuration);
    116.                 playerAnimator.SetFloat("Forward", valueToLerp);
    117.                 timeElapsed += Time.deltaTime;
    118.             }
    119.             playerAnimator.SetFloat("Forward", valueToLerp);*/
    120.         }
    121.  
    122.         if (turnOnOffPlayerAnimator)
    123.         {
    124.             playerAnimator.enabled = false;
    125.         }
    126.         else
    127.         {
    128.             playerAnimator.enabled = true;
    129.         }
    130.     }
    131.  
    132.     private void OnTriggerEnter(Collider other)
    133.     {
    134.         entered = true;
    135.  
    136.         Debug.Log("Entered !");
    137.     }
    138.  
    139.     private void OnTriggerExit(Collider other)
    140.     {
    141.         entered = false;
    142.  
    143.         Debug.Log("Exited !");
    144.     }
    145.  
    146.     private bool IsFacing(Transform target)
    147.     {
    148.         Vector3 forward = player.TransformDirection(Vector3.forward);
    149.         Vector3 toTarget = target.position - player.position;
    150.         return Vector3.Dot(forward, toTarget) > 0;
    151.     }
    152.  
    153.     private System.Collections.IEnumerator AnimateRotationTowards(Transform target, Quaternion rot, float dur)
    154.     {
    155.         rotateAutomatic = true;
    156.         float t = 0f;
    157.         Quaternion start = target.rotation;
    158.         while (t < dur)
    159.         {
    160.             target.rotation = Quaternion.Slerp(start, rot, t / dur);
    161.             yield return null;
    162.             t += Time.deltaTime;
    163.         }
    164.         target.rotation = rot;
    165.     }
    166.  
    167.     public IEnumerator ScaleOverSeconds(Vector3 scaleTo, Vector3 rotateTo, Vector3 moveTo, float seconds)
    168.     {
    169.         float elapsedTime = 0;
    170.         Vector3 startingScale = player.localScale;
    171.         Vector3 startingRotation = player.localEulerAngles;
    172.         Vector3 startingPosition = player.localPosition;
    173.      
    174.         while (elapsedTime < seconds)
    175.         {
    176.             player.localScale = Vector3.Lerp(startingScale, scaleTo, (elapsedTime / seconds));
    177.             player.localEulerAngles = Vector3.Lerp(startingRotation, rotateTo, (elapsedTime / seconds));
    178.             player.localPosition = Vector3.Lerp(startingPosition, moveTo, (elapsedTime / seconds));
    179.  
    180.             elapsedTime += Time.deltaTime;
    181.          
    182.             yield return null;
    183.         }
    184.         player.localScale = scaleTo;
    185.         player.localEulerAngles = rotateTo;
    186.         player.localPosition = moveTo;
    187.     }
    188. }
    189.  
    The script is a bit messed but everything , almost everything is working as I wanted so far.
    The problem is with the function : ScaleOverSeconds

    It was working fine and smooth when I used the Lerp for scaling and rotating. The player is scaling and rotating at the same time. but then I tried to add also a movement to the player. So the player should scale,rotate,move the same time.

    The problem is as soon as I added the move part for the player in this function the player is stuttering. stuttering/shaking when moving and when stopped at the end when it finished moving the player is keep stuttering.

    That's why I asked about the FixedUpdate because the stuttering problem.