Search Unity

AddRelativeForce not doing anything

Discussion in 'Physics' started by steveh2112, Jan 23, 2020.

  1. steveh2112

    steveh2112

    Joined:
    Aug 30, 2015
    Posts:
    314
    i am trying to move an object towards the player using this code in the players FixedUpdate

    Code (CSharp):
    1. // move _HitTargetGO towards player a bit
    2.         const float speed = 1000f;
    3.         Rigidbody rb = _HitTargetGO.transform.GetComponent<Rigidbody>();
    4.         Vector3 direction = transform.position - _HitTargetGO.transform.position;
    5.         Vector3 movingStep = direction.normalized * speed * Time.deltaTime;
    6.         Debug.Log("movingStep=" + movingStep);
    7.         rb.AddRelativeForce(movingStep, ForceMode.Force);
    _HitTargetGO has IsKinemaic unchecked, drag of 0 and angle drag .05, mass of 1, no consraints and its not moving at all
    the debug shows me its applying a force of -14,0,12 which is pretty much what i'm expecting so i think the math is correct

    any idea what i could be missing? thanks
     
  2. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,776
    Try force Mode.Impulse.
    Or try see what happen, if you set force to 100 or even 1000?
     
  3. steveh2112

    steveh2112

    Joined:
    Aug 30, 2015
    Posts:
    314
    well i think i should have been using ForceMode.Force or Impulse only once at the start of the move, not continuously.

    anyhow, i did try bigger numbers and it kind of worked except the object didn't always move towards me, i think because of interaction with some colliders its sitting on.

    i have a rope pull animation what is supposed to move something closer about an arms length each pull, so i switched to setting position of the target explicit and using Vector3 MoveTowards to do the math

    its kind of working but not taking into account the mass of the object yet, but i can add that
     
  4. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    Try simply using AddForce instead of AddRelativeForce. You're calculating the direction in world coordinates, but AddRelativeForce expects a direction in the object's local coordinates, which depend on the object's orientation.
     
  5. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    Oh! And remove Time.deltaTime from the calculation. That's surely why your code seems to do nothing. Forces, velocities and impulses are time-independent magnitudes.

    Bonus: ForceMode.Force is the default value, so you may omit it and simply call rb.AddForce(movingStep).
     
    steveh2112 likes this.
  6. steveh2112

    steveh2112

    Joined:
    Aug 30, 2015
    Posts:
    314
    thanks to all, i think i have it working now. i moved my pull code to the animation callback so its timed with the actual pulling part of the animation, then did this
    Code (CSharp):
    1.     override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    2.     {
    3.         if (stateInfo.normalizedTime < .1f || stateInfo.normalizedTime > .6f)
    4.             return;
    5.         if (!_wm._ActiveRope)
    6.             return;
    7.  
    8.         // pulling part of animation
    9.         if (_wm._NewDistancePlayerToHitTarget == 0)
    10.             return;
    11.  
    12.  
    13.         if (_wm._DistancePlayerToHitTarget <= _wm._NewDistancePlayerToHitTarget)
    14.         {
    15.             _wm.ClearNewDistancePlayerToHitTarget(); // got there so stop moving
    16.             return;
    17.         }
    18.  
    19.         float distanceRemaining = _wm._DistancePlayerToHitTarget - _wm._NewDistancePlayerToHitTarget;
    20.         Debug.Log("PullRopeSMB distanceRemaining=" + distanceRemaining);
    21.  
    22.         Rigidbody rb = _wm._HitTargetGO.transform.GetComponent<Rigidbody>();
    23.  
    24.         const float speed = 60f;
    25.         Vector3 direction = animator.transform.position - _wm._HitTargetGO.transform.position;
    26.         Vector3 movingStep = direction.normalized * speed;
    27.         Debug.Log("ullRopeSMB movingStep=" + movingStep);
    28.         rb.AddForce(movingStep, ForceMode.Impulse);
    29.     }
    seems to work on simple objects, yet to try on things that have joints
     
    Last edited: Jan 24, 2020
  7. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    Just a heads up: it seems like OnStateUpdate is called on every visual frame, not physics frame. While the visual frames per second can vary, the physics frames per second are held constant. This is why you should add torques and forces always in FixedUpdate().

    Otherwise you'll get a much stronger physical effect if you game runs with a higher frame rate and a weaker effect if the scene becomes more complex.
     
    Edy likes this.
  8. steveh2112

    steveh2112

    Joined:
    Aug 30, 2015
    Posts:
    314
    physics frames per second are held constant? are you saying that FixedUpdate rate is a constant, not related to frame rate?
     
  9. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    steveh2112 likes this.
  10. steveh2112

    steveh2112

    Joined:
    Aug 30, 2015
    Posts:
    314
    thanks for mentioning that, didn't realize, very good to know.
    so for the animation state machine to do it in FixedUpdate guess i'll have to set a persistent bool someplace like the player controller script and read the bool in its FixedUpdate
     
  11. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    steveh2112 likes this.