0
\$\begingroup\$

First GO moves by transform.translate (necessary).

Second GO needs to move by physics.

If I do rb.MovePosition on the 2nd GO like:

 private void FixedUpdate()
    {
        rb.MovePosition(targetTransform.position);
        rb.MoveRotation(targetTransform.rotation);
    }

then it stutters and blinks around crazily, even if I turn on Interpolate.

If I do

 rb.AddForce(targetTransform.transform.position - this.transform.position, ForceMode.Acceleration);

it moves smoothly and does interact properly physics-wise BUT orbits around the original GO's position rather than perfectly copying it.

If I do:

// Calculate your desired position however you like.
    Vector3 desiredPosition = targetTransform.position;

    // What velocity gets us there in one timestep?
    Vector3 desiredVelocity = (desiredPosition - transform.position) / Time.deltaTime;


    // Apply a sufficient impulse to hit reach that velocity.
    rb.AddForce(desiredVelocity - rb.velocity, ForceMode.VelocityChange);

then it DOES copy the original GO's position but then annoyingly clips right through other rigidbodies as if moving by transform.translate.

What is the perfect secret sauce to making a GO copy another GO's position, but respond to Physics properly? Namely, it needs to actually be stopped when colliding with a Rigidbody that has frozen position+rotation.

\$\endgroup\$
3
  • \$\begingroup\$ I've had good luck with the bottom one as long as the velocity is kept small enough that the follower doesn't tunnel through an obstacle in a single time step. Clamping the velocity or displacement, thickening your obstacles, or using continuous dynamic collision detection on this object can help reduce tunnelling. \$\endgroup\$ – DMGregory Jan 23 at 13:40
  • \$\begingroup\$ Thank you! Changing the last line to rb.AddForce( (desiredVelocity - rb.velocity)/5f , ForceMode.VelocityChange); made it so it interacted with things correctly. Very glad to see it can work as desired. I appreciate it very much. \$\endgroup\$ – nightfarrow Jan 25 at 1:49
  • \$\begingroup\$ Want to add that as an Answer below? \$\endgroup\$ – DMGregory Jan 25 at 2:15
1
\$\begingroup\$

The code:

// Calculate your desired position however you like.
Vector3 desiredPosition = targetTransform.position;

// What velocity gets us there in one timestep?
Vector3 desiredVelocity = (desiredPosition - transform.position) / Time.deltaTime;


// Apply a sufficient impulse to hit reach that velocity.
rb.AddForce(desiredVelocity - rb.velocity, ForceMode.VelocityChange);

works to make one GameObject copy another GameObject's position and react to physics.

However, if the velocity is too high then it can still cause wonky physics, so in my case changing the last line to

rb.AddForce(   (desiredVelocity - rb.velocity)/5f , ForceMode.VelocityChange);

made it work with physics consistently. :)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.