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.
Related
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
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
I'm trying to use the EventManager and according Events to calculate the distance between objects, and to do something when enough objects are close to the target.
I watched video's on YouTube and searched for examples on Google, but I couldn't find something that looks like what I want. Of course I also watched the explanation videos of Events in general, but I just don't get it. They are all English, which is not my native language, this makes it difficult to understand. So, also sorry for any grammar mistakes. They often talk so fast. So please don't think I'm lazy, I have searched for hours but I just don't get it.
I have one target object, and several enemy objects. This enemy objects have the tag 'Enemy'. The target object can move. I made a coroutine, so when the target moves, the enemies follow, until a distance of 0.5. But from the moment that they reached the distance of 0.5, the enemies won't move anymore. Instead they should also follow the target when they already reached their target position. So to prevent this, I changed the while(Vector3.Distance(transform.position, target.position) > 0.5f) in while 1 > 0, (so just always) and I deleted the part of the code that was about 'after the while loop'. But this is probably not the right way.
So, in short, I want to make an Event that keeps track of when enemies reaches or loses their target position. When three enemies are on their target position, I want to make them blue.
Could anyone show me how I can do this? I don't get it now, but when I see how it works I can use this for more events in the game.
I think You can use trigger collider, just make it bigger then your target object, then do all you want about enemies in methods OnTriggetEnter, OnTriggerStay
As an another technique you can use raycasts. Raycasts will provide you more performance than colliders.
You can locate your raycasts in your target position, in case your raycast hit the enemy then make them blue. For Example;
public LayerMask enemyLayer;
bool isTouch = false;
public bool isTouched(){
if (Physics.Raycast(transform.position,-Vector3.up,1f,enemyLayer)) {
isTouch = true;
return isTouch ;
}
return !isTouch ;
}
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);
}
}
I'm making a platformer (sidescroller), and right now I'm making a grenade-launcher for the player.
It spawns grenades which is a prefab, this prefab has a Circle Collider 2D which is the blast radius for the explosion.
When a grenade is spawned I run this (amongst other things);
// Add the initial force
rBody.AddForce(new Vector2(forceX, forceY) *300f);
Invoke("Explode", 2.5f);
I'm having trouble figuring out how I should handle the Explode function.
I would like to find all the GameObjects that are colliding with the Circle Collider 2D at that point, but I can't find a way to do it.
I would like to be able to do something like this (not real code but you understand what I'm trying to do)
void Explode () {
collidingObjects = circleCollider.getCollisions();
foreach(collidingObject as entity) {
if(entity = 'player')
player.pushLeftOrRight()
elseif(entity = 'enemy')
grenade.dealDamage(grenade.damage)
}
Debug.Log("Explode");
Destroy(gameObject);
}
I'm guessing that it wouldn't work so can anyone point me in the right direction?
In your grenade's script, use OnTriggerEnter or OnCollisionEnter to log collisions; basically just have a HashSet for each grenade that is updated and keeps track of what it is colliding with. Then Explode just has to iterate through this set when you call it.