- Home /
[C#] Recreating object A's velocity relative to object B
Hi, My code is currently duplicating an object on collision, creating the duplicate at the same relative coordinates on a duplicate of the original object and then attempting to recreate the impactor's velocity.
Everything works fine up until the velocity part.
Ideally I'd like to add the right force to recreate the objects velocity at point of impact. Failing that I'd like to just give it the same amount of force along it's forward axis (which mean glancing impacts would not work quite as expected, but that may be fine)
I've tried using RotateTowards and various other approaches, but its possible something more basic is missing from my understanding so I'll just defer to you guys.
I also understand setting the velocity directly is bad (because it bypasses the physics engine, which I am relying on) if that's not the case, it may help simplify matters.
Note: This is all done without gravity. The basic idea is that when the main player item gets hit it should also provide the same collision on a cloned version of the player ship that is too complicated to move around in the physics engine (long story).
The impacts on this second, cloned object are then used in other areas of the code.
TL DR Main Question: How can I correctly calculate the force to add to an object to make it match the velocity (direction and magnitude) of its predecessor, relative to the original Object A?
Bonus Question: How is it best to calculate the force I need to add to match a given velocity?
Here's what I have so far, I've highlighted the broken part.
public void OnCollisionEnter(Collision collision) {
// Recreate collision for duplicate object
Vector3 newLocation = collision.contacts[0].point;
newLocation = transform.InverseTransformPoint(newLocation);
// where impact would have occured on the second object
Vector3 impactLocation = deformer.transform.TransformPoint(newLocation);
// Slightly behind collision point so doesn't contact collider before force can be added
newLocation = newLocation + (collision.transform.forward * -3);
newLocation = deformer.transform.TransformPoint(newLocation);
// Duplicate the impactor
GameObject duplicate = Instantiate(
collision.gameObject,
newLocation,
Quaternion.LookRotation(impactLocation - newLocation)) as GameObject;
// Get the relative direction to send the duplicate impactor
// WHEN I ADD THIS AS AS A FORCE IT GOES IN WRONG DIRECTION //
Vector3 newDirection =
deformer.transform.TransformPoint(
collision.rigidbody.velocity - collision.collider.rigidbody.velocity);
// float force = collision.rigidbody.velocity.magnitude * collision.rigidbody.mass;
duplicate.rigidbody.mass = collision.rigidbody.mass;
duplicate.rigidbody.angularVelocity = collision.rigidbody.angularVelocity;
// IS THERE A BETTER WAY TO ACHIEVE THIS? //
duplicate.rigidbody.AddForce(newDirection, ForceMode.VelocityChange);
}
its bad to do because it isn't realistic to assign velocity.
You can make an object go from 200mph to 0mph without going 100mph in between just 200 then 0
However if you want to clone something and you don't want the player to realize a new object entered and everything. If what you want is an object to pop into existence at 200mph go ahead.
So yea modify the velocity directly. Just don't do it normally.
the user wont be aware of any of this, the hole Object B and duplicated object are going to be hidden from them. Be that as it may, I still don't know how to correctly modify the original velocity to be compensated for the change in global location and rotation.
wait a $$anonymous$$ute are you trying to like make it so when an object hits another object it reflects off but takes into account the speed it was going or what?
So I had, in theory, gone through the same mental process you described, I just was adding a step of saying "now make that global vector local relative to the other object". But using AddRelativeForce seems to remove that need. Annoying that I was so close! Thanks dude.
FYI the "newDirection" code in the orignial post seems to work fine. Object A could be at any rotation when the impact happens, but its clone will always be static. Does that make sense? Anyway, THAN$$anonymous$$S!
Any chance you could make that last comment a new answer, then I'll tick it?
Answer by sparkzbarca · Jul 09, 2013 at 04:15 PM
anyways if you want to basically be able to "rotate" an object but have it keep its velocity you want to take the velocity. get the local velocity not global so first we want to take velocity which is global and convert to local. Then take and add force locally not globally.
So were going to use transformdirection not position because we don't want to consider scale. We are doing a direction not a position.
Vector3 CurrentLocalVelocity = this.transform.transformDirection(this.rigidbody.velocity);
Thats it we have how much were moving towards the objects up, how much towards the objects forward and how much toward the objects right.
Now add that to the new object but do so relative to it.
//assuming the objects force is currently 0
NewObject.rigidbody.AddRelativeForce(CurrentLocalVelocity);