Trigger in Unity 3D project working not constantly - triggers

There is a remake of the Snake game. The snake's head is a trigger, and the apple uses only a collider. Now OnTriggerEnter() does not work every time - the snake's trigger have to enter several times into apple's body to get it.
There is code used for eating:
void Head.OnTriggerEnter(Collider col)
{
if(col.CompareTag("Food"))
{
gameController.FoodEated();
}
}
public void GameController FoodEated()
{
Destroy(currentFood);
InitializeMeal();
head.GrowUp();
}
void GameController.InitializeMeal()
{
currentFood = (GameObject)Instantiate(foodPrefab, FindFreeSpace(), Quaternion.identity);
}
And there is some kind of magic: The first apple could be eaten normally, but the snake can walk through the second apple a few times before the apple will be activated.
I tried every trigger functions and none of them are working. http://www.youtube.com/watch?v=z_UQi7SGOLw - video of a bug. The snake is going through the apple for 3-4 frame updates. I have another idea for realizing an apple, but a trigger is more appropriate, I think.

If your snake moves too fast and the apple collider is too small than I guess that Unity's engine can sometimes miss collisions.
If on the snake you have a Rigidbody component than you can increase collision detection quality by changing "Collision Detection" from "Discrete" to "Continues" or "Continues Dynamic".

As you can see on the video above, my snake is growing by creating a tailelement at the current transform.position. TailElement starts moving when the distance between last two tail elements is more or equals 1.
I just tried to decrease the radius of the head's collider by 10% and now the tail element is not collider during the movement of snake. Now it works fine.

Related

Why does the object get stuck in the wall when repelled?

I made the endless movement of the object and its repulsion from the walls, but it does not always work correctly. At rounded corners (sometimes even at a straight wall), it just gets stuck and stops moving altogether, or moves slowly to the point where it stops moving. What can this be related to and how can it be fixed?
private void FixedUpdate() {
rb.velocity = direction * normalSpeed;
lastDirection = direction;
}
private void OnCollisionEnter2D(Collision2D collision) {
//Repulsion from objects.
direction = Vector3.Reflect(lastDirection.normalized, collision.GetContact(0).normal);
}
There is a small distance between the objects, but the circle seems to stick to the wall and moves with it until it collides with another collider:
Example
there are objects under the circle that also have colliders, but the collision between them is not considered, since they have the same layer (in the settings, I disabled the collision for objects on the same layer). What can be done to fix this error and what can it be related to?
The object in the general scale:
Example
I tried to increase the size of the wall collider, tried to change polygon collider to box collider, connect composite collider, changed the mechanics of the object movement (in these cases, the movement could work incorrectly), but the result was always the same - the jams (sticking to the wall) continued.
It is difficult to answer your question without having more information, but I can suggest if you are using physics to move your objects - utilize physic materials and remove code that changes direction manually in OnCollisionEnter. Using physic materials you can easily make your object bounce from colliders of your choice without losing velocity.

How to calculate the length of platform/object in Unity 5?

I'm new to Unity and after watching and reading some tutorials I'm now trying to make a simple 2D platformer kind of game. In the said game both enemies and player can jump to different platforms and traverse it like the old SnowBros game.
The problem I'm facing is related to programming the enemy movement. In my game there would be several types of enemies but generally for now there are two types, one that can jump from the platform and one that only walks upto the length of the platform, wait for 1 second then flip and walk backwards; meaning they don't get off the platform. Now this is an issue I'm having trouble with. I can't seem to find a way to calculate the length of the underlying current platform. I thought of using the collider.bound.min.x and max.x to come around the problem but the issue is I can't seem to find a simple way to reach the current platform's collider without fetching the script and then going through it.
Since, there would be many platforms of many different sizes and each platform is made up of a prefab of other platforms, it just doesn't seem like a workable solution to use the platform script and then traverse through it.
You can use Physics2D.Raycast to "sense" for collisions on a Ray. Imagine the enemy putting their toe one step forward, feeling if there is still solid ground, and then deciding whether to stop.
void Update()
{
Vector2 newPosition = transform.position + velocity * Time.deltaTime;
Vector2 downwardDirection = Vector2.down; // you may have to replace this with your downward direction if you have a different one
RaycastHit2D hit = Physics2D.Raycast(newPosition, downwardDirection);
if (hit.collider != null)
{
// solid ground detected
transform.position = newPosition;
}
else
{
// no ground detected. Do something else...
}
}
You can and should define the Layers your Raycast is supposed to hit, so it can ignore the enemy itself and avoid self-collision.
Well, I hope that you have prefabs of platform and in those prefabs put colliders at start and at end. You can specify layers and tags so that only enemy can detect those colliders and then you can detect tags on collision from enemy script and make your operation.
First create layers by opening Edit -> Project Settings -> Tags and Layers. Create two Layers
Create layers for enemy and enemyColliders and Goto Edit -> Project Settings -> Physics2D. Set collision matrix as EnemyCollider will collider with enemy only.
And your prefab will be looks like,
I hope this would help you.

Wheel Collider Unity: after adding torque the vehicle starts moving sideways

I really killed few hours to try to fix this, Googling for a solution, but I could not.
I've got a vehicle, it's a go-cart, so there are no suspensions (technically there are, but the values are close to 0, to simulate the tires). The vehicle has a rigid body attached and the child object contains the 4 wheel colliders (and the model itself), as can be seen here:
https://dl.dropboxusercontent.com/u/76599014/sxc/Clipboard01.jpg
For testing, I added a short script to make the vehicle move. It's in the GameObject called "gokart":
public class carControler : MonoBehaviour {
public WheelCollider fr, fl, rr, rl;
public float performance = 50f;
void FixedUpdate () {
throttle();
}
public void throttle() {
this.rl.motorTorque = this.performance;
this.rr.motorTorque = this.performance;
} }
What happens is: the rear wheels start to rotate, as intended, but the vehicle starts moving sideways slowly. The movement speed depends on the torque amount (the wheel rotation in this case). There is no movement forward, so this is not the bug, where when you are standing on a flat surface you are drifting on the sides.
Any ideas? If you need a video or a GIF (I have to figure out how to make one) of the movement, I'll be glad to provide one.
I think you should try and apply 0 brake torque to the front wheels while applying motor torque to the rear wheels.
public void throttle() {
this.rl.motorTorque = this.performance;
this.rr.motorTorque = this.performance;
this.fr.brakeTorque = 0f;
this.fl.brakeTorque = 0f;
}
That being said, anything could go wrong if the Rigidbody/wheelcolliders aren't set up correctly. Unity's wheel colliders can be difficult to set up and work with. Unity changed the physics in Unity 5 so most documentations are outdated.
I found this very good short document that was made by unity: http://unity3d.com/profiles/unity3d/themes/unity/resources/downloads/beta/unity-5.0-user-guide.pdf
It highlights the changes that was made to unity 5 and at the end of page 5 you can find a section that explains how to set up a car. I have tried it about a month ago in a new unity project and it worked. the instructions are clear so try this tutorial out and I hope it will help.
Regards
Not having the image available I'm not a totally sure about the situation but my assumption based on your description is you should try increasing the sideways friction and tweak the forward friction a little bit according to your taste. You have to increase the sideways friction anyways as you are making a go-cart. As far as I know, most arcadey go-carts don't drift and behave a lot different from regular racing cars.
Hope that will solve the problem.

Am I missing something or Unity3d skips frames?

I have a gun with 4 muzzles. Each muzzle can fire a bullet (so 4 bullets can be fired at once). In my scene I have 100 guns thus 400 bullets can be fired at the same time.
The problem is, if the number of gun is below 20 then it is Ok, but if I raise it to above 20, some of the bullets go through the target (a big Cube). And ton of bullets pass through the Cube if it is above 100.
This is the code that check for collision:
private IEnumerator ProjectileCoroutine() {
while (Vector3.Distance(transform.position, Target.transform.position) > 5)
{
yield return null;
}
Explode();
yield break;
}
Some notes:
Games runs at 49 - 68 fps (100 guns on the scene)
I uses prefab pooling method
Above code is run in a separated coroutine (StartCoroutine)
Please can anyone tell me what is happening?
I suspect that Unity skips some of the frames as Coroutine has some connections to it.
I don't think Unity is "skipping frames". That said, I expect your coroutine will only run once per full graphics frame. Physics updates usually occur more often, especially at lower frame rates.
Note that the more bullets there are, the slower the scene probably runs. For a time-stepped physics simulation, this means that bullets have to move further every time step. If the bullets are moving fast, and the time step is large, it is possible for bullets to move too far through the cube for collisions to be detected and resolved in a frame. If this is the problem, you may need to add some sort of ray casting, to better detect collisions.
That said, I don't think your ProjectileCoroutine is the best way of resolving collisions. For starters, it appears to check a sphere, rather than a cube, and running it for every bullet is a bad idea performance wise.
It would be much better to use an appropriate Collider, and rely on the actual physics engine to detect collisions, instead of doing a manual distance check.

OnCollisionStay Vs OnCollisionEnter

Hi I've been using Unity for a while and for the life of me I can still not tell the difference between OnCollisionStay and OnCollisionEnter. I'm assuming that OncollisionEnter is called when a rigidbody (like a ball) makes contact with another rigidbody/collider such as a wall. But when I look at the example for OnCollisionStay, I get completely confused. Even if its called once per frame, If I for example jump up in the air and hit a ceiling above me, is it still called? What exactly are the differences? Here is what the Unity documentation says and the code I was using.
"OnCollisionEnter is called when this collider/rigidbody has begun touching another rigidbody/collider."
"OnCollisionStay is called once per frame for every collider/rigidbody that is touching rigidbody/collider."
if(Input.GetKeyDown(KeyCode.W) && OnGround == True)
{
rigidbody.velocity.y = jumpHeight;
}
onGround = false;
function OnCollisionStay()
{
onGround = true;
}
It is really pretty simple. Let's assume that the collision starts, the colliders keep intersecting for a period of time (several frames), and after a while they separate again. The events then are:
OnCollisionEnter for the first frame only, and never again until after an OnCollisionExit
OnCollisionStay for the entire duration (all frames)
OnCollisionExit for the last frame only
Even if its called once per frame, If I for example jump up in the air and hit a ceiling above me, is it still called?
Sure it is. But then for that new collision. If there is a period in between where you're not colliding with anything however, you will not get OnCollisionStay events for that duration.
To get a deeper understanding of these events, it's perhaps best to create a simple demo scene in which you manually intersect two colliders, and have some text written to the console for the various events.
Bart's answer is correct so this answer is more of an example of how you would use the two.
So OnCollisionEnter will fire 1 per collision case lets say for example a ball hitting a wall and OnCollisionEnter could maybe do some damage to the wall or destroy the wall. (Like breakout)
//Ball
#pragma strict
function OnCollisionEnter (col : Collision)
{
if(col.gameObject.name == "Wall")
{
Destroy(col.gameObject);
}
}
However in OnCollisionStay you would use that if you have a character with hit points that steps into a poison cloud and removes continuous hit points or removes incremental timed hit points as long as OnCollisionStay continues to fire after a given amount of time. (I'm thinking castlevania SOTH)
//PoisonGasCloud
#pragma strict
function OnCollisionStay(collisionInfo : Collision)
{
collisionTime = Time.deltaTime;
if ( collisionTime > 5)
{
hero.hp-=10;
}
}
Note:I usually code in C# so my UnityScript might be a little off.
When collision start: OnCollisionEnter & OnCollisionStay
When collision continue: OnCollisionStay
When collision end: OnCollisionExit
Note 1: OnCollisionStay & OnCollisionExit will not be called simultaneously.
Note 2:OnCollisionEnter call before OnCollisionStay.