Fast moving 2D objects workarounds and performance tradeoffs?
I'm using Unity 5.5 and my fast moving 2D prefab doesn't collide properly with my scene geometry without hacks. I saw an article mentioning the same issue I'm having and the "DontGoThroughThings" script as a workaround. I found this previously and tried it and while it does seem to work, I'm concerned about the performance hit from this script (Raycasting).
Here is a video showing the issue in 3D (same thing happens in 2D).
I also just discovered another article mentioning doubling the "Position Iterations" in the Physics2D settings but once again, I'm not sure about the performance hit.
I have a Dynamic CircleCollider2D set to Continuous Collision Detection that needs to Collide with a static collider in my scene geometry. I have tried using EdgeCollider2D and BoxCollider2D on the walls, floors and platforms. It works fine if I don't use too much force and keep a little distance from the launcher to the wall but once I increase force or get too close it stops colliding.
Assuming that this still hasn't been resolved...these seem to be the only workarounds:
Change Physics2d Position Iterations from 3(default) to 6 (not yet tested)
Continue using this script attached to my prefab which uses Raycasting
I can't help think that I'm probably just overlooking something simple. Ultimately I would really like to just use a simple edge collider for my walls/floors/platforms but others have said it won't work and I can't get it to work either. Any feedback is greatly appreciated!
Continuous collision detection in 2D physics is rock solid and I've yet to see a report that shows otherwise.
The only time I've seen failures is when scripts are modifying the Transform directly and/or the Rigidbody position/rotation. Another change is if the default value of Physics2D.$$anonymous$$PenetrationForPenalty has been changed from its default.
The force applied makes no difference to CCD. All CCD does is sweep the collider from the old position to the new position checking for the first contact (if any). If a contact is found then the body is placed at the position so that the contact is touching. If no contact is found then the body is placed at the new position.
Can you please provide a simple reproduction case for this?
Thanks $$anonymous$$elv$$anonymous$$ay!
TBH...I'm very new to Unity so I am likely seeing this the wrong way. I've created a couple GIFs to demonstrate what's happening:
This one shows the boundary of my BoxCollider2D on the "SideBarrier" when I toggle the Sprite Renderer and the expected behavior happening when I launch the projectile. However notice the gap between the Player (Blue Square) and SideBarrier (yellow wall).
This one demonstrates my projectile prefab (tpGrenade) appearing to breach the SideBarrier with the BoxCollider on it (same as last GIF) and riding up the wall as if on an elevator. Sometimes it shows that the projectile is still rising on the Y coord and then it drops outside the screen boundary of my $$anonymous$$ain Camera (it's off in the GIF). Camera 2 is being used for demonstration
It seems like it's instantiating my prefab in the outer-most side of my BoxCollder2D on the SideBarrier but it does the same thing with an EdgeCollider2D. The projectile fits inside the space of the Blue Square exactly.
Here is the related code attached to the Player 4 object (note that the other Players in the GIFs are disabled test objects)
public float thrust;
public Transform tpGrenade;
public LineRenderer playerShotLine;
private Vector2 launcherTo$$anonymous$$ouse;
private Vector2 targetVector;
...
void On$$anonymous$$ouseDrag()
{
Vector3 mouseWorldPoint = Camera.main.ScreenToWorldPoint (Input.mousePosition);
Vector2 launcherTo$$anonymous$$ouse = mouseWorldPoint - transform.position;
mouseWorldPoint.z = 0f;
playerShotLine.SetPosition (0, transform.position);
playerShotLine.SetPosition (1, mouseWorldPoint);
playerShotLine.sortingOrder = 3;
targetVector = -launcherTo$$anonymous$$ouse;
}
void On$$anonymous$$ouseUp()
{
playerShotLine.SetPosition (1, transform.position);
playerShotLine.sortingOrder = 0;
SpawnGrenade ();
}
void SpawnGrenade()
{
Instantiate(tpGrenade, new Vector3(transform.position.x, transform.position.y, 0), Quaternion.identity);
tpGrenade.GetComponent<Rigidbody2D> ().AddForce (targetVector * thrust, Force$$anonymous$$ode2D.Impulse);
}
...
Answer by Socapex · Mar 15, 2017 at 04:35 AM
Raycasting is fast. A single raycast to see if you went through geometry is a standard way to fix this. It is a good solution.
Thanks...what about the performance impact vs Position Iterations? Any idea which is more taxing?
Your answer
Follow this Question
Related Questions
OnCollisionEnter2D not calling, but objects are colliding. 1 Answer
How to stop game object movement instantly after collision is detected ? 1 Answer
ECS performent collision 0 Answers
Enemy bullets pass through my walls 0 Answers
Absolutely no collision detection in build but editor is fine 1 Answer