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