It is impossible to implement accurate collisions in 3D SpriteRenderers? Is Billboard incompatible with rigidbodies? - unity3d

I've been having difficulty implementing enemies with a billboarding system for a while:
For a new project I'm reusing some animated sprites from an old static camera shooter game I made. It consisted of shooting projectiles and hitting enemies advancing towards your position. The enemies were capsules which had an animated plane in front of them.
I wanted to go a step further and make a raycast system that would detect if the impact on a plane is on the alpha part of its texture. I achieved it using a SpriteRenderer and a plane that matched the size of the sprite which receives the impact of the Raycast.
The problem comes with the movement of the enemies. If I use Rigidbodies this conflicts with the plane which detects the impact, since I have to use a non-convex Mesh Collider for RaycastHit.textureCoord (With Convex colliders it doesn't return the correct position). I need Rigidbody based movement for the enemies to push each other when colliding.
I tried using Transform Movement, since the error does not occur, but this allows enemies to pass through each other and occupy the same space.
I started investigating navMesh but I'm not sure if it is possible to avoid collisions.
I started to place a group of trigger colliders on the enemy mimicking the shape of the sprite. But this makes it difficult for me to detect collisions when enemies do certain animations (Some enemies jump diagonally or their animations are a bit jittery).
I would like to keep the impact detection system for the sprite, but maybe there is another way to check the texture at the impact location.
I think my options are:
With rigidbody based movement: separate the animation and hit detection system from the enemy movement. And make the billboarding effect teleport to the object constantly.
With Transform movement: Detect if they are overlapping and move them in opposite direction to the overlapping to simulate the collision.
With motion based navMesh: I'm not sure if it will be useful to me, since the characters jump and I also believe that a Mesh Agent ship cannot simultaneously be an obstacle. I understand that the navMesh cannot be generated in runtime.
Leaving texture based detection and using the trigger colliders group: Animate the colliders to also follow the animations. Or simplify everything to a large collider, losing precision on impact.
-Find an alternative method to detect the impact coordinates in the texture, avoiding using RaycastHit.textureCoord and therefore Mesh Collider. (Although I would like to keep the impact detection system as it is, maybe there is a similar approach for the same result).
The reason I have not yet delved into these solutions is because I would like to keep the system simple. I'm trying to avoid separating the enemy into 2 gameobjects, simulating collisions or animating collider positions. I honestly don't know which way to go in order to move forward with the project.

Related

The GameObject passes through the terrain - Unity3D

I am trying to make some kind of simulation program with Unity. The simulation includes a missile launched from an aircraft and a terrain.
I get the coordinate data required for the movement of the missile from another program using a socket connection.
I created an explosion effect for the missile to explode as soon as the missile and the terrain collided. But the explosion effect is not triggered in any way.
I used the OnCollisionEnter() method to detect the collision, but this method does not seem to work.
The missile has its own rigidbody and collider and The terrain has Terrain Collider, but still no collision is detected and the missile passes through the terrain.
What could be the cause of this error?
EDIT :
I thank everyone for their help, but none of the solutions worked. I solved the error using the OnTriggerEnter method. For this, I also had to enlarge the object's collider a little more.
As mentioned in the comment section above (I dont have enough rep to contribute to the discussion but will provide a solution), you need to enable continuous collision detection. Once you have done that we can move onto the next step.
It is generally bad practice to interact with rigidbodies in update and it can lead to all sorts of strange bugs so I wouldn't recommend it. That being said I dont think it's the cause of your issues. As #HumanWrites mentioned, you are manually moving the position each frame which causes your missile to never actually collide with your mesh. the solution to this is:
rb.MovePosition(Vector3.MoveTowards(...))
The reason for this is that by using the method on the rigidbody, you inform the physics engine that you want to move from one position to the other and you would like the physics to take care of this instead of you doing it directly. This allows it to "sweep" between the current position and target position and detect any collisions that would have happened along the way.
Your missile is moving too fast to ever actually touch the mesh within a frame so you need to rely on the physics engine doing that sweep check.

Preventing collider from glitching through terrain

I'm using a terrain in Unity 2019.2.1f1 and a custom mesh of a cave with a mesh collider.
My character that has a Capsule Collider way bigger than the entry of the cave should not be able to enter in. But due to the roundness of both colliders, he can come into force in the cave, glitching through the terrain collider.
I think it's velocity is not excessive, I'm moving the character with rb.MovePosition() in the FixedUpdate(), and I set its rigidbody collision detection to Continuous speculative (tried all the "continuous" modes)
In the animation below, you can see the mesh of the cave and the capsule collider around the character.
How can I prevent this from happening? How can I say to Unity: "I want the colliders to be rock solid and not marshmallow"?
Colliders in Unity are rock-solid. They are incapable of any kind of soft physics, and the only moment they will warp through each other is when you force them to.
Here, you are setting the rigidBody position by force, into an impossible location. The game tries its best to fit your rigidBody despite the lack of room.
You can
Only use forces, and velocities. You can simply set the velocity to the direction of your choosing, and set it to 0 when you stop moving, or use AddForce, which is basically the same thing.
Keep using MovePosition, but use a SphereCast or CapsuleCast to check if you have enough room to move first.

How to fix Unity collision problem with 2D sprites

So I've made this game right here: https://youtu.be/OxJEeOTldcM
And I'm facing an issue with the maze wall's colliders where, in certain levels (not just the one I'm showing in the video below), the ball goes through the walls when it's being forced against the wall by the movement.
Here you can see what I'm talking about: https://youtu.be/dVU3LWKuXJ0
I've already dealt with this and compromised by making the maze's rotation speed a lot slower than I initially intended to. I wanted the maze to rotate as fast as the player's movement, but that made the ball go through every single wall.
So the way I'm creating these levels is this: I have these pre-made PNG mazes, I import them into the level and I apply a Polygon Collider 2D on them. But it seems like that Polygon Collider alone can not properly deal with my game's collisions.
More than this, I started layering some empty game objects with box colliders on some of these walls, trying to make them stronger. This does work, but it's still not enough, and the ball keeps going through some of them.
The ball, as well as the walls, have rigidbodys on them, and I've set their Collision Detection to Continuous, based on some answers I've seen online regarding bad collision detection. Still doesn't fix it.
I've also tried making those maze's walls thicker in Photoshop, but I can't go thicker than they're right now without ruining the space the ball should be moving in, as well as distorting the maze's look.
There has to be a way in which I can fix this bad collisions of Unity. I need the ball to stop going through walls, as this is obviously an essential part of my game.
I also want to be able to set the maze's rotation back to being as fast as the player's movement, without having to limit its speed, but honestly I'd be happy if I can just fix this collision problem with the current speed.
The most frequent cause of "clipping through walls" is not bad collisions. It's usually due to poor understanding of Unity's separation of Physics and Frames.
Unity calculates collisions and physics on a fixed update cycle, and generates frames on a dynamic update cycle based on CPU resources. These are often explicitly leveraged by FixedUpdate() and Update() in Monobehaviours.
Everything in Unity happens on one of these 2 cycles. Frame based logic like changes to a transform happen on the dynamic update cycle, and physics logic like collisions happen on the fixed udpate cycle.
You are likely rotating your puzzle using the transform. This rotation to the transform happens outside of any physics calculation, and if you rotate fast enough you can end up clipping through walls before the physics calculation has a chance to run and generate a collision. This is very noticeable when you have very high FPS (like the uncapped FPS of the inspector). However, locking your FPS only masks the issue, and the bug can still occur.
To fix your issue, I implore you to make your rotation changes to the Rigidbody2D itself instead. Something like this should work:
public class SimpleRotation: MonoBehaviour
{
Rigidbody2D rigidBody2D;
void Start()
{
rigidBody2D = GetComponent<Rigidbody2D>();
}
void FixedUpdate()
{
if(rotateRight)
rigidBody2D.rotation += 1.0f;
if(rotateLeft)
rigidBody2D.rotation -= 1.0f;
}
}
Something else important to note is that Unity only updates input on the frame, so if you read your input during the FixedUpdate(), you may double read your input (or miss it completely). It is a good idea to read your input on the Update() cycle, and set a variable to transfer logic between the methods.

Make two physics objects not collide but do detect collisions in Unity

I have a Unity project in which there is a 2D game world that consists of static colliders to make the geometry solid to the characters that inhabit it. The player is a dynamic collider (with a non-kinematic rigidbody). There's also an enemy character that is also a dynamic collider. Both characters walk over the floor and bump into walls like I'd expect them to.
What I want to achieve is that the player and enemy are not solid to each other, so they can move through each other. I achieved this by putting the enemy and the player on separate layers and setting the collision matrix so that these layers do not collide with each other. The problem I'm having now, however, is that I do want to detect whether or not the enemy and the player ran into each other. I added a trigger collider to the enemy character, it's on the enemy layer which means it doesn't detect collisions with the player.
I thought of making a sub-gameobject for the enemy, put it on the player's layer, add a rigidbody and trigger collider to it and use that to detect collisions between the player and the enemy, but it feels so convoluted that it leaves me wondering if there isn't a more elegant solution for this.
Edit (2020-05-26): Nowadays you can tell the engine to ignore collisions between two given objects. Kudos to Deepscorn for the comment. Will leave the rest of the answer unchanged, and read with that in mind.
Yes, you need to create a child GameObject, with a trigger collider, and put it in a layer that interacts with the player layer.
No, you don't need to add a Rigidbody to the new GameObject, the parent's rigidbody already makes it a dynamic collider, so you will get OnTrigger events.
As a side note, just to keep things organized, if you create a child of the enemy don't put it in the player layer. For example, in the future you might need to disable the player's layer collision with itself. Furthermore, if your player interacts this way with many objects, I'd put a single trigger on the player instead of the enemies, on a separate PlayerTrigger layer, just to keep things simple.
Isn't there a simpler way? Not really. You definitely need non-interaction between the player and enemy colliders, but some kind of interaction between them too. So one of them needs to span two layers, or the whole interaction would be described by a single bool. The physics engine processes lots of information in one go, so you can set all the layers and collisions you want, but during the physics loop you have no further control on what happens. You can't tell the engine to ignore collisions between just two objects. Having only 32 layers, and having them behave in the rigid way they do are actually heavy optimizations. If you are concerned about performance for creating another layer, disable interaction between layers you don't need, like the trigger layer and the floor and walls, or layers that don't even touch.
Your alternative is doing it all by code, which is even less elegant. A single child capsule on the player doesn't sound that bad now, doesn't it?

Collision detection between characters in Unity3D

I am working on 3D fighting game and I am using Unity3D as my game engine. I have a scene, two characters who work very fine and I can control it with my keyboard. But now the problem is in the collision detection.
I have used capsule colliders on my characters and also rigidbody gravity. Now when both these players collide the collision can be detected easily but due to the collision my character will fall down and is not able to stand, just like a capsule. I want to create some realistic effects just like other games have. Is there way to do this?
I would recommend you use a Mesh Collider, but that does not work for animated models.
Here are some suggestions:
Collision for Animated Characters
Note: The mesh collider does not animate. This means that if you want accurate 1:1 collisions for
animated characters, it will need a series of colliders parented to
each joint roughly the same shape as the character.
Another way to do
this is to make a ragdoll out of the character and turn off (or
remove) the rigidbody components. If you just want generic collisions
for humanoid characters, you may use a Character Controller (below).
You have to use primitive colliers because two mesh colliers can never collide with each other.
If you want to make realistic interactions... you should use animations and IK in Unity... its the best way...
For more collision related issues check this : https://youtu.be/Bg73o9JH53c