(06-04-2023, 05:31 PM)mikecochang Wrote: The problem with Rigidbody.AddForce is that the object will never remain still because it'll bounce back and forth to the target position when grabbed.
Why would it? it entirely depends on how you calculate the force, if you just add a force towards a point it will of course overshoot when you're very close to the point (bouncing back and forth around it). Typically you want a force that's:
- Proportional to the distance between the object and the target point. (F = - strength * distance). Intuitively, if you're far way from the target position, move faster towards it.
- Proportional to the velocity towards the target point. (F = - damping * velocity). Intuitively, if you're approaching the target position too fast, slow down a little bit.
Both these conditions lead you to a common damped spring: F = - k*x - d*v
If you don't want the results to depend on the mass of the object, just divide by mass to turn the force into an acceleration, or use ForceMode.Acceleration. Here's a very simple example script that does this:
Code:
using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
public class MoveTowardsAccel : MonoBehaviour
{
public Transform target;
public float strength = 2000;
public float damping = 50;
private Rigidbody rb;
private void Awake()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
var dist = transform.position - target.position;
rb.AddForce(-dist * strength - rb.velocity * damping, ForceMode.Acceleration);
}
}
Here's a video of the result: as you can see there's zero overshoot and the rigidbody sphere follows the transform exactly, using AddForce:
(06-04-2023, 05:31 PM)mikecochang Wrote: Changing the velocity directly allows me to have a better control of this rigidbody.
There's absolutely no difference between using AddForce and modifying velocity directly, since AddForce is just a shortcut to modifying the velocity (in slightly different ways depending on the ForceMode used). According to the
manual:
Code:
velocity += input/rigidbody.mass * Time.fixedDeltaTime; // ForceMode.Force
velocity += input * Time.fixedDeltaTime; // ForceMode.Acceleration
velocity += input/rigidbody.mass; //ForceMode.Impulse
velocity += input; //ForceMode.VelocityChange
(06-04-2023, 05:31 PM)mikecochang Wrote: I have implemented my own tension system for these interactable objects so it'll stop any grabs when max tension is reached. But I'm wondering if ropes can set a max distance like how IK doesn't stretch the arms beyond its limits.
Sounds to me like you're
really overcomplicating things: ropes already have their own tension system, and already have a max distance like IK, in fact they can be understood as a dynamic version of FABRIK (forward and backward reaching IK, a specific type of IK constraint). Take momentum out of a rope simulation, and you've got an IK chain.
A rope is just a sequence of points in space, held together by distance constraints. Once points are spread apart further than a given distance, they're brought back together just like in IK: the only differences with an IK system are that points have momentum, and that constraint adjustments are applied using forces (actually, impulses) instead of directly setting their position.
Because of this, it is not possible to adjust the position of an object unless an impulse can be applied to it, same as in any physics engine: eg. you can't have a physics-driven box push a character around unless it's endowed with velocity, mass, momentum, etc. In Unity this is done by adding a Rigidbody component.
kind regards,