- Home /
cubes fall through floor
In my game the player has to position some cubes above slots (other cubes). These slots are placed on a plane. The player can grab the cubes with the mouse and move them around. If he releases the cubes, the cube checks if it is above a slot, and if so, the cube is normalized to the coordinates of the slot, to fit it perfectly. That usually works, but sometimes the cubes fall through the slot and the floor and I sometimes get an error on the hit collider object.
I post my release cube code. Maybe some has an idea. (The is mostly a bunch of cubes connected, that the player moves around. Usually it happens with more cubes connected)
var hit : RaycastHit; //Saves the hitted object
function OnMouseUp()
{
ReleaseRightCube();
ReleaseLeftCube();
ReleaseCube();
}
function ReleaseCube()
{
gameObject.renderer.material.color = originalCubeColor; //reassign original Color after dropping the Object
aboveSlot = false;
transform.position.y = 2;//cube lifted by 2, falling down by physics
GetSlot();
if(hit.collider.gameObject) //check if on a slot
{
if(hit.collider.gameObject.tag =="slot") //Still above a slot?
{
aboveSlot = true;
transform.position.x = hit.collider.gameObject.transform.position.x; //normalize Cube to center of the slot
transform.position.z = hit.collider.gameObject.transform.position.z;
}
}
}
function ReleaseLeftCube()
{
if(connectedCubeLeft)
{
connectedCubeLeft.GetComponent.<MovableCubeScript>().ReleaseCube();
connectedCubeLeft.GetComponent.<MovableCubeScript>().ReleaseLeftCube();
}
}
function GetSlot()
{
var ray = new Ray(transform.position, (-transform.up)); //check object under the cube
Physics.Raycast (ray, hit, 10.0);
}
I try to get one, but there is not always an error sometimes they just fall through
Error message:
NullReferenceException: Object reference not set to an instance of an object
on:
if(hit.collider.gameObject) //check if on a slot
(but not always)
add before if:
Debug.Log(hit); Debug.Log(hit.collider); Debug.Log(hit.collider.gameObject);
and try to raise error again
Well my two cents on the problem would be that hit is null, the Physic.Raycast don't actually hit something.
When using Physic.Raycast, you should ALWAYS test for it's return:
if(Physics.Raycast(ray, hit, 10))
{
//do something with hit
}
This way you avoid working with uninitialized variables (and even don't do computation that shouldn't be done).
And use the $$anonymous$$ovePosition even to move the cube in it's "y" component.
But the simpler would be that when the cube is grabbed you set it's rigidbody to "is$$anonymous$$inematic"
rigidbody.is$$anonymous$$inematic = true;
That would allow you to move it like you do, throught transform, without any problem. If your cube are then snap, let it kinematic it doesn't matter. If your player drop it, and you want the cube to be afected by physic again, just switch "is$$anonymous$$inematic" back to "true"
Answer by Sirithang · Jul 31, 2012 at 03:11 PM
Well if cubes are "snaped" to the slot, maybe just deactivate the rigidbody (rigidbody.active = false or rigidbody.isKinematic = true), as it won't move again.
If you still want the cube to be affected by gravity, try to position it with rigidbody.MovePosition instead of moving it with transform.position (the physic engine don't run as the same "speed" than the game, so your modification can be "ignored")
But yeah it can also come from an exception (the error message you got, like you try to grab GetComponent(), but there isn't one things like that...), so would be nice to have it, if you can post it.
Thank you for your answer. the cube is only moved to the x,z coordinates of the slot and falls down on its own. I will try the rigidbody movement - maybe i have to learn more about the different between transform and rigidbody movement. I haven't seen the error message for a long time - maybe I fixed that one - but the main problem still occurs without any error message. The message pointed at:
if(hit.collider.gameObject) //check if on a slot
and said no object found or something like that. (which schould be imposible because it should either hit the slot or the plane)
It seems as if the cube gets a completely wrong y value (negative one, so it is under the plane)the moment I release it. Don't know why.
Answer by Sundar · Aug 02, 2012 at 09:57 PM
You need to adjust settings in PhysicsManager.
Edit - Project Settings - Physics
Where you adjust "Sleep velocity", "Sleep Angular velocity" and "Min. penetration for Penalty" until your cube falls and stays on the plane
I tried something with these parameters and it did help a little bit, but not at all. I think now I know a little bit about the reason when this happens: If I grab the cube and move it around, the y value is always set to 2. If I hold the cube grabbed but do not use the mouse, i recognice a slow falldown of the cube. If I release it after a while, it falls through. increasing the sleep velocity a little, reduced the problem, I had to wait longer until the cube fell through. maybe I have to deactivate the gravity for the cube while I move it around? Is this possible and does it help?
Ok I deactivated gravity while moving the cube with the mouse - that seems to work until now ...
If you are happy with it go for it, another suggestion though is to tweak gravity value in Physics$$anonymous$$anager to see whether you are getting desired effect. Default is -9.81. Thanks for the vote.
Answer by fschaar · Aug 01, 2012 at 11:27 AM
ok, now i've made the slots and the plane rigidbodys to and deactivated gravity and kinematics, so it stayes where it is (does that make sense or did I destoy the whole purpose of rigidbody by doing this?) Still I cant drop the cubes on the slots. If I drop them, they are dropped to the nearest position next to the slot???
That's how the code looks now:
function ReleaseCube()
{
var newPosition = Vector3(0,2,0); //cube lifted by 2, falling down by physics
gameObject.renderer.material.color = originalCubeColor; //reassign original Color after dropping the Object
aboveSlot = false;
isMoving = false;
var ray = new Ray(transform.position, (-transform.up)); //check object under the cube
if(Physics.Raycast (ray, hit, 10.0)) //check if on a slot
{
if(hit.collider.gameObject.tag =="slot") //Still above a slot?
{
aboveSlot = true;
//constrain Cube to center of the slot
rigidbody.MovePosition(Vector3(hit.collider.gameObject.rigidbody.position.x,2,hit.collider.gameObject.rigidbody.position.y));
}
else
rigidbody.MovePosition(rigidbody.position+ newPosition);
}
else
rigidbody.MovePosition(rigidbody.position+ newPosition);
}
Answer by fschaar · Aug 02, 2012 at 08:15 PM
Now it occured in some tests, that the cubes fall through the plane sometimes even when I create and place them. I create the cube from a prefab and then place the at random positions over the plane. I used translate.position to arrange them - i fixed that to rigidbody Movement, but the error remains. It also seems to happen more often on faster computers. When I'm using my computer at work (old windows core2 duo) I can hardly reproduce the error. On my 1 year old MacBook Air at home it happens quite often.
My guess at this point is, that it has something to do with the speed and at some point there is a gap between the frames, where the objects dont collide. Or- on the other hand thy collide while being created and fly around out of control.
But when I pause the game an manipulate the position of the cubes that fell through on the fly (put their coordinates back over the plane) they still fell through. They seem to have an enormous speed already.
Any suggestions?
Thanks in advance
Answer by Meltdown · Aug 03, 2012 at 09:50 AM
Don't use planes. They are known to have collision issues with moving objects.
Change your floor to a cube with a box collider. You can also increase the overall scale of your project objects if you continue to have problems.
Your answer
Follow this Question
Related Questions
Recursive Raycast Spatial Search 0 Answers
Shooting system not working 1 Answer
How do I load a scence upon clicking on and object? 1 Answer