1
\$\begingroup\$

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!.

\$\endgroup\$
  • \$\begingroup\$ Perhaps GameObject.FindGameObjectsWithTag("Enemy")? It should return a list of enemies. \$\endgroup\$ – KevLoughrey Nov 16 '15 at 13:56
  • \$\begingroup\$ @KevLoughrey Yeah, i thought about that, but i found myself unable to work with the List of GameObjects this returns... \$\endgroup\$ – DS94 Nov 16 '15 at 15:18
5
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ 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? \$\endgroup\$ – DS94 Nov 16 '15 at 15:34
  • \$\begingroup\$ 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. \$\endgroup\$ – Sheikz Nov 16 '15 at 15:39
  • \$\begingroup\$ 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. \$\endgroup\$ – DMGregory Nov 16 '15 at 15:47
0
\$\begingroup\$

Enemy script

void HandleHits(Collision2D col) {

  if(col.gameObject.tag == "beam") {
    Destroy(col.gameObject);
  }

  if(col.gameObject.tag == "beam") {
    timesHit += 1;
    GameObject smokePuff = Instantiate (
      bulletHitParticle, 
      transform.position, 
      Quaternion.identity) as GameObject;
  }

  if (Ball.PowerBallActive && col.gameObject.tag !="Extra Ball" ) {
    timesHit+=50 ;
  }

  timesHit++;
  int maxHit = hitsSprites.Length + 1;
  if(timesHit >= maxHit) {
    if(isBreakable) {
      brickCount --;
    }

    levelmanager.BrickDestroyed();
    PuffSmoke();
    GameObject newCoin = Instantiate(
      coin, 
      transform.position, 
      Quaternion.identity) as GameObject;
    Destroy(gameObject);
    Camera.main.GetComponent<CameraShaker>().VibrateForTime(.3f);
  }
}
\$\endgroup\$
  • 1
    \$\begingroup\$ Welcome to Game Development! We generally like to see explanations of what's going on with the code. Blocks of code are generally not as good as blocks of code with good documentation. You might want to edit your post to add more details of what's going on and why it helps the question asked. \$\endgroup\$ – Alexandre Vaillancourt Jul 17 '18 at 18:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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