I'm casting SphereCastAll in direction of the red line and I sometimes have a strange issue that this cast misses some colliders like in the screen below. The green line shows SphereCastAll origin and closest hit with different rigidbody to not collides with own colliders. SphereCastAll radius is half of car width.
Sometimes SphereCastAll misses all colliders from car in front and hits the next car.
Rigidbody is moving by WheelColliders
Here's a link
One interesting aspect of Physics.SphereCast() is that it occasionally fails if the sphere was already colliding with an object. Thus for Physics.SphereCastAll() it might not return the first (couple of) collisions if the sphere would already be colliding with them. Consider using Physics.OverlapSphere() to get the collisions you are missing or reducing the radius of the SphereCast to such a radius where the SphereCast cannot start inside of any other enemies / cars / what-have-you.
Related
I'm attempting to write a bouncing ball game using flame in flutter. To detect collisions the onCollision and onCollisionStart methods are provided. What I had hoped is that onCollisionStart would give a precise location when two objects first hit each other. However, instead it gives a list of positions indicating where the two objects overlap after the first game-tick when this happens (i.e. onCollisionStart is called at the same time as onCollision, but is not called a second time if the same two objects are still colliding on the next tick).
This is illustrated in the attached picture. The collision points are marked with red dots. If the ball were moving downwards, then the ball would have hit the top of the rectangle and so should bounce upwards. However, if the ball were moving horizontally, then its first point of contact would have been the top left corner of the box, and the ball would bounce upwards and to the left.
If I want to work out correct angle that the ball should fly off, then I would need to do some clever calculations to work out the point that the ball first started hitting the other object (those calculations would depend on the precise shape of the other object). Is there some way to work out the point at which the two objects first started colliding? Thanks
What you usually need for this is the normal of the collision, but unfortunately we don't have that for the collision detection system yet.
We do have it in the raytracing system though, so what you could do is send out a ray and see how it will bounce and then just bounce the ball in the same way.
If you don't want to use raytracing I suggest that you calculate the direction of the ball, which you might already have, but if you don't you can just store the last position and subtract it from the current position.
After that you need to find the normals of the edges where the intersection points are.
Let's say the ball direction vector is v, and the two normal vectors are n1 and n2.
Calculate the dot product (this is build in to the vector_math library) of the ball direction vector and each of the normal vectors:
dot1 = v.dot(n1)
dot2 = v.dot(n2)
Compare the results of the dot products:
If dot1 > 0, n1 is facing the ball.
If dot2 > 0, n2 is facing the ball.
After that you can use v.reflect(nx) to get the direction where your ball should be going (where nx is the normal facing the ball).
Hopefully we'll have this built-in to Flame soon!
There are two planes next to each other. Each plane has a mesh collider. Randomly, when the capsule (with a rigidbody and a capsule collider) crosses the edges it bounces.
Do you know why ?
This normally happens if the planes don't align. Make sure there is no gap between the planes and that they are on the same y position.
If this won't fix you problem, you might want to consider using Unity's CharacterController and adjusting the step size which will, rather than bounce, slide/snap the player to position.
Basic Problem: Unity's physics engine produces weird collisions when a player is moving over a flat surface made of more than one Collider. The ghost collisions occur at the joints between Colliders, and express as two behaviors:
This seems to be a problem with physics engines in general, based on this talk by Bennett Foddy:
https://www.youtube.com/watch?v=NwPIoVW65pE&ab_channel=GDC
Game Specifics:
In my case, the player is moving through a procedurally generated wormhole, composed of Segment objects using a MeshCollider. The wormhole twists randomly through 3D space, while the width and height change dynamically. The player can strafe 360 degrees around the inside of the tunnel (direction of gravity is relative to position).
This makes the simpler solutions I've found impractical. Those include:
Using a single object instead of many
Placing redundant Colliders behind the joints
I've managed to flag these erroneous collisions in OnCollisionEnter(). This method on the PlayerController works fine to identify these erroneous collisions, and raise a flag.
private void OnCollisionEnter(Collision other)
{
if (other.gameObject.tag != "Tunnel"){return;}
// Bit mask for tunnel layer.
int tunnelLayerMask = 1 << 10;
// Get the direction from the nearest Segment's origin to the collision point.
Vector3 toCollision = other.contacts[0].point - nearestSegment.transform.position;
if (Physics.Raycast(nearestSegment.transform.position, toCollision, out RaycastHit hit, 100f, tunnelLayerMask))
{
// Flag the collision if the detected surface normal
// isn't equal to the collision normal.
if (other.contacts[0].normal != hit.normal) { colFidelityFlag = true; }
}
}
But I'm at a complete loss when it comes to gracefully resolving the issue.
Currently, I'm just caching the player's velocity each frame. If a collision is flagged, I overwrite the resulting velocity with the cached velocity from the previous frame. This works for most conditions: the player ghosts imperceptibly into the floor for a frame, and gets past the offending joint.
But under high enough velocities or interactions with obstacles inside the tunnel, it is possible for the player to be ejected through the floor, and into space. I don't want to limit the velocity of the player too much, since the feel of the game partially relies on high velocity and hard collisions.
Does anyone know of a better way to resolve these erroneous collisions?
This is called "ghost vertices", and happens if you have like 2 box colliders (or something equivalent) and they are connected to each other. You could try to join the colliders so that instead of 2 separate connected colliders you have a single one.
Here ghost vertices are explained in more detail: https://www.iforce2d.net/b2dtut/ghost-vertices
I'm currently trying to develop an arkanoid-like game in Unity but I'm having a problem that I can't seem to be able to solve with a satisfying solution.
When the ball hits the edges of two adjacent bricks, it "reflects" the velocity in an unexpected way: the ball goes to the direction where it was coming from.
For information, I have a world space size of : 5.625x, and each brick has a size of 0.703125 for 8 bricks per line. Also, every bricks have the same Y size for the collider.
I tried increasing the x size of the collider to some reasonable extent (0.74x for example) to make sure there's no gap between two bricks but the problem still occurs sometimes.
Here is a very ugly picture illustrating what's happening (the green arrow being the expected trajectory):
Thanks in advance for your help!
EDIT: Here are the inspector informations regarding the ball and the bricks. Regarding the lines of bricks, it's basically eight game objects with a boxcollider2d and a kinematic rigidbody2d.
The ball material has a friction of 0 and a bounciness of 1.
Imagine you have a ball falling due to gravity. When it encounters a rotating "cube" object, then you would expect it to bounce off of the object. However, in my case if the cube is rotating fast, the ball goes through it, but if the cube is rotating slowly, the ball hits it and bounces away as expected.
I am using RotateAround() inside the Update() method to achieve the "cube" object's rotation. I tried setting the ball's collision detection to Discrete, Continuous, and Continuous Dynamic with no luck.
My goal is to make the ball bounce away no matter how fast the "cube" object is rotating around another object.
Is there something else I should look into?
Thanks!
You can try lowering the Fixed Timestep value under Edit > Project Settings > Time.
Be aware that this will affect the performance of the game as you're calculating physics more often.
Documentation: http://docs.unity3d.com/Manual/class-TimeManager.html
Also, I assume that you have box and sphere colliders as opposed to mesh colliders? The former are more efficient at detecting collisions.