AddRelativeForce not doing anything

i am trying to move an object towards the player using this code in the players FixedUpdate

// move _HitTargetGO towards player a bit
        const float speed = 1000f;
        Rigidbody rb = _HitTargetGO.transform.GetComponent<Rigidbody>();
        Vector3 direction = transform.position - _HitTargetGO.transform.position;
        Vector3 movingStep = direction.normalized * speed * Time.deltaTime;
        Debug.Log("movingStep=" + movingStep);
        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

Try force Mode.Impulse.
Or try see what happen, if you set force to 100 or even 1000?

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

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.

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).

1 Like

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

    override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        if (stateInfo.normalizedTime < .1f || stateInfo.normalizedTime > .6f)
            return;
        if (!_wm._ActiveRope)
            return;

        // pulling part of animation
        if (_wm._NewDistancePlayerToHitTarget == 0)
            return;


        if (_wm._DistancePlayerToHitTarget <= _wm._NewDistancePlayerToHitTarget)
        {
            _wm.ClearNewDistancePlayerToHitTarget(); // got there so stop moving
            return;
        }

        float distanceRemaining = _wm._DistancePlayerToHitTarget - _wm._NewDistancePlayerToHitTarget;
        Debug.Log("PullRopeSMB distanceRemaining=" + distanceRemaining);

        Rigidbody rb = _wm._HitTargetGO.transform.GetComponent<Rigidbody>();

        const float speed = 60f;
        Vector3 direction = animator.transform.position - _wm._HitTargetGO.transform.position;
        Vector3 movingStep = direction.normalized * speed;
        Debug.Log("ullRopeSMB movingStep=" + movingStep);
        rb.AddForce(movingStep, ForceMode.Impulse);
    }

seems to work on simple objects, yet to try on things that have joints

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.

1 Like

physics frames per second are held constant? are you saying that FixedUpdate rate is a constant, not related to frame rate?

Absolutely.
From https://docs.unity3d.com/ScriptReference/MonoBehaviour.FixedUpdate.html:

MonoBehaviour.FixedUpdate has the frequency of the physics system; it is called every fixed frame-rate frame. Compute Physics system calculations after FixedUpdate. 0.02 seconds (50 calls per second) is the default time between calls.

RTFM :slight_smile:

1 Like

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

You may also find interesting this quick guide on when to use Update and FixedUpdate, and why:

1 Like