Unity2D disable player collision with ennemy when taking damage - unity3d

My player has multiple hearts, and i want to damage him one heart for every collision with an ennemy, but after each collision i want him to be invulnerable for a certain amout of time, and making him able to pass through the ennemy, thought about disabling his BoxCollider2D for a moment but that makes him fall through the ground as i'm using a Rigibody2D, how can i achieve that ?

There is two ways to do this:
1-https://docs.unity3d.com/ScriptReference/Physics.IgnoreCollision.html
2-https://docs.unity3d.com/Manual/LayerBasedCollision.html (You will change layers for a short period of time)

Related

Unity - two human players, how to detect which player did most damage to AI enemy?

I truly apologize for I have no code to offer here.
I am completely stumped, I’m still a coding noob and trying to run a simple exercise to test a game mechanic idea via prototype.
I’ll use a simple example:
2 players vs. 2 AI enemies
both enemy ai have 400 points of health
both human players have guns that do 20 points of damage per trigger
press.
both enemies are dead after a quick battle.
I want to reward the player who did the most damage to the enemies.
This is what I am trying to achieve:
How do I go about detecting, which player, did the most damage to the enemy AI?
Any help would be appreciated, once I can grasp the concept of how to even go about doing this, I can then move forward on how to code it.
Thanks.
The question is too general - there are a lot of ways to do this. Let's stick to OOP: let's make the "damage" object (script, class), which contains the following info: damage amount, player id. Wheh player hits trigger, lets assume, the bullet prefab is instantiated. It has a script (MonoBehaviour) on it, called "DamageContainer". When you instantiate a bullet, you also create your "damage" object, set correct values, and put it into bullet's "damage container". Then, when bullet collides with enemy, you get this info from bullet. Damage amount you use to reduce enemy's health. For counting damage, you need the counter itself. It can be a static class, a scriptable object, singleton, or something else. Let's use a static class, which is not the best practice, but simplest one. You need a simple static class, called "DamageCounter", and containing two public fields: Player1Damage and Player2Damage. When bullet collides with enemy, you need to add dealt damage to proper field of "DamageCounter", depending of damage.PlayerId field.
And don't forget to reset static class values on start of each battle.

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;

Playing same sound on multiple object collide on Unity

I have a Dice rolling game. I have a 6 dice which is applied random force in random direction in a box. Now, when Dice collide with each other as well as within the box wall the sound need to be produced.
Currently when i add sound to each dice and trigger it when the dice collide, the sound is wired when all of them plays at the same time.
Is there a better way to produce the sound like real when all 6 dice collide with each other and with the walls of the box.
The flange-like effect you hear happens when two identical sounds are played with a very small delay causing their wavelengths to amplify and dampen themselves.
To avoid such effect you have many options:
To just avoid playing same sfx with delays less than inconceivable to user. (you are probably playing each dice hit sfx twice right now)
Use different samples and play them randomly. (if you can't generate new samples try modifying the ones you have by simply changing their pitch by say 3%-10% to have enough different samples)
If second option does not satisfy your need (project size increase) you can use third party plugins such as master audio to create several custom-pitched sounds out of one single sound at run-time.
You can change the pitch in code (at run-time) and make sure two close hits never play with same (or very close) pitch
It's actually pretty difficult to produce realistic collision sound for multiple objects collision.
If you use the same AudioClip for each dice-to-dice or dice-to-box collision event and trigger them on collision event, the end result will simply sound like an echoed version of the AudioClip with various delays.
If you choose to use a variety of collision AudioClips as a pool to choose from, you might produce ok end results as long as you can guarantee there is no two collision sounds with the same AudioClip playing during any given time period.
The best solution probably is to obtain several recordings of the real scenario (dice rolling and colliding in a box), and randomly play one when you are simulating the collision in game. As long as the duration of the AudioClip matches the simulation, it will be relatively hard to spot it's faked.

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.

How to measure the force by which Two rigid Bodies collide?

How to measure the force by which Two rigid Bodies collide and in the reaction add force to other object in opposite direction. For example in the cricket game how the force is measured b/w bat and ball . If player blocks it add a min force to the ball and if he plays the shot he ball goes too far for a four or a six. I will say that just simple addforce() component will not work. It will just apply the force every time when it hits the bat doesn't matter it is blocked or a shot played.