- Home /
Make object tip over
Hi all, wondering how i can make an object standing on its end IE. A Domino fall 'FORWARD' to the objects space and rotation NOT world space..
AddForce does not work as expected and only tips the object according to world space. so if i rotate the object 90 degrees it will not longer fall forward, it will now fall sideways....
my current code is useless and nothing as to what i need...
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo))
{
if (hitInfo.collider.CompareTag("DominoFrontFace"))
{
hitInfo.collider.GetComponentInParent<Rigidbody>().AddForce(transform.position += Vector3.right * forceAmount);
}
if (hitInfo.collider.CompareTag("DominoBackFace"))
{
hitInfo.collider.GetComponentInParent<Rigidbody>().AddForce(transform.position += Vector3.left * forceAmount);
}
}
with this current code as well as pushing the objects in a direction that makes no sense to the current objects rotation, it also always multiplies the force added, meaning each and every time i click on a domino to make it tip over the force gets stronger and stronger and starts throwing the dominos rather than tipping them over.
Video showing what happens, as people are unaware that adding force only goes in one direction according to world space, no matter the rotation of the domino. Youtube Video
I don't know what local space do you mean, this comment is refering to the local space of the object where the script is attached
please try using transform.right
(right in local space) ins$$anonymous$$d the vector3.right
(world space) and also if u use +=
you are changing the transform.position
manually and also adding force... so on line 8 replace
hitInfo.collider.GetComponentInParent<Rigidbody>().AddForce(transform.position += Vector3.right * forceAmount);
by
hitInfo.collider.GetComponentInParent<Rigidbody>().AddForce(transform.position + transform.right * forceAmount);
and also replace line 12 by
hitInfo.collider.GetComponentInParent<Rigidbody>().AddForce(transform.position - transform.right * forceAmount);
I don't know what local space do you mean, this comment is refering to add force on the click direction, without using any local space
you can also addforce making a impulse to the direction to you see from the camera, I think this isnt the result you want to archieve, because the camera may not be pointing directly at target and you still want a "right" impulse
so again on line 8 replace by
hitInfo.collider.GetComponentInParent().AddForce(hitInfo.point + ray.direction * forceAmount);
on line 12 replace by the same code, you dont need know how is the piece oriented here, just its position relative to the camera
I don't know what local space do you mean, this comment is refering to the local space of the transform piece, so the parent of the collider u point
I think this is the result you want to archieve, cause check the left or right to the piece without care of camera orientation, just if you are pointing the correct face
so, again replace line 8 by
hitInfo.collider.GetComponentInParent().AddForce(hitInfo.collider.position + hitInfo.collider.parent.right * forceAmount);
and line 12 by
hitInfo.collider.GetComponentInParent().AddForce(hitInfo.collider.position - hitInfo.collider.parent.right * forceAmount);
last some more (cosmetic) modifications
to evade problems with mistake + with += (the problem that increases force added each time) use specific functions, on this case is AddForceAtPosition
u use the code hitInfo.collider.GetComponentInParent<Rigidbody>()
because its almost impossible u click two sides at the same time, doesnt cause computation problems, bu just to not repeat code can create a
Rigidbody piece = hitInfo.collider.GetComponentInParent<Rigidbody>();
and use it inside the ifs
This worked perfectly, thank you so much, i did make a prior post about this but seemed to be leading people in the wrong direction, I think that's where i got really confused.
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo))
{
if (hitInfo.collider.CompareTag("Do$$anonymous$$oFrontFace"))
{
hitInfo.collider.GetComponentInParent<Rigidbody>().AddForce(hitInfo.collider.transform.position - hitInfo.collider.transform.parent.forward * forceAmount);
}
if (hitInfo.collider.CompareTag("Do$$anonymous$$oBackFace"))
{
hitInfo.collider.GetComponentInParent<Rigidbody>().AddForce(hitInfo.collider.transform.position + hitInfo.collider.transform.parent.forward * forceAmount);
}
}
Answer by unity_DKqnJkGo8MOKYQ · Jan 20, 2019 at 06:17 PM
AddForce( pos + dir )
makes no sense. AddForce takes a direction, not a position.
The call you want does use world coordinates, but lets you define where on the rigidbody to apply the force: AddForceAtPosition( force, position ).
To always have the domino fall forward in localspace, you can just use the domino's local transformation: body.AddForceAtPosition( body.rotation * Vector3.forward, hitinfo.point );
[1]: https://docs.unity3d.com/ScriptReference/Rigidbody.AddRelativeForce.html
or just keep using raycast info and apply on point where the ray collide
body.AddForceAtPosition(ray.direction, hitInfo.point);
he have to add a collider (cube probably) at the piece gameobject (the parent of the faces) and delete the faces if isn't useful anymore,
also physics, correct me if I'am wrong but the angular force is (approximated by) the vector to the force ( Vector3.right * forceAmount
) plus the vector distance to the relative center... relative to te point of refecence however I still recommed use the AddForceAtPosition