Search Unity

Question Why when adding force to transform the transform never moving pass a slope ?

Discussion in 'Physics' started by shamenraze1988, Jul 18, 2021.

  1. shamenraze1988

    shamenraze1988

    Joined:
    Nov 24, 2020
    Posts:
    208
    Code (csharp):
    1.  
    2. rb.AddForce(transform.forward * speed * Time.deltaTime);
    3.  
    Even if the speed value is 500 or 1000 the object is rolling but never climbs up the slope.

    If I change the transform to Vector3.right instead it will roll and pass the slope with speed 500 but it will not move directly forward it will move a bit to the right. And if I set it to Vector3.forward then it will move directly to the right and even a bit back. When I'm using vector3.right this is forward and if using transform.forward this is forward but then the object will not move over the slope.

    I want the object to move directly forward on the blue axis but if I'm using transform.forward it will not be able to climb the slope at all but the direction is directly forward. and if I'm using Vector3.right it will move forward but also to the right.

    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class Rolling : MonoBehaviour
    7. {
    8.    public Transform player;
    9.    public Transform crate;
    10.    public Animation anim;
    11.    public float timeToStopRolling;
    12.    public float speed;
    13.    public float waitBeforeSlowdown;
    14.    public float startDrag;
    15.    public float endDrag = 50;
    16.    public float rotationSpeed;
    17.  
    18.    private bool crateOpenOnce = false;
    19.    private bool alreadyRolling;
    20.    private Rigidbody rb;
    21.    private Quaternion defaultRotation;
    22.    public float lerpTimeMultiplicator = 0.25f;
    23.  
    24.    private void Start()
    25.    {
    26.        rb = GetComponent<Rigidbody>();
    27.  
    28.        defaultRotation = rb.rotation;
    29.    }
    30.  
    31.    private void Update()
    32.    {
    33.        var distance = Vector3.Distance(crate.position, player.position);
    34.        if (distance < 1.7f && crateOpenOnce == false)
    35.        {
    36.            anim.Play("Crate_Open");
    37.            rb.isKinematic = false;
    38.  
    39.            crateOpenOnce = true;
    40.        }
    41.    }
    42.  
    43.    private void OnCollisionEnter(Collision collision)
    44.    {
    45.        //NOTE: In general you should go for Tags instead of the name
    46.        if (collision.gameObject.name == "Crate_0_0")
    47.        {
    48.            if (crateOpenOnce)
    49.            {
    50.                rb.drag = 0f;
    51.  
    52.                // Directly start a routine here (if none is already running)
    53.                if (!alreadyRolling) StartCoroutine(RollingRoutine());
    54.            }
    55.        }
    56.    }
    57.  
    58.    private void OnCollisionExit(Collision collision)
    59.    {
    60.        if (collision.gameObject.name == "Crate_0_0")
    61.        {
    62.            speed = 100;
    63.        }
    64.    }
    65.  
    66.    private Vector3 GetRandomDirection()
    67.    {
    68.        var rnd = Random.insideUnitSphere;
    69.        rnd.y = 0;
    70.        return rnd.normalized;
    71.    }
    72.  
    73.    private IEnumerator RollingRoutine()
    74.    {
    75.        // Just in case prevent concurrent routines
    76.        if (alreadyRolling) yield break;
    77.  
    78.        // Block new routines from starting
    79.        alreadyRolling = true;
    80.  
    81.        // Get the random direction for this routine
    82.        var rollDirection = GetRandomDirection();
    83.  
    84.        // Roll for the given time within the FixedUpdate call
    85.        for (var timePassed = 0f; timePassed < timeToStopRolling; timePassed += Time.deltaTime)
    86.        {
    87.            // Wait until you are in FixedUpdate
    88.            // the code after this is now executed within FixedUpdate
    89.            yield return new WaitForFixedUpdate();
    90.  
    91.            rb.AddForce(transform.forward /*rollDirection*/ * speed * Time.deltaTime);
    92.        }
    93.  
    94.        // Wait before slowing down
    95.        yield return new WaitForSeconds(waitBeforeSlowdown);
    96.  
    97.        // Do slow down and rotate to default until both conditions are fulfilled
    98.        var dragLerpFactor = 0f;
    99.        // Store the original drag to reset it later
    100.        var defaultDrag = rb.drag;
    101.        while (!Mathf.Approximately(rb.velocity.sqrMagnitude, 0) || rb.rotation != defaultRotation)
    102.        {
    103.            // Again wait until you are in FixedUpdate
    104.            yield return new WaitForFixedUpdate();
    105.  
    106.            dragLerpFactor += Time.deltaTime * lerpTimeMultiplicator;
    107.            rb.drag = Mathf.Lerp(startDrag, endDrag, dragLerpFactor);
    108.  
    109.            rb.MoveRotation(Quaternion.RotateTowards(rb.rotation, defaultRotation, rotationSpeed * Time.deltaTime));
    110.        }
    111.  
    112.        // Just to be sure to end with clean value assign once
    113.        rb.rotation = defaultRotation;
    114.        rb.drag = defaultDrag;
    115.        rb.velocity = Vector3.zero;
    116.  
    117.        // Allow the next routine to start
    118.        alreadyRolling = false;
    119.    }
    120. }
    121.