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.
Related
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.
I am trying to make a Retro Tenis Game in Unity2D but I have some issues with the colliding system.
My controller does not collide with the walls. It goes through them.
It should stop in the wall like pic1 but it goes through it like pic2.
Can anyone help me, please?
pic1
pic2
UPDATE#1: I added a RigidBody component but it does not fix it. (pic3)
pic3
You shouldn't use the colliding system for this purpose. It would be much better that the script in charge of moving your paddle was able to control its maximum and minimum height too (note that the screen size can change, and the paddles should move at different heights depending on the screen size).
Although if you want to do it with the collision system and "walls" that limit the space of the paddles, both the "walls" and the paddles need to have a correctly positioned BoxCollider2D and the paddles an extra kinematic Rigidbody2D too (as they can move).
Also make sure to move the paddles using physics and not modifying its position with transform.position (see Rigidbody2D.MovePosition)
Edit: Unity2D physics system is rather a complicated topic and difficult to get it well on your own. I'd suggest to learn the basics in the Unity Learning Platform. You could start with this project.
You need add RigidBody2D to your "circle"
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.
So i am making a simple Golf game, when trying to replicate the balls movement i have noticed that on slopes the ball functions very oddly, it either never stops or stops too quickly and when travelling down slopes will reach a very slow terminal velocity quickly (ie it stops accelerating down slopes). So it either doesnt deaccelerate enough going up a slope or accelerates too slowly going down a slope.
I have been messing about with angular and static Friction of both the ball and the surface to see if that changes it at all and i have also been changing the friction combine of the surface and the ball to see if that makes any difference and so far haven't had any luck.
Is this a common issue with Unity because i haven't been able to find any other questions about it on here. If anyone could give me some advice on how to have my ball not roll forever but still accelerate when going down a slope that would be great
EDIT: The ball has a rigidbody with continous collision, then the course uses a mesh collider. Both however have attached physics materials
The ball is currently just a basic sphere from unity using a sphere collider, i havent tried changing the rigidbody about much yet other than mass. When the ball is hit i addforce to it, the slopes are an asset i have purchased that are perfectly smooth.
Rolling object physics are indeed difficult in game engines.
As I mention in the comment for such questions it's necessary to know (a) what sort of collider and (b) what sort of object it is, since there are at least 4 major approaches to this problem.
But in general you usually have to manually add the "slowing down" function, in a sense representing air resistance.
For a moment set aside the collider choices, and imagine in the abstract you have a ball rolling along a flat plane. You've somehow started it moving at 2 m/s say.
There's really no reason at all it will stop rolling or slow down. Why would it? There's no air resistance in physX and what you "want" it to do in the game engine physics is keep rolling.
Thus what you do is add a script that, essentially, "slows it down a little" every frame. In pseudocode, something like
velocity = 0.99 * velocity
Note however that alternately, to "manually slow it down", you may have to simply add force to it.
The trick is you do that in the opposite direction to movement
yourBalls.addForce( v.normalized * -1 * some small force )
(It's easy to think of that as basically "air resistance")
You usually also, simply, just add a top speed. In this way on downslopes it won't just get "infinitely fast"
if (v.magnitude > 3.0) v = v.normalized * 3.0
That's basically how you make objects roll around on hilly surfaces.
Note that you basically should not fool with the friction settings in anyway, it's really not relevant in most cases.
Unfortunately there is a vast amount of detail but, I feel your question is more asking for the "basic principles" - and there they are!
Tip: it could be this question is more suited to the gameDev site, where "techniques" of game physics are QA'd.
Sorry if similar questions have already been asked.
I have a character that can hold up a shield to block incoming damage. The character has a circle collider for his body space. The shield has a box collider that blocks off a portion of whatever direction he's facing, and it's only enabled when the player is holding down a button. My enemies have weapons surrounded by triggered box colliders which are enabled when they decide to attack.
So, my problem is that when my character is attacked while shielding, sometimes his body collider is detected and sometimes his shield collider is detected. I can't find any consistency no matter what I try.
[Screenshots] (http://i.imgur.com/VHujbcG.png)
[Code] https://gist.github.com/siketh/2401454977d10ed7699b
I've been struggling with this all day and need another set of eyes. This isn't a serious project so if you need to see anything else I'm happy to post more code or explain more of my design.
It's probably because the weapon intersects with both the character and the shield at the same time. There are great tools in Unity if you want to see if that's the case.
Notice that Unity has "Play", "Pause" and "Play one step" buttons at top of the editor window. You can pause the game with Debug.Break(); instantly at the moment player fires or swings the weapon. Then you can watch what's happening step by step. Select the character, the shield and the weapon so that you can see their colliders in action. This way you can see what collides with what exactly step by step.
Similarly you can see the action in slow motion by adjusting time scale. Something like Time.timeScale = 0.1f;
To prevent this,
You may want to look at continuous collision though I've always failed to use it properly in Unity.
You may want to utilize more physics layers. http://docs.unity3d.com/Manual/LayerBasedCollision.html
You may want to detect collisions by using raycasts.
You can enlarge the shield and reduce the weapon swing speed or bullet speed. So that it's impossible to penetrate through shield.
You can decrease the period of FixedUpdate calculations so weapon movement will be smoother and there will be less penetrations.
http://docs.unity3d.com/Manual/class-TimeManager.html
There is a high probability that you are detecting both weapon-to-shield and weapon-to-player collision in one step. So why not postpone the decision one FixedUpdate later. So that you can check if there was only weapon-to-player collision or both collisions. If weapon-to-shield collision detected in previous update, then you know player hit the shield no matter if weapon passed through the shield or not.
Let's say there is no way you can detect if weapon hits the shield or the player. By using some simple geometry, you can check if the attack is coming from the direction of the shield or not.
Good luck :)