Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by jjdoughboy · Apr 20, 2020 at 10:08 PM · colliderprojectiletower defense

I'm working on a tower defense game and my "enemy" game object is losing health before my "projectile" hits the box collider

In my tower defense game I have a turret that spawns a projectile that heads towards an game object with the tag "Enemy" when said enemy game object is in range of the turret but for some reason my enemy health will decrease before my projectile will hit the enemy collider I'm not to sure where my mistake is can someone tell me how I can fix this problem. I should mention that my enemy game object has a box collider and my projectile game object does not.

this is my projectile script

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class Projectile : MonoBehaviour
 {
     private Transform target;
 
     public float speed = 70f;
 
     public GameObject impactEffect;
 
     public int damage = 10;
 
     public float explosionRadius = 0f;
 
     public void Seek(Transform _target)
     {
         target = _target;
     }
 
     // Update is called once per frame
     void Update()
     {
         if (target == null)
         {
             Destroy(gameObject);
             return;
         }
         Vector3 dir = target.position - transform.position;
 
         float distanceThisFrame = speed * Time.deltaTime;
 
         if (dir.magnitude <= distanceThisFrame)
         {
             HitTarget();
             return;
         }
 
         transform.Translate(dir.normalized * distanceThisFrame, Space.World);
 
         transform.LookAt(target);
     }
 
     void HitTarget()
     {
 
         GameObject effectIns = (GameObject)Instantiate(impactEffect, transform.position, transform.rotation);
 
         Destroy(effectIns, 5f);
 
         if(explosionRadius > 0f)
         {
             Explode();
         }
 
         else
         {
             Damage(target);
 
             Destroy(effectIns);
         }
     }
 
     void Explode()
     {
         Collider[] colliders = Physics.OverlapSphere(transform.position, explosionRadius);
 
         foreach(Collider collider in colliders)
         {
             if(collider.tag == "Enemy")
             {
                 Damage(collider.transform);
             }
         }
     }
 
     void Damage(Transform enemy)
     {
         Enemy e = enemy.GetComponent<Enemy>();
 
         if(e != null)
         {
             e.TakeDamage(damage);
         }
 
         
     }
 
 
     void OnDrawGizmosSelected()
     {
         Gizmos.color = Color.red;
 
         Gizmos.DrawWireSphere(transform.position, explosionRadius);
     }
 
 }
 

and this is my enemy script

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.UI;
 
 public class Enemy : MonoBehaviour
 {
     public float startSpeed = 10f;
 
     public float speed;
 
     public float startHealth = 200f;
 
     private float health;
 
     public int moneyEarned = 10;
 
     public GameObject deathEffect;
 
     [Header("Health Bar")]
     public Image healthBar;
 
     void Start()
     {
         health = startHealth;
 
         speed = startSpeed;
     }
 
 
     //enemy damage
     public void TakeDamage(float amount)
     {
         health -= amount;
 
         healthBar.fillAmount = health / startHealth;
 
         if (health <= 0)
         {
             Die();
         }
     }
 
 
     public void Slow (float pct)
     {
         speed = startSpeed * (1 - pct); 
     }
 
 
     void Die()
     {
         GameObject audioManagerObject = GameObject.Find("AudioManager");
         AudioManager audioManagerScript = audioManagerObject.GetComponent<AudioManager>();
         audioManagerScript.PlayEnemyDeath();
 
         //Enemy prefab >> Death effect >> plug in death effect
         GameObject effect = Instantiate(deathEffect, transform.position, Quaternion.identity);
 
         Destroy(effect, 1f);
 
         PlayerStats.Money += moneyEarned;
 
         WaveSpawner.EnemiesAlive--;
 
 
         Destroy(gameObject);
     }
 }
 
Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image icehex · May 16, 2020 at 03:10 PM 0
Share

@jjdoughboy is your issue resolved?

3 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by icehex · May 05, 2020 at 07:08 PM

Could it be here?

          if (dir.magnitude <= distanceThisFrame)
          {
              HitTarget();
              return;
          }

You call HitTarget before you update the projectile's position below that part. It's still in 1 frame so that should be not noticeable... but just to check you could try changing to:

      void Update()
      {
          if (target == null)
          {
              Destroy(gameObject);
              return;
          }
          Vector3 dir = target.position - transform.position;
  
          float distanceThisFrame = speed * Time.deltaTime;

          transform.Translate(dir.normalized * distanceThisFrame, Space.World);
  
          transform.LookAt(target);
  
          if (dir.magnitude <= distanceThisFrame)
          {
              HitTarget();
              return;
          }

      }


To have your projectile be destroyed, it needs a call for Destroy on itself once it applies damage. This here should do it, or get you close:

      void Damage(Transform enemy)
      {
          Enemy e = enemy.GetComponent<Enemy>();
  
          if(e != null)
          {
              e.TakeDamage(damage);
              Destroy(gameObject);
          }
  
          
      }

Also if you do the above, you need to correct your HitTarget function so the effect is Destroyed before your projectile destroys itself ---

      void HitTarget()
      {
  
          GameObject effectIns = (GameObject)Instantiate(impactEffect, transform.position, transform.rotation);
  
          Destroy(effectIns, 5f);
  
          if(explosionRadius > 0f)
          {
              Explode();
          }
  
          else
          {
              Destroy(effectIns);
 
              Damage(target);
          }
      }
  

Also the script only looks at the collider if explosionRadius is greater than zero. Otherwise it considers the enemy to be hit if the enemy's position is within the projectile's reach this frame. if you want to use collision, you'll need to take out the dir.magnitude

  void OnCollisionEnter(Collision collision)
  {
      if (collision.collider.tag == "Enemy")
      {
          HitTarget();
      }
      else
      {
          // something other than the enemy was collided with
      }
  }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by jjdoughboy · May 05, 2020 at 08:50 PM

@icehex I made the switch but its kind've hard to tell if it worked is there a place a can put a Debug.(Log) to see if it hit the collider. My projectile every other frame will go to the enemy position but the projectile is suppose to destroy itself after hitting the collider and deal damage so is there anything else I need to do at this stage to fix this

Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image jjdoughboy · May 05, 2020 at 09:35 PM 0
Share

@icehex it seems that my original projectile script has my projectile go to the enemy game object 's position but doesn't destroy itself and will update to the enemy position again. your suggestion has made my projectile get to the enemy game object's position and the next frame the projectile will jump to a random position somewhat close to the enemy position so I think my original script will work better. I just need to figure out how to make my projectile recognize the enemy collider and deal damage and than destroy itself. I added a Debug.Log to tell me if the collider got hit like @boss2070301 suggested and never got the popup so my projectile doesn't hit the collider as if the projectile doesn't think the collider exists.

avatar image icehex jjdoughboy · May 05, 2020 at 10:46 PM 0
Share

The script only looks at the collider if explosionRadius is greater than zero. Otherwise it considers the enemy to be hit if the enemy's position is within the projectile's reach this frame. if you want to use collision, you'll need to take out the dir.magnitude

     void OnCollisionEnter(Collision collision)
     {
         if (collision.collider.tag == "Enemy")
         {
             HitTarget();
         }
         else
         {
             // something other than the enemy was collided with
         }
     }
avatar image jjdoughboy · May 06, 2020 at 05:08 PM 0
Share

@icehex just to be sure I would replace the following with the on collision enter function correct

 if (dir.magnitude <= distanceThisFrame)
          {
              HitTarget();
              return;
          }
  
          transform.Translate(dir.normalized * distanceThisFrame, Space.World);
  
          transform.LookAt(target);
      }

avatar image jjdoughboy · May 06, 2020 at 07:03 PM 0
Share

ok so my explosion Radius is what caused my projectile to actually hit the collider so now that works but now my projectile is not destroying itself after it hits the collider.

avatar image icehex jjdoughboy · May 06, 2020 at 07:12 PM 0
Share

Hi, I think I know why your object isn't going away. Check out my answer above, for clarity/conciseness I've combined my recommendations into the answer.

avatar image
0

Answer by boss2070301 · May 05, 2020 at 08:55 PM

@jjdoughboy I think you should put it here like so

         foreach(Collider collider in colliders)
          {
              if(collider.tag == "Enemy")
              {
                  Damage(collider.transform);
                 Debug.Log("I got hit!");
              }
          }
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image jjdoughboy · May 05, 2020 at 09:16 PM 0
Share

@boss2070301 I added the debug so now know that my projectile is not hit the collider even though my projectile is going to the enemy game object position.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

167 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How can i make a projectile attack travel through multiple enemies dealing damage to all of them? 1 Answer

Colliders won't work (Closed) 2 Answers

Distance to object I am looking towards 1 Answer

Fired projectile collision with player issue 1 Answer

Projectiles, their speed, and collisions 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges