Checking collision only during animations - unity3d

I have this knight character with a sword and an attacking animation. I want to check if the sword is colliding with an enemy and then decrease the enemy health. I managed to do that but EVERY TIME the sowrd's collider hits the enemy's collider I have the interaction. Obviously I don't want that, but the interaction should happen ONLY when the player is attacking.
I tried different approahces:
Check the attack with a boolean, by doing this in the character script
if (Input.GetButtonDown("Fire1"))
{
GetComponent<Animator>().SetBool("hit1", true);
isAttacking = true;
}
and this in the enemy script
if (other.gameObject.CompareTag("Sword") && knight.isAttacking)
{
Debug.Log("Hit");
currentHealth -= 10;
Debug.Log("Enemy healh: " + currentHealth.ToString());
healthBar.UpdateHealthBar();
}
Check if the animation is running using animator.GetCurrentAnimatorStateInfo(0).IsName("nameOfTheAnimationState") instead of knight.isAttacking
Nothing seems to work so far, I know that I'm missing something stupid and I'm going to facepalm when you guys will tell me so, please, make me facepalm!
Thanks.

In the animation window, open the attack animation of the player which roughly looks like this
Now, try playing with the vertical white bar, moving it shows the animation snapshot of the player at each keyframe. Now, find the keyframe at which the player lifts the sword to hit the enemy. Add an event there by clicking the button that's circled red in the image below
After adding the event, you'll see the function in the inspector that's invoked by the event when the animation reaches that keyframe.
Now, create a function to set the attack point active in your script.
Find the keyframe at which the player drops the sword after hitting the enemy and add an event there. Invoke another function that sets the attack point to false.

Related

How to keep track of the damage taken?

So I'm making a simple 3D RPG game in Unity with a player and a bunch of enemies. What is the standard way to keep track of the damage taken in combat? I think the easiest way is to count damage everytime the attack animation is triggered, but how? How do I know whether an animation is triggered or not? Or is there any other way to do it? Please help, thanks in advance!
So you want to detect if the enemy hits you with a projectile/melee. The way to do that is attaching a collider to their weapon, you can do this by setting empty game objects as children of the weapon and attach individual collider components to them (Don’t do this unless you know how to make it not take multiple damages at once. Just for extra precision). Then what you want to do is for each/the collider hit the isTrigger check box so it has a check in it. Add a tag to the collider(s) that has a name like “damage” or “weapon”. Then open a script to attach to your player. Use OnTriggerEnter() to detect the weapon hitting your player:
...//the rest of your code before this.
public float health = 10f; //health value.
public float damageTick = 1f; //damage taken per hit
void OnTriggerEnter(Collider obj)
{
//for same damage per different weapon hit.
if (obj.GameObject.Tag == “damage”) //remember this is what the tag of the weapon was.
{
health -= damageTick;
//play the animation. You can do that.
}
//*optional* for different damage per weapon type.
if (obj.GameObject.Tag == “sword1”)
{
health -= sword1Damage; //make sure you have a variable for sword1Damage.
}
else if (obj.GameObject.Tag == “bow8”)
{
health -= bow8Damage; //make sure you have a variable for bow8Damage.
}
// add on to this if else, to make more weapons take different damage.
}
It's too expensive. If you have 10 enemies, then the calculations through the colliders will overload the system.
It's easier to calculate, when the user clicks on the attack button, create a primitive and see what objects are included in this primitive around it. Push them onto the stack. Further, if your attack is at a distance, you can count through the vectors of the nearest enemy, if the damage is massive, then you can set the hitting radius and inflict damage on all enemies in this zone using the observer pattern

Unity OnParticleTrigger() get Collider it collides with

I wanted to make a shot with a particle system and if one of the particles collides with something, then the opponent should get damage. I use the trigger function because I want the particles to continue flying after colliding. And in case you are wondering why I don't use a raycast: if I work with a raycast, the opponent gets harm without the particles arriving.
My Code:
private void OnParticleTrigger()
{
if (!hitObjects.Contains(other.gameObject))
{
other.GetComponent<IDamageable>().GetDamage(PlayerScript.instance.damage);
hitObjects.Add(other.gameObject);
}
}
where I would like to have the opponent's collider later, I have already inserted "other"
Make the projectile a game object with a child particle system that gets triggered once the projectile hits a target

unity2D: Make enemies ignore OnTriggerEnter2D when they are traveling down

I have two scripts, one attached to a gameobject and the other attached to an enemy prefab that is instantiated over time. The script attached to the gameobject uses OnTriggerEnter2D to detect when the enemy has entered, then the health bar for the object goes down by one. Iit works, the only problem is now is that because of the fact that the enemy comes up then walks back down, the enemy is colliding with the objects more than once which is not what I want.
I have tried things like using booleans to stop it colliding more than once but other prefabs enemies isn't able to collide with the gameobject because of the boolean is being set to true and not being set back to false. I don't want to use yield wait for seconds because enemies do spawn often and so it won't really look normal; I also tried onTriggerExit2D but you get the idea if I try that method. Is there any other way of detecting if an enemy has entered the objects collider damaging the object once but then when the enemy comes back down he ignores the collision (without turning off the enemies or the gameobject's collider) aka all instantiated enemies is able to collide with the gameobject when they are going up but not when they are coming back down.
Your best bet is to simply do a bool check on the monsters if they're going north or not. There are several ways to go about this. If you know where they are going you can simply compare where they are going to where they are and compare the y vector values. so something like this:
public bool monsterNorthChecker(){
if(monsterDestination.y > currentLocation.y){
return true;
}
else{
return false;
}
}
Then you can simply call that function OnTriggerEnter and verify if the monster is going north or not, if he is, take away his health. If you don't know his destination, you'll probably have to resort to more tedious means of determining destination direction. Something like comparing the y values of last frame's vector2 to this one and see which way he's moved.

Unity collision not being detected

I am learning to create a simple fps game in unity the problem is that the collision does not update itself for example initially when my player is on the ground console prints "floor" by "Debug.log(collision.gameObject)" but when it intersects other objects such as a cube console will print out "cube" but when I walk away from it , console does not change back to "floor" Why????
I am using transform.translate to move and jump and using method OnCollisionEnter for collision detection
OnCollisionEnter is triggered only when object enters the collider.
A) Make a list of all encountered objects by adding them when OnCollisionEnter happens and removing when OnCollisionExit happens. Then whenever you need to make sure you are on "floor" check it in the list.
B) Use OnCollisionStay and every frame you will be notified if you are touching the "floor".
Remember one thing, the other object you want to collide with need to have a collider component asigned, make sure of it. Join this with the previous answer.
I recommend to verify collision.
Here on simple example:
void OnCollisionEnter (Collision col){
if (col.gameObject){
Debug.Log("Object name : "+ col.gameObject.name);
}
}

SneakyJoystick question in Cocos2d

I currently have a SneakyJoystick up and running. It works fine, it moves the sprite around the screen. I already have it so it will flip the sprite's image when the joysticks degrees is to the left. But how do i make it so if it was moving left and then becomes inactive, the sprite won't automatically flip back? This is really confusing to me. Any help is appreciated. Thanks.
You must have a scheduled selector function in your program that checks the movement of your joystick after every second (or whatever the interval). I mean the code where you are checking if the joystick is towards left (joystick.velociy). So this selector will be called continuously, no matter your joystick is active or not. So when your joystick moves to left, you can flip the sprite and you can set define a boolean flag "isFlipped=true". And in the same selector method that you can check if joystick is not moving and "isFlipped=true" then you can flip back your sprite and set the flag false.
Generally speaking, it is advised to multiple the velocity by an arbitary amount and the delta value passed in to the update routine so that things move more smoothly. That will ensure that the final movement of the player is OK. I have seen people use a value between 50 and 200 for average movement.
eg,
CGPoint velocity = ccpMult(moveStick.velocity, 200 * delta);