- Home /
How to fix/clamp rigidbody dir vector, despite Force dir
I wish to bind a rigidbody to move only along a fixed vector between two points, despite any forces that may be acting on it.
I understand in Maths how to apply the x,y components of a Force to find the resultant on a mass in its direction but I can't find a way to bind the rigidbody to the fixed vector and prevent it from veering off course, but still respond to the components of physics in its direction.
Imagine a cube with a hole sliding along a pole fixed in space. You can apply a force in any direction you like but the pole fixes movement along one vector and so only the force components in the direction of the vector will produce a movement.
Creating that imaginary pole and fixing the vector is what I'm having the problem with. I require non-K rigidbody so the cube is influenced by a changing gravity.
Edit:
(Could I achieve this with var Properties?)
basically, just use AddRelativeForce
if it's fixed to the "pole" though, you probably could fake the changing gravity very easily either way...
it may help to freeze rotation too..
EDIT:
as in:
rigidbody.AddRelativeForce(amount,0,0);
How I would do it:
don't allow any actual collision to the cube, just child an empty object with a box collider to it, and put the main box on a separate collision layer, to serve as a collider for the impact detection.. and child the box to the pole. that should work I think.
Hi Seth, thanks for your swift reply! I will try the parenting and layering and see how it works for me.
I am currently using :
rigid.AddRelativeForce(Vector3.up*resultForce.magnitude*gravDot);
cube is spawned in direction that Vector3.up follows the vector.
where :
gravDot = Vector3.Dot(startVector.normalized, Physics.gravity.normalized);
gravX = Physics.gravity.x * gravDot;
gravY = Physics.gravity.y * gravDot; ETC
resultForce = Vector3(gravX,gravY,gravZ);
I have frozen all rotations and z plane.
The rigidbody behaves well under the gravity, however when it collides with something else (a floor), the physics engine makes it move in a resultant in x,y and veer from the vector. The biggest culprit is the bounce factor, which I can't seem to eli$$anonymous$$ate without messing up my cube gravity response.
I am trying to eli$$anonymous$$ate this veering and ins$$anonymous$$d calculate the component influence within the vector of whichever force causes the veering. Hope I make sense!
If you're still having issues with bounciness, you need to go into the physics manager (open the physics material on your cube) and change the 'bounciness' to 0.
I believe the bounce is the percent of how much of its original height it will bounce again, so .75 would slowly bounce less and less.
Have you tried using Clamp$$anonymous$$agnitude? http://docs.unity3d.com/Documentation/ScriptReference/Vector3.Clamp$$anonymous$$agnitude.html
Answer by meat5000 · Sep 03, 2013 at 12:24 AM
So this worked for me. This script is on a non-K rigidbody with collider and 'Use Gravity' OFF. I am changing Physics.Gravity with another script but this object only moves in its local Up/Down direction under the influence of the component of Gravity that is acting in that direction Vector. When the object lands on its cylindrical floor or concave ceiling it normally tends to bounce and slide off vector but this script calculates the displacement in Local X axis and adds a force in World Space to correct the displacement.
Blocks are now all aligning wonderfully in my game. I know this can be condensed but it really helps to see what you can do. (Plus tried a load of stuff that just didn't work). Also, it didn't touch the fps even with loads of objects.
//
#pragma strict
var ImpulseCollisionMax : float = 10.0;
var snapFactor : float = 2.0;
var startVector : Vector3;
var spawnAngle : float = 0.0;
private var rigid : Rigidbody;
private var gravDot : float = 0.0;
private var gravX : float = 0.0;
private var gravY : float = 0.0;
private var gravZ : float = 0.0;
private var resultForce : Vector3;
private var startTrans : Transform;
private var startLocalPos : Vector3;
private var localPosition : Vector3;
private var blockRelativeXDiff : float = 0.0;
private var blockDiffVector : Vector3;
function Start ()
{
startTrans = transform;
startLocalPos = transform.InverseTransformDirection(startTrans.position);
rigid.useConeFriction = true;
startVector = Vector3(transform.position.x, transform.position.y, 0);
spawnAngle = Mathf.Atan2(startVector.x, startVector.y) * Mathf.Rad2Deg;
}
function FixedUpdate ()
{
localPosition = transform.InverseTransformDirection(transform.position);
blockRelativeXDiff = localPosition.x - startLocalPos.x;
blockDiffVector = startTrans.TransformDirection (blockRelativeXDiff, 0, 0);
if (blockRelativeXDiff != 0)
{
rigid.AddForce(-blockDiffVector*snapFactor);
}
gravDot = Vector3.Dot(startVector.normalized, Physics.gravity.normalized);
gravX = Physics.gravity.x * gravDot;
gravY = Physics.gravity.y * gravDot;
gravZ = 0;//Physics.gravity.z * gravDot;
resultForce = Vector3(gravX,gravY,gravZ);
rigid.AddRelativeForce (Vector3.up * resultForce.magnitude * gravDot, ForceMode.Acceleration);
}
function OnCollisionEnter(Land : Collision)
{
rigid.velocity = Vector3(0,0,0);
}
I'm sorry I couldn't help much. Looking at the code, it seems you know some complex math, eh?
Yeah, I looked through. I still couldn't quite understand your game mechanics for some reason. I mean the reason to restrain the movement in such a way. But that's probably because it's really original.
I have a new question, by the way, would you be kind enough to check it out?