In my project, I have some objects that move at a fairly high velocity. So, more often than not, those objects pass right through level geometry without even registering a collision. I put together a script to try and stop the problem but it still occurs. Any suggestions?
private var newPos : Vector3;
private var oldPos : Vector3;
private var hasHit;
function Start()
{
newPos = transform.position;
oldPos = newPos;
hasHit = false;
}
function Update()
{
if(hasHit)
return;
newPos = oldPos + rigidbody.velocity;
// Check if we hit anything on the way
var direction = newPos - oldPos;
var distance = direction.magnitude;
if (distance > 0)
{
var hit : RaycastHit;
if (Physics.Raycast(oldPos, direction, hit, distance))
{
// adjust new position
newPos = hit.point;
// notify hit
hasHit = true;
}
}
oldPos = transform.position;
}
Also, I’ve tried the script on the wiki, but that didn’t work.
Make sure the ray isn’t colliding with “its” own collider (the collider of the object to which this script is attached. I was working on the same issue and had the same problem. When I used a mask to exclude the projectile, it worked.
If you want to test for that issue before making that change, just check the distance of the ray. If it is hitting its own collider, it’ll be very small.
Ah. That seems as though it is the problem. The raycast distance is very small. What do you mean by masking? Like putting the ball of a different layer?
Now the raycast length is changing, but the ball doesn’t actually stop. And after looking over the script, I realized that I never actually change the position of the moving object. I don’t really know where to go from here.
Does anyone with a working script feel like sharing how they got fast moving objects to stop moving through other meshes?
You probably want to change the rigidbody.velocity and not only the position.
Most likely setting the velocity to zero. Also your script will of course only ever stop once. I’d also put in a check where the raycast is only performed if the rigidbody velocity exceeds a certain size, otherwise you will get strange behaviour when the collider is moving slowly.
Alright, just a little update so far. This is what I have and it sort of works. The object doesn’t usually go through the mesh but there are a few problems. The object usually just magically teleports a fair distance from its current position and attaches itself to a mesh. Also sometimes it hit the mesh and then slides down the mesh.
private var newPos : Vector3;
private var oldPos : Vector3;
private var hasHit = false;
function Update()
{
if(hasHit)
return;
oldPos = transform.position;
newPos = oldPos + rigidbody.velocity;
// Check if we hit anything on the way
var direction = newPos - oldPos;
var distance = direction.magnitude;
if (distance > 0 rigidbody.velocity.magnitude > 30.0)
{
var hit : RaycastHit;
if (Physics.Raycast(oldPos, direction, hit, distance))
{
// adjust position
transform.position = hit.point;
rigidbody.velocity = Vector3(0,0,0);
// notify hit
hasHit = true;
Debug.Log(hit.distance);
}
}
}
Hi,
Not entirely sure what the problem is, but as far as the object sliding off the mesh: Is it possible that setting the rigidbody to not use gravity would help?(rigidbody.useGravity = false;).
I was searching the board for a solution to the high velocity collision problem as well. I was wondering if you ever found a good solution to this or modified your script any more.
You mentioned a script in the wiki for this but all I could find was http://www.unifycommunity.com/wiki/index.php?title=Calculating_Lead_For_Projectiles, which seems to require a target. All I’m really interested in at this point is detecting a collision EVERY time when the rigid body hits the collision mesh on the background, not a particular target.
Is the mesh you are using a thin “skin” for terrain, say, or does it form an enclosed, solid object? Generally, the physics can tell if something has moved inside the volume of a solid object and apply the appropriate collision force. However, it is not quite the same with a mesh that is a thin skin - a colliding object can easily pass from one side to the other without the two colliders actually making contact.
Is it possible for you to make the troublesome colliders into enclosed volumes? Say, thin box colliders for flat surfaces and enclosed meshes rather than thin skins?
I’m having the most problems with the background collision mesh, which would fall into the thin skin category.
Raycasting sounds like the right approach… The specific implementation I guess will be up to trial and error.
No, the level geometry was completed a long time ago. I’m actually trying to juryrig an unfinished game project from several years ago into Unity to see if I can revive and finish it. I’m evaulating Unity right now and am working on a simple mockup of the game based on existing assets. I’m not really ready to be writing refined game code, but am collecting information on some of the problems I’ve discovered as I try to create the mockup in the most straightforward manner using techniques from the docs and tutorials. I’m finding some of the techniques they use seem to get the job done, but only barely and really shouldn’t make it into a real production game. (Actually, I’ll probably post a full topic on this and see if I can get some high-level answers on several show-stopper problems I’ve run into.)