- Home /
Smooth rigidbody movement
Hi Unity Community,
I have written a script to move an object via ray cast to positions on a terrain, however I can’t for the life of me seem to make this movement smooth. I have tried all manner of things trying to figure this out (as you can probably tell by the amount of commented-out code below); disabling various rigidbody variables, however to no avail.
One approach that (kind of) worked was disabling the collider attached to the object, however this lead to the object inadvertently sinking below the terrain.
Can anyone please advise me as to the best approach to go about this would be? I feel like this should be very simple but I am over complicating it.
Many thanks in advance, Ryan
//Move
if ( Input.GetKey(KeyCode.E))
{
// if (Input.GetKeyDown(KeyCode.E))
// {
// modObj.GetComponent(BoxCollider).enabled = false;
initPos = modObj.transform.position;
var initRotation = modObj.transform.rotation;
// }
//
// modObj.GetComponent(Rigidbody).isKinematic = true;
// modObj.GetComponent(Rigidbody).useGravity = false;
moveObject(modObj, initPos, initRotation);
}
else{
// modObj.GetComponent(BoxCollider).enabled = true;
// modObj.GetComponent(Rigidbody).isKinematic = false;
// modObj.GetComponent(Rigidbody).useGravity = true;
}
function moveObject(modObj : GameObject, initPos : Vector3, initRotation : Quaternion)
{
//Debug.Log("Moving Object");
var hit : RaycastHit;
var foundHit : boolean = false;
foundHit = Physics.Raycast(transform.position, transform.forward, hit);
//Debug.DrawRay(transform.position, transform.forward, Color.blue);
if(foundHit && hit.transform.tag == "Terrain")
{
modifyObjGUIscript.activateMoveDisplay(initPos, hit.point);
// var meshHalfHeight = modObj.GetComponent.<MeshRenderer>().bounds.size.y /2; //helps account for large and small objects
modObj.transform.position = hit.point; //***method 01***
// modObj.transform.position = Vector3.Lerp(initPos, hit.point, speed); //***method 02***
// modObj.transform.position = Vector3.SmoothDamp(initPos, hit.point, velocity, smoothTime); //***method 02***
// modObj.transform.position.y = modObj.transform.position.y + meshHalfHeight + hoverHeight;
modObj.transform.rotation = initRotation;
}
}
have you tried to move the gameobject via the rigidbody component? You shouldn't move a gameobject via its transform if you have a rigidbody attached to it
Hi @$$anonymous$$lockrent, I have made the changes you suggested to use rigidbody position (see code below); I think this made the movement smoother but it is still 'juddering' quite a bit - any further suggestions?
//$$anonymous$$ove
if ( Input.Get$$anonymous$$ey($$anonymous$$eyCode.E))
{
if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.E))
{
modObj.GetComponent(BoxCollider).enabled = false;
initPos = modObj.transform.position;
var initRotation = modObj.transform.rotation;
}
// modObj.GetComponent(Rigidbody).is$$anonymous$$inematic = true;
modObj.GetComponent(Rigidbody).useGravity = false;
modObj.GetComponent(Rigidbody).freezeRotation = true; //***NEW***
moveObject(modObj, initPos, initRotation);
}
if (Input.Get$$anonymous$$eyUp($$anonymous$$eyCode.E)){
// Debug.Log("E $$anonymous$$ey is up");
modObj.GetComponent(BoxCollider).enabled = true;
// modObj.GetComponent(Rigidbody).is$$anonymous$$inematic = false;
modObj.GetComponent(Rigidbody).useGravity = true;
}
function moveObject(modObj : GameObject, initPos : Vector3, initRotation : Quaternion)
{
//Debug.Log("$$anonymous$$oving Object");
var hit : RaycastHit;
var foundHit : boolean = false;
foundHit = Physics.Raycast(transform.position, transform.forward, hit);
//Debug.DrawRay(transform.position, transform.forward, Color.blue);
if(foundHit && hit.transform.tag == "Terrain")
{
modifyObjGUIscript.activate$$anonymous$$oveDisplay(initPos, hit.point);
var meshHalfHeight = modObj.GetComponent.<$$anonymous$$eshRenderer>().bounds.size.y /2; //helps account for large and small objects
// modObj.transform.position = hit.point; //***method 01***
// modObj.transform.position = Vector3.Lerp(initPos, hit.point, speed); //***method 02***
// modObj.transform.position = Vector3.SmoothDamp(initPos, hit.point, velocity, smoothTime); //***method 03***
// modObj.transform.position.y = modObj.transform.position.y + meshHalfHeight + hoverHeight;
// modObj.transform.rotation = initRotation;
var movRb = modObj.GetComponent.<Rigidbody>(); //***NEW - method 04***
movRb.position = Vector3.Lerp(initPos, hit.point, speed);
// movRb.position.y = modObj.transform.position.y + meshHalfHeight + hoverHeight;
// movRb.rotation = initRotation;
}
}
Try setting interpolate to interpolate or extrapolate on the rigidbody. And make sure you are moving the rigidbody from FixedUpdate and not Update.
Answer by valaskasz · May 19, 2016 at 11:59 AM
use Vector3.Lerp to interpolate between two positions. ex: modObj.transform.position =Vector3.Lerp(modObj.transform.position ,hit.point,Time.deltatime*smootValue)
Hi @ valaskasz, thanks for your response; have tried this in the code above modObj.transform.position = Vector3.Lerp(initPos, hit.point, speed); //***method 02***
however the 'juddering' issue persists.
Any other ideas?
Answer by MuratKul · May 20, 2016 at 11:49 AM
Did you tried to decrease fixed timestep? (Project Settings>>Time)