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 pufffuryy · Aug 18, 2019 at 11:54 PM · targetingtower defense

How to make a targeting system to target an enemy furthest on the track

I am making a tower defense game. in short, my towers current targeting system make it so that they target the closest enemy to themselves. i am trying to make a targeting system that sets the towers target to the enemy furthest on the track. i currently have a progress variable that tracks their progress on the track by multiplying their time alive by their speed. because i have different types of enemies, this task proves difficult to me and was wondering if anybody could help me

    void UpdateTarget()
     {
         GameObject[] enemies = GameObject.FindGameObjectsWithTag(enemyTag);
         float shortestDistance = Mathf.Infinity;
         GameObject nearestEnemy = null;
         foreach (GameObject enemy in enemies)
         {
             float distanceToEnemy = Vector3.Distance(transform.position, enemy.transform.position);
             if (distanceToEnemy < shortestDistance)
             {
                 shortestDistance = distanceToEnemy;
                 nearestEnemy = enemy;
             }
         }
 
         if (nearestEnemy != null && shortestDistance <= range)
         {
             target = nearestEnemy.transform;
         }
         else
         {
             target = null;
         }
     }

let me know if you need any more information about the code for example the progress variable

Comment
Add comment
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

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Cornelis-de-Jager · Aug 19, 2019 at 03:53 AM

Create a base enemy class that has functions and attributes that will all enemies will have.

 public abstract class Enemy : MonoBehaviour {
     
     public float health;
     public float timeAlive;
     public float speed;
     
     public Enemy (){
         timeAlive = 0;
     }
     
     /// <summary>
     /// Call this in FixedUpdate
     /// </summary>
     void  OnTick () =>
         timeAlive += Time.deltaTime;
         
     /// <summary>
     /// Calculates the target priority for a certai nenemy
     /// </summary>
     public abstract float GetTargetPriority ();
 }

Below we will use custom enemy classes derived from the base evenmy class. Attach them to your enemies (1 per enemy) You can create as many of your own as you like, below i created an enemy that has armor and one that keeps ketting faster and faster. Note they derive from the Enemy abstract class. You can customize their behaviour this way and add write custom priority functions to suite your needs.

 public class SpeedIncreasingEnemy : Enemy {
     
     void FixedUpdate () {
         // Do the on tick function
         OnTick();
         
         // Increase speed slightly every tick
         speed += Time.deltaTime / 2;
     }
     
     public float GetTargetPriority () {
         return timeAlive * speed + health;
     }
 }

 public class ArmoredEnemy : Enemy {
     
     public float armor;
     
     void FixedUpdate () => OnTick();
     
     public float GetTargetPriority () {
         return timeAlive * speed + health + armor;
     }
 }

 ... Create your own custom classes
 

Now we can easily select target priority through your script. I made small changes that should work

 void UpdateTarget()
 {
     GameObject[] enemies = GameObject.FindGameObjectsWithTag(enemyTag);    
     GameObject nearestEnemy = enemies.FirstOrDefault(); // using System.Linq;
     
     foreach (GameObject enemy in enemies)
     {
         if (nearestEnemy == enemy)
             continue;
             
         if (nearestEnemy.GetComponent<Enemy>().GetTargetPriority() < enemy.GetComponent<Enemy>().GetTargetPriority())
             nearestEnemy = enemy;
         
     }
  
     // This code is fine
     if (nearestEnemy != null && shortestDistance <= range)
     {
         target = nearestEnemy.transform;
     }
     else
     {
         target = null;
     }
 }
Comment
Add comment · Show 6 · 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 pufffuryy · Aug 19, 2019 at 03:46 PM 0
Share

I am receiving the error 'ArmoredEnemy' does not implement inherited abstract member 'Enemy.GetTargetPriority()'

when i try and make the armored enemy class, also when you are making your own custom classes, do you make them inside the enemy class? @Cornelis-de-Jager

avatar image Cornelis-de-Jager pufffuryy · Aug 19, 2019 at 09:26 PM 0
Share

So the error you are receiving is because the Enemy.GetTargetPriority() function should be implemented in your ArmoredEnemy class. I might have speleld it incorrectly and thats why it is giving an error. But let me explain abstract classes. They are basically a class that you can inherrit from, but you can't use directly. You say that the members in the class are abstract, meaning you only give the function names, you have to fill out the detail in the other classes that inherrit from it. But you have to implement those functions.


Think of it like a requirements list. Or like an interface if you have ever worked with those. You list all the functions that need to be implemented in the abstract class/interface. Then when you extend/inherrit from it you simply need to implement those functions.


Where a interface and abstract class differs, is that a abstract class can contain variables and ACTUAL non abstract functions that can be called from child classes.


An no, don't make them inside the Enemy class. Simply create new scripts like you would with any other. To make them a child of the Enemy class / Or inherrit from the enemy class you simple change this:

 public class $$anonymous$$yCustomClass : $$anonymous$$onobehaviour {...}

to this:

 public class $$anonymous$$yCustomClass : Enemy {...}

That will tell Unity that $$anonymous$$yCustomClass is a child class of Enemy / Inherrits from the Enemy class.

avatar image pufffuryy Cornelis-de-Jager · Aug 19, 2019 at 10:29 PM 0
Share

okay thanks, that will work but rn im just going to work on the gameplay of it and later i will implement that system. thanks

avatar image pufffuryy · Aug 19, 2019 at 03:52 PM 0
Share

I also receive the error when i change the class enemy to abstract

The class named 'Enemy' is abstract. The script class can't be abstract! UnityEngine.Object:Instantiate(Transform, Vector3, Quaternion) waveSpawner:SpawnEnemy01() (at Assets/Scripts/waveSpawner.cs:51)

but when i dont have it abstract this error pops up

'Enemy.GetTargetPriority()' is abstract but it is contained in non-abstract class 'Enemy' 79 Active

avatar image Cornelis-de-Jager pufffuryy · Aug 19, 2019 at 09:34 PM 0
Share

Ok so this a strange thing Unique to Unity only. You can't Instantiate from a abstract class. Ins$$anonymous$$d create an abstract function class Spawn:

 // In abstract class
 public abstract void Spawn();

 // In inherited class
 public void Spawn() { ... }



Alternatively, you can remove all abstract references from your class and just make it a normal class - you can still inherit from it just like you would from an abstract class. And is a bit easier to start off with.


Your enemy class will then look like this:

  public class Enemy : $$anonymous$$onoBehaviour {
      
     public float health;
     public float timeAlive;
     public float speed;
      
     public Enemy (){
         timeAlive = 0;
     }
      
     /// <summary>
     /// Call this in FixedUpdate
     /// </summary>
      void virtual OnTick () =>
          timeAlive += Time.deltaTime;
          
     /// <summary>
     /// Calculates the target priority for a certai nenemy
     /// </summary>
     public virtual float GetTargetPriority (){
         return timeAlive * speed + health;
     }
 }

This way all your child classes already has the GetTargetPriority and will fix any errors you previously got from it. But if you want to customize it, then this is how it will look (Using Armored Enemy class):

 public class ArmoredEnemy : Enemy {
      
     public float armor;
      
     void FixedUpdate () => OnTick();
      
     // Notice the OVERRIDE statement
     // The parent class needs to be virtual to be able to be Overriden
     public override float GetTargetPriority () {
         return timeAlive * speed + health + armor;
     }
 }


avatar image pufffuryy Cornelis-de-Jager · Aug 19, 2019 at 10:28 PM 0
Share

okay thanks, that will work but rn im just going to work on the gameplay of it and later i will implement that system. thanks

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

108 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

Related Questions

TowerDefense Game, shooting at Target! 2 Answers

My Tower is acting weird (shooting at one enemy, killing different enemy) 0 Answers

How to determine a "cone of influence" used for targeting an object. 2 Answers

Combat Script 2 Answers

How to save position of camera 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