I've got a coin RigidBody and walls around it with box colliders. For trial purpose I've applied the following code to the coin.
private void OnMouseDown()
{
rigidbody.AddForce(30.0f, 0f, 5.0f, ForceMode.Impulse);
}
But, sometimes the coin passes through the walls, but when I increase the speed from 30 to 50 points it passes through the walls on the first click. I've googled a lot and still got nothing except for the DontGoThroughThings Script which doesn't work for me or I don't really know how to use it.
I've always added a continuous dynamic on the coin and continuous collision detection on the walls but still doesn't work.
the problem with physics collision detection is that sometimes when the speed of an object is too high (in this case as a result of a force added to the rigid body) the collision wont be detected. The reason is that the code you are executing is running at x ammount of steps per seconds so sometimes the rigidbody will go through the collider between one step to another. Lets say you have a ball at 100 miles per hour and a wall that is 1 feet wide, the code will move the ball a determined ammount of feets everytime the code is runned according the physics of it, so the movement of the ball is virtualized but its not a real physical movement so it can happen that from one step to another the ball can move from point a to b and the wall is between those points and as a result the collision will not be detected.
Possible Solutions.
You have a simple solution that wont be as accurate as it should be and a harder one that will be perfectly accurate.
The solution number one will be increasing the colliders size, according to the max speed your coin can get, that way the collider will be big enough so that the collision wont be missed between one frame to another.
The second and harder solution will be adding an auxiliar to your collision detection, some kind of a security check. For example using physical raycast. You can set a raycast to forward direction and determine if that object is an inminent collision, if it does and once the object isnt being collided by the raycast anymore then your collision detection had failed that way you have your auxiliar to confirm that and call the collision state.
I hope it helped and sorry about my english. If you didnt understound it very much i could help you with code but i will need some code from your project.
See if the colliders have their 'Is Trigger' unchecked.
Also, check if the gameObjects have colliders.
I have faced this problem many times..
Make sure Your coin's Rigidbody has "Is Kinamatic" False, Is Triggger:false,
And also "Is Trigger" of walls is False.
You could save the velocity and position on each update and then test for out of bounds, if the coin leaves the valid area you can restore it at the last valid position or plot the collision yourself if you want to
Related
I am trying to make a game where i got a ball with an arrow rotating around it. The ball starts as immovable, but when i hit a button i launch it to the direction the arrow is pointing at. Player will have the option mid air to press another button to make the ball "sticky" so when it hits a wall it will stick to the surface and repeat the process till he gets to the top of the level.
Aside from that, i want to give the option to the player to not stick to the wall if he doesn't press that button and instead bounce off the wall but when he does that, the player should speed up with every bounce, giving the option to either play it safe and slow or try to go fast getting more points as he does.
For the early prototyping i used force to move the player up every time he launches but i am not sure how i can make him speed up every time he bounces off the wall. It feels to me like a math problem more than it is a coding challenge. What i am thinking is that i have to find the angle on which player hits the wall, and add force according to that towards the direction he is supposed to follow after the collision.
Sadly i am not that good with trigonometry (working on it though). I am thinking that i might need to use a formula containing sin, cos, tan formulas but i m not sure how to do it. Any help is much appriciated! If you need more information on it please tell me and i ll be happy to provide.
Edit: After the first reply to this question i also found out those links that dive deeper into the subject. I m gona link them here for people that have the same issue.
Bouncing a ball off a wall with arbitrary angle?
http://www.3dkingdoms.com/weekly/weekly.php?a=2
If your ball has velocity vector V=(vx,vy), then after bouncing from standing surface with normal N, ball's new velocity is
V' = V - 2 * N * (V.dot.N)
where dot is scalar product of vectors (vx*nx+vy*ny)
Particular cases:
bouncing from vertical wall (N=(+-1, 0)) causes reversing of vx-component, vy component remains the same. V' = (-vx, vy)
bouncing from horizontal wall (N=(0, +-1)) causes reversing of vy-component, vx component remains the same. V' = (vx, -vy)
Note I recommend to work in velocity vector components, and use angles only when they are really needed.
If you need to calculate bouncing from moving bat, it is worth to change stationary coordinate system to moving one, connected with the bat, find reflection in that system, and revert to stationary system.
Ok so problem was solved!
I want to thank both #MBo and #shingo for their contribution to the solution. While the answer of Mbo solved the problem via trigonometry and gave me nice material to study and figure out how things work, i followed shingo's advice in the comments of my question and managed to do it without diving deep into math.
So basically what he said, and what i did, was to use Unity's physics engine and let the ball hit the wall. After the ball bounces off the wall, it gets a new Velocity vector towards the direction it would go based on physics. I then created an OnColllisionExit check, and when the ball stops colliding with the wall, i AddForce to it to the direction of its new Velocity Vector3.
Works like a charm!
Thank you all for your contributions!
Hey I am trying to make my sprite button go from green to red and backwards when my player collides with it. I have a boxcollider2d as is trigger, and a script
script : https://gyazo.com/ec64a2bca5b23526c6949bf18cb50a0d
I think this is some of it but I dont get anything at all when colliding with the button can anyone enlighten me on this problem would be very appreciated.
Thanks in advance
It is important to distinguish the difference between Colliders and Triggers.
Colliders are used by the Physics system in order to make it so object do not penetrate or overlap each other. Triggers on the other hand are made so that you can check for overlapping areas, an example is a Ring in Sonic. Sonic collects the rings but they do not stop him from passing, think of these as triggers. If they were colliders sonic would jump into them and bounce off.
In Unity the process for creating a trigger is the same for creating a collider, with 1 additional step, and that is marking a check box.
As such it is also important to know which functions you should use in each case.
OnCollision... For Colliders, (Or Colliders not marked as triggers)
OnTrigger... for Triggers, (Marking a collider in unity as a trigger makes it a trigger.)
To just add a bit more detail, It is also important to use the correct collider types for the correct dimensions of the game, 2d Colliders/Triggers do not interact with 3d Colliders/Triggers. More so physics components: 2d Rigidbodies do not works with 3d colliders, and 3d rigidbodies do not work with 2d colliders/triggers.
As such there are functions for each 2d, 3d, collision, and trigger.
Another important factor is to ensure if you want to use these functions atleast one of the objects have to have a rigidbody of the correct type(2d or 3d).
As such the problem you were running into was using OnCollisionEnter2D for a "collider" that was marked as a trigger, in this case OnCollisionEnter2D is not called, but OnTriggerEnter2D is called.
I have a labyrinth in my unity game, this game also has a red ball that is passing through the labyrinth, both have colliders (The ball circle colliders and the labyrinth edge colliders), it seems to work fine, but, when you drag the ball and push it into the labyrinth, passing some seconds, you can get through the colliders and pass, and, if you get enough speed, you can pass all the labyrinth like nothing!, I put in my script a speed limit (10) but it isn't working that well.
Your problem is FixedUpdate and using CollisionDetectionMode.Discrete.
It is called N counts per second, where N is a fixed value. Physics is calculated on FixedUpdate. Now imagine situation:
FixedUpdate is called 60 times per second. Time between FixedUpdate
calls is 1 second / 60 times = 17 ms (approx.)
Collider A size is
1x1x1, Collider B size is 1x1x1
Collider A attached to still object, Collider B attached to object moving towards Collider B with speed 90 units per second.
Physics engine is comparing position of A and
position of B on FixedUpdate It thinks that Collider B just
teleported through Collider A, because it's speed per one
FixedUpdate tick is larger, then collider's size.
If you are going to use very high speed, you have three options:
Try to follow Foggzie's advice
Increase count of FixedUpdates per second, and avoid overloading it with scripts.
Implement your own physics for high-speed objects
Unity deals with this problem through its Collision Detection Modes. Make sure your Rigidbody components have their collisionDetectionMode properties configured accordingly (they default to Discrete). It seems like you'll want the ball to use ContinuousDynamic and the labyrinth to be Continuous but note, as stated in the link:
Continuous Collision Detection is only supported for Rigidbodies with
Sphere-, Capsule- or BoxColliders.
You'll probably need to change the labyrinth colliders.
I am currently working on a 3D Unity game in which you control a block through a labyrinth made out of blocks and have to avoid spikes, moving enemys and other traps.
Here a picture how it looks at the moment ( you are the blue cube and have to avoid the moving pink ones ):
The problem now is, that when I move along a wall, the player gets stuck and stops moving until I move in the other direction again (every part of the wall is as big as the player because I am generating it from an image).
I already tried everything with Physics materials and friction but it does not get better :(.
The problem is that your BoxCollider of the player is probably getting stuck on the edges between two of the wall colliders. Consider "smoothing" the edges of the collider a bit so the player wont get stuck.
The default collision detection mode in Colliders is Descrete, it might jump through a small gap occasionally, you could set the players collider to CollisionDetectionMode.Continuous it will prevent the overshoot.
Try decreasing the Default Contact Offset in Edit/Project Settings/Physics
Changing it from 0.01 to 0.0001 worked for me
Source
Alright, so Im having an odd issue in Unity and cant find the answer there.I have 2 objects, one is movable by the player and the other is spawned. I need the player do be able to move (only along the z axis, meaning forwards/backwards/etc) this spawned object when he bumps into it, but only a little bit.
To accomplish this, Ive attached gravity rigid bodies to both and box colliders to both. Ive increased the mass and drag on the spawned object to make it hard to move here and frozen its rotation/some position to prevent flipping over:
And this does work, meaning the player does push the object and it seems to be a bit resistant, however Im having an odd bug.
I think due to the position/rotation being frozen, after pushing once my player will go THROUGH the object:
I cant have this. I have tried changing physics settings and set bounce threshold to 0
But still having the problem. Decreasing time step basically froze my game. Why is this happening? How can I fix it?