Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Shooting and colliding with enemies

Discussion in 'Scripting' started by epochplus5, Nov 16, 2020.

  1. epochplus5

    epochplus5

    Joined:
    Apr 19, 2020
    Posts:
    677
    so if you want to be able to collide with an enemy (that a collision causes damage, i have a health bar)
    and be able to shoot it. Do you need 2 colliders on the enemy? 1 on the target for physics and one for a trigger?

    how can you set this up?
     
  2. Terraya

    Terraya

    Joined:
    Mar 8, 2018
    Posts:
    646
    You should do both with one Collider :eek:
     
    epochplus5 and adamgolden like this.
  3. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,464
    You could use your enemy's OnCollisionEnter for both,
    Code (CSharp):
    1. void OnCollisionEnter(Collision collision)
    2. {
    3.   Projectile projectile = collision.gameObject.GetComponent<Projectile>();
    4.   if (projectile != null)
    5.   {
    6.     Debug.Log("hit by projectile: " + projectile.name);
    7.   } else {
    8.     Player player = collision.gameObject.GetComponent<Player>();
    9.     if (player != null)
    10.     {
    11.       Debug.Log("hit by player: " + player.name);
    12.     }
    13.   }
    14. }
    You would replace "Player" class in the above with your player's base class, and Projectile with your projectile base class.

    You can do the same thing with a Trigger, using OnTriggerEnter(Collider other) and other.gameObject.

    To damage your player, in your player class you could have a public void CollidedWithEnemy(Enemy enemy); then in the example above you could call player.CollidedWithEnemy(this); where the "hit by player" line is, etc.

    Edit: Note that you could check collision in the Player class, but then you have to evaluate for anything the player might hit at all in your game you might want to react to and the code will bloat up fast without additional work. If you do it in the enemy as above, your code only needs to consider the player and projectiles (and you could also expand the same thing to have an enemy take damage from another enemy or something falling on it etc.). So I think it's easier to just call a function on the player class if there's something the player class needs to know.
     
    Last edited: Nov 16, 2020
    epochplus5 likes this.
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,336
    Adding onto what @Terraya and @polemical say above (which is spot-on), I like fast bullets and don't like the chance of passing through stuff, so I tend to do my bullets with raycasting.

    Each frame I figure how much the bullet will move and then raycast ahead of it to see if I hit a collider. If I did then I know the bullet is toast and I can spawn a bullet splash prefab precisely at the impact point from the raycast hit.

    Finally when you hit something, check if it can accept damage. Interfaces are awesome for this purpose, something like an
    IDamageable
    interface. That way every enemy can implement its own notion of how it can be damaged. Look up tutorials on using interfaces in Unity; they're pretty powerful.
     
  5. epochplus5

    epochplus5

    Joined:
    Apr 19, 2020
    Posts:
    677
    Thanks all!!!
     
    adamgolden and Kurt-Dekker like this.
  6. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,464
    Adding to what @Kurt-Dekker said - if you won't be raycasting for projectiles as suggested, make sure the projectile's Rigidbody component has Collision Detection set to Continuous Speculative. "The algorithm is speculative because it picks all potential contacts during the next physics step. All contacts are then fed into the solver, which makes sure that all contact constraints are satisfied so that an object does not tunnel through any collision." (quoted from here).
     
    epochplus5 and Kurt-Dekker like this.
  7. epochplus5

    epochplus5

    Joined:
    Apr 19, 2020
    Posts:
    677
    Sorry guys inexperienced and learning here: "You would replace "Player" class in the above with your player's base class, and Projectile with your projectile base class." what does this mean?

    is that just doing:
    public GameObject projectile;

    and then dragging the object into the slot?
     
  8. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,464
    You would make a new script somewhere like Assets/Scripts/ called "Player.cs" then put this code in it:
    Code (CSharp):
    1. using UnityEngine;
    2. public class Player : MonoBehaviour
    3. {
    4.   public void CollidedWithEnemy(Enemy enemy)
    5.   {
    6.     Debug.Log("hit enemy: " + enemy.name);
    7.   }
    8. }
    Then select your player GameObject and in the Inspector click Add Component and select Player.
    You create a base Projectile class the same way, and add that component to your projectile prefab.
    Also create a base Enemy class the same way, and add that component to your enemy, with the OnCollisionEnter function posted earlier.

    I say base class because typically you would extend from it, for example once you have an Enemy class, you might create a
    public class BossEnemy : Enemy
    which would have all the same stuff as your base class plus more (and likely overriding virtual functions defined in the base). That's getting more advanced if you're just starting, but it's important to learn about inheritance, base classes and overriding virtual functions when you get the chance.
     
    epochplus5 likes this.
  9. epochplus5

    epochplus5

    Joined:
    Apr 19, 2020
    Posts:
    677
    Yes i know about OOP and inheritence in standard programming but have never applied it in Unity thanks for your help.
     
    adamgolden likes this.
  10. epochplus5

    epochplus5

    Joined:
    Apr 19, 2020
    Posts:
    677
    Should i just add this:

    1. using UnityEngine;
    2. public class Player : MonoBehaviour
    3. {
    4. public void CollidedWithEnemy(Enemy enemy)
    5. {
    6. Debug.Log("hit enemy: " + enemy.name);
    7. }
    8. }
    to my existing player script, or is it better to have a separate script for this function?
     
  11. Terraya

    Terraya

    Joined:
    Mar 8, 2018
    Posts:
    646
    It depends on how flexible you want to be and what the goal of everything is,

    you could add this to your existing player script it would work,
    or you make a new script where you handle the health / damage :)
     
    adamgolden likes this.
  12. epochplus5

    epochplus5

    Joined:
    Apr 19, 2020
    Posts:
    677
    best to keep it separate i think, my player script is growing pretty big
     
  13. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,464
    That's the balance right there - something functional vs. tailored. A few lines gets it working, but you might spend a few hundred (or thousand) on a system that's reasonably abstract, robust and optimized for your game in particular. An impact with an enemy has a number of considerations - spawning particles/effects, playing audio, handling damage, updating your HUD for related changes to stats or points, setting flags (i.e. maybe that the player has destroyed a particular enemy), mission/story/dialogue progression, maybe network/multiplayer-related and so on.

    Also be wary of needlessly over-complicating - by the time you make the best system ever to handle all that, but you could have finished a game :D as per the quote, depends on your goals. If you're just learning, just have fun (imho).
     
    epochplus5 likes this.
  14. epochplus5

    epochplus5

    Joined:
    Apr 19, 2020
    Posts:
    677
    Its only a 2D shooter, so not very complicated but in the same token its best to learn "The best ways and practices" off the bat so that the same principals can be applied to later projects.
     
  15. epochplus5

    epochplus5

    Joined:
    Apr 19, 2020
    Posts:
    677
    ok firstly, im going to change my shooting to raycasts, will let you know how i get on.
    Does a raycast have to be in a static class? The code monkey tutprial im watching he creates a static class. Is that neccesary, i just want to apply it in my player script so that i dont have to get the controls exported to the new script etc. Would be simpler to keep the shooting on the player main script.
     
    Last edited: Nov 17, 2020
  16. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,464
    Indeed - I'm still quite new to Unity myself. I'd say the Profiler is something to learn asap if you haven't yet, it's easier to keep things in good order as you go as opposed to wondering what's going on later and having to look over / clean stuff up. Also, Addressables are worth a look - they simplify asset management, you can group assets to be loaded or downloaded together, drop-drop assets between Local or Remote groups - it's great.
    Good luck with your project :)
     
  17. epochplus5

    epochplus5

    Joined:
    Apr 19, 2020
    Posts:
    677
    How come in the tutorial this:

    public void FireLaser(Vector3 shootPosition, Vector3 shootDirection)
    {
    RaycastHit2D raycastHit2D = Physics2D.Raycast(shootDirection, shootDirection);
    if (raycastHit2D.collider != null)
    {
    //Hit
    Target target = raycastHit2D.collider.GetComponent<Target>();
    }
    }

    is fine in his editor, but in mine Target is red and underlined?
     
  18. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,464
    That example expects a Target.cs script, at least this:
    Code (CSharp):
    1. using UnityEngine;
    2. public class Target : MonoBehaviour
    3. {
    4. }
    Then for whatever object you want to hit, in the Inspector click Add Component and select Target.
     
  19. epochplus5

    epochplus5

    Joined:
    Apr 19, 2020
    Posts:
    677
    Hey Kurt "spawn a bullet splash prefab" whats a bullet splash prefab?
     
  20. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,336
    Whatever you want it to be!

    Shower of sparks, puff of smoke, etc.
     
  21. epochplus5

    epochplus5

    Joined:
    Apr 19, 2020
    Posts:
    677
    oh i see any "non hit" effect