Game Development Stack Exchange is a question and answer site for professional and independent game developers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

i'm working on a basic Top-Down Shooter, kind of like... Nuclear Throne or The Binding of Isaac, but since i'm new to Unity, and it's something i'm required to do for school, i'm quite in a rush so i didn't have enought time to look at all the documentation i should've, so i apologize if i'm asking too much.

The thing is like this : I have the Player that moves around, and a Sword that rotates in the mouse direction, clicking the mouse activates a Trigger Collider around the Sword, and it's suposed to Hit all enemies inside its range

The problem :

How should i "plan" my Scripts? i mean, i have a Sword script that handles the click and the OnTriggerEnter, and it should, somehow (Working on it), check if it hit an enemy, and access the Enemy Script to modify its Life Points, but how do handle the GameObject Enemy = GameObject.FindObjectWithTag("Enemy")[...]? since this just gives me one enemy...

I apologize again since i'm really bad at focusing on one point, i dont think it's neccessary to provide all the code since i dont really need you to provide me with code, just... guidelines or a basic pattern of doing this kind of things.

Thank you a lot!.

share|improve this question
    
Perhaps GameObject.FindGameObjectsWithTag("Enemy")? It should return a list of enemies. – KevLoughrey Nov 16 '15 at 13:56
    
@KevLoughrey Yeah, i thought about that, but i found myself unable to work with the List of GameObjects this returns... – DS94 Nov 16 '15 at 15:18
up vote 2 down vote accepted

The start of your reasoning is good, but you get lost when trying to reduce the enemy HP. Let's restart from the Sword:

In your Sword script, you have a function OnTriggerEnter2D. In this function, you can check if the collider is of type "Enemy", and, if so, apply the "damage" function:

void OnTriggerEnter2D(Collider2D collider)
{
    GameObject objectCollided = collider.gameObject;  // Get a reference to the object hit
    if (objectCollided.CompareTag("Enemy")) // If the object is an enemy
    {
        objectCollided.getComponent<EnemyController>().doDamage(swordStrength); // Here you call the enemy function that will lower his health
    }
}

A more advanced solution would be to generalize this behavior for any objects that are damageable. Let's imagine that, in the future, you want to add destructible items, like a destructible wall. This wall would have HP, get damaged, and die when its HP gets to 0, just like an Enemy.

This is achievable via a script component "Damageable" that you will add to any prefabs you have that are damageable:

public class Damageable : MonoBehavior
{
    public int maxHP;       // This has to be set in the inspector
    private int currentHP;

    void Start()
    {
        currentHP = maxHP;
    }

    void doDamage(int damage)
    {
        currentHP -= damage;
        if (currentHP <= 0)
            Destroy(gameObject);
    }
}

By attaching this script to a prefab, it becomes damageable. Then, in your Sword script:

void OnTriggerEnter2D(Collider2D collider)
{
    GameObject objectCollided = collider.gameObject;  // Get a reference to the object hit
    Damageable damageableComponent = objectCollided.getComponent<Damageable>();

    if (damageableComponent) // If the object is damageable
    {
        damageableComponent.doDamage(swordStrength); // Here you damage the object, without knowing which type it is
    }
}

I hope this helps.

share|improve this answer
    
Thank you for the Code Example, just one question. Is accessing, or assigning the GameObjects inside the OnTriggerEnter the standard or best way of doing this kind of things, or just a workaround? – DS94 Nov 16 '15 at 15:34
    
It is a standard approach. You access the component inside your Sword script and call the function with the minimum information your Enemy need. Then, the processing is done inside the Enemy script. – Sheikz Nov 16 '15 at 15:39
    
Just be careful with this approach, OnTriggerEnter2D is not always called if one trigger collider is moved into another with translate. Typically at least one of the colliders involved needs to be attached to a Rigidbody which is either moved with physics or marked isKinematic, to ensure the trigger collision is detected. – DMGregory Nov 16 '15 at 15:47

Why would you? Just make a script that controls individual enemies.

But in case you want to, you can construct a class named Enemy (i.e.) and keep a list of that class'es instances, so you can handle every Enemy by running a foreach loop on that list.

The class may contain GameObject referance of enemy, so you won't need to build a dictionary for it.

share|improve this answer
    
Right now, the Enemies have a EnemyController Script that allows them to move individually, my problem was with the Sword Script, since i didnt really know how to approach the problem, but i guess that adding GameObject.FindGameObjectsWithTag("Enemy") , as @KevLoughrey stated, then looping it for the .GetComponent<>(); for each one could work, so i can access the Methods in the Enemy Script from the Sword Script. – DS94 Nov 16 '15 at 15:27
    
Yes, but you can't store data about enemies in your script this way. (actually you can, but with hundreds of lines of code) – S. Tarık Çetin Nov 16 '15 at 15:29

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.