Am I missing something or Unity3d skips frames? - unity3d

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.

Related

How to change game speed in mid development without touching the Timescale in Unity (2D)?

I have a game similar to Sand balls and I was wondering how can I speed up the game a bit without touching the timescale? A nice and somehow correct approach would be to scale down all my objects so gravity can also "affect" the drop movement. I already tested that and works as expected, except I have to apply that for 100+ levels... and would break some prefabs (a mass level editor to scale by bounding box would work but that's another story)
On the other hand, I have timescale but feels like it's the incorrect approach since it also affects animations and leads to unwanted behaviors.
So... do you know any other ways to speed up the game?
If objects is falling down, you can increase gravity. Or without touching timescale, you can just create a public speed multiplier variable and set it to 1 at start.
If you only move balls (Assumed from give sand balls reference), just multiply speed variable of ball with public speed multiplier variable. When you want to change the speed, just change the variable. As an example:
var ballSpeed = baseBallSpeed * speedMultiplier;

Make Physics more accurate

I make a 2D-game. In this game, I have a projectile, which I move the fires by myself like this:
void Update()
{
gameObject.transform.position = new Vector3(
gameObject.transform.position.x + baseVelocity * Time.deltaTime,
gameObject.transform.position.y + baseVelocity * Time.deltaTime,
gameObject.transform.position.z);
}
And also, I use void OnTriggerEnter2D(Collider2D other) to know when collisions occurs.
The problem is when game running on a weak phone with 30-FPS it won't detect collision, while same fire in an 60-FPS phone will collide.
I think this is because the fires move 2x more in 30-FPS phones.
One option was use FixedUpdate() method for moving fiers, but it gave me jerky movement, and I used Update() method for moving because it gives me smooth movement(in both of them I used Time.deltaTime).
Can you please suggest me how make more accurate while using smooth movement?
like move object in Update() method but check object position in more(offset) positions than where it is!
I forget to note that I changed the value of Fixed TimeStep to 0.01 for getting more accurate physics.
Thanks in advance.
edit:
I finally end up with using FixedUpdate() for move objects by myself, for so many reasons I can't use Physics engine, I set FixedUpdate TPS(tick per second) around 60 to some how be match with my 60 FPS Update (and still can't figure out why increase FixedUpdate TPS will make object movement jerky!).
And will keep this question open for finding better answer.
You seem to be doing the physics manually. The issue with manually updating the position is that you don't know about the position of your projectile between frames. Even if you were to use FixedUpdate, you could still be in the situation where two FixedUpdate calls cause your projectile to miss an object.
So instead of manually updating the position, you should use a RigidBody2D, with the collision detection set to "Continuous". A continuous collision detection will interpolate object collision in between physics update cycles, so you hit your target even at very high speeds. Also, this solution does not depend on frame rate.
Note that the above will only work if you don't manually update your positions yourself. That is because the physics engine uses velocity to calculate collision in between physics update cycles.
So instead of updating the position yourself (which is bad for physics), use forces instead.
Or alternatively, if you don't want to mess with forces, update the velocity instead:
GetComponent<RigidBody2D>().velocity = baseVelocity;

SKPhysics in Swift - Lowering Speed Property Jittery

Usually in 2D physics engines like JBox2D, if the user wanted to make a simulation run in "slow motion", you would just decrease the value by which the simulated world iterates by, for example normal movement at 60fps, the step would be 1/60 if the physics world is stepped forward every frame.
But for the SKPhysics class in the sprite kit in xcode 6 using swift, I only see the property called ".speed" which when I decreased, only led to a jittery mess, that updated the physics bodies once every 10 frames.
Is there a specific property, or trick maybe to get the SKPhysics world to iterate forward in time by smaller increments without gross glitchy movements?
The only way to slow down the simulation in sprite kit is to use the physicsWorld.speed element.
But if you are trying to change only one or two sprite speeds, try the velocity element of the sprite:
node.physicsBody.velocity = x
you can directly change the velocity(speed) of your node or sprite through its physicsBody.
Hope it helps :)

Trigger in Unity 3D project working not constantly

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.

How to detect collision between three objects simultaneously in Box2D?

I am new to Objective-C. I am currently working on a game using Cocos2D and Box2D. My problem is that when 3 objects collide together, the game crashes. Now let me describe my game in details:
In my game I have a main character standing on top of a building. Below the building there's this the road. Enemies pass by the road at various random speeds entering the screen from right and exiting from the left. I have created the enemies as b2_kinematicBodies and set a random velocity for each of them using SetLinearVelocity(). The main character shoots the enemies. The projectile (the object being shot) is a b2_dynamicBody. When the projectile hits the enemies, both the projectile and the enemy are destroyed. During gameplay sometimes an enemy moving at a slow speed is crossed by one which is moving at a higher speed. If a projectile hits the two enemies just at the point when they are overlapping and one is about to pass the other one, the game crashes! Please help me with this.
I have detected collision using b2contactListener class.
One thing I didn't mention before is that I am not creating the enemies as individual distinct bodies. Instead, I am creating it once and making it move and I am calling this method (which creates the enemies and makes them move) inside init as below:
[self schedule:#selector(addRightTarget) interval:2.0];
I believe the issue is that the collisions are calculated before your handler gets any calls. Meaning that when your handler gets called, the bullet has hit 2 objects. So you get 2 call-backs as shown below.
Collision Detected: Bullet + Enemy1
Destroy Enemy1
Destroy Bullet
Collision Detected: Bullet + Enemy2
Destroy Enemy2
Destroy Bullet [CRAAAASH!!! You just tried to delete a non-existent object]
1st: You should not be removing anything except in your step function (as someone mentioned in another answer)
2nd: Pick one of these:
Make your list/array of objects-to-delete be a 'set' or implemented in such a way that duplicates are avoided.
Check for existence of your object in the world
The collision only happens between 2 objects in Box2D. So in your mentioned scenario your will get multiple collision events which could be,
Enemy-1 and Enemy-2
Enemy-1 and Bullet
Enemy-2 and Bullet
So one possible reason of crash could be that you are not expecting (Enemy-1 and Enemy-2) collision and you are handling it like you have collision between (Enemy-1 and Bullet) so you might be casting it into wrong class. Make sure you are checking the kind of class "isKindOf" before casting it.
Also you may want to use Contact Filtering and or assign category masks to your enemies so that they don't collide with each other and only collide with bullet.
But it will be more help full if you tell something about how and where you destroy your bodies (I hope its not inside your Collision Detection Functions) and also if you can share the exception text when your application crash, that will be helpful.
I used a rather cheap workaround. I alternately created enemy fixtures of different sizes(differing by few pixels). So now if i shoot them even when they overlap, the app doesn't crash(because only the bigger object collides and gets destroyed). This serves my purpose. Thanx a llot for your help. I really appreciate it! :)