Search Unity

iterate through overlapsphere array

Discussion in 'Scripting' started by ialokinmloh, Sep 13, 2019.

  1. ialokinmloh

    ialokinmloh

    Joined:
    Feb 23, 2019
    Posts:
    4
    Hi all!

    I've only been using unity or even coding in general for 2 weeks, so sorry if the solution to this is super obvious to you all. This is my first post to the forum, as I am desperate for a solution.

    I'm trying to create a targeting system for a hack and slash game using an overlap sphere, but I haven't been able to find a way to iterate through items in the array. So far the only 'working' targeting system only detects and selects the closest enemy (highlighted in green), but I'd like to be able to buttondown and move to the next enemy in the array.

    What is the best way to move my through items in an overlapsphere array to reassign my currentTarget?

    I've tried a few things with limited success... sometimes it jumps between targets, but inconsistently.

    Here is my code thus far (be prepared for some hacky garbage):

    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3. public class Targeting : MonoBehaviour
    4. {
    5.     public GameObject currentTarget;
    6.     public GameObject player;
    7.     public bool lockedOn;
    8.     public float sphereRadius;
    9.     public LayerMask layerMask;
    10.     private Vector3 origin;
    11.     private Vector3 direction;
    12.     public Collider[] enemyList;
    13.  
    14.     private void Start()
    15.     {
    16.         lockedOn = false;
    17.  
    18.     }
    19.     private void Update()
    20.     {
    21.         if (Input.GetButtonDown("Fire2"))
    22.         {
    23.             if(lockedOn== false)
    24.             {
    25.                 CollectTargetArray();
    26.                
    27.             }
    28.             else if (lockedOn == true)
    29.             {
    30.                 DumpTarget();
    31.             }
    32.         }
    33.     }
    34.     public void CollectTargetArray()
    35.     {
    36.         origin = transform.position + transform.up;
    37.         Collider[] enemyList = Physics.OverlapSphere(origin, sphereRadius, layerMask);
    38.         Array.Sort(enemyList, new DistanceComparer(transform)); //Sorted by Distance
    39.        
    40.         currentTarget = enemyList[i].transform.gameObject;
    41.         player.GetComponent<CharController>().isTargetLocked = true;
    42.         lockedOn = true;
    43.        
    44.         //List all potential targets
    45.         foreach (Collider hit in enemyList)
    46.         {
    47.             Debug.Log(hit.name);
    48.         }
    49.     }
    50.  
    51.     void DumpTarget()
    52.     {
    53.         Debug.Log(currentTarget.transform.gameObject.name + " is target dumped.");
    54.         currentTarget = null;
    55.         lockedOn = false;
    56.         player.GetComponent<CharController>().isTargetLocked = false;
    57.     }
    58.     void OnDrawGizmosSelected()
    59.     {
    60.         Gizmos.color = Color.red;
    61.         Debug.DrawLine(origin, origin);
    62.         Gizmos.DrawWireSphere(origin, sphereRadius);
    63.     }
    64. } //END OF SCRIPT
     

    Attached Files:

  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,187
    I might be missing it, but where are you getting the variable "i" from that you are using to set your currentTarget?

    Also, if the array is already sorted, you should be able to just grab entry 0 to get the nearest enemy, assuming that is how your sort works.
     
  3. ialokinmloh

    ialokinmloh

    Joined:
    Feb 23, 2019
    Posts:
    4
    Oops, yeah, "i" was a remnant of something i was using to try and move through the array, but it wasn't consistently working - sometimes it would grab another target, but then stopped working all together.

    Right now the 'working' version is grabbing the nearest enemy, but I am looking for a function or mechanism that will let me go through to the next array item on a button press, then return to item 0 after it is through.
     
  4. ialokinmloh

    ialokinmloh

    Joined:
    Feb 23, 2019
    Posts:
    4
    Well, I got it working and going through different items on the array. For some reason it didn't like it when I used a separate function to actually make the change in target and switch all the bools and stuff.... but oddly, if I repeated the code in without referring to another function, it seems to work fine.

    Here is the working code. Still open to advice on how to clean it up, or an explanation of why I had to repeat the code in all the if statements instead of referring to another function!


    Code (CSharp):
    1. public class Targeting : MonoBehaviour
    2. {
    3.  
    4.     public GameObject currentTarget;
    5.     public GameObject player;
    6.  
    7.     public bool lockedOn;
    8.  
    9.     public float sphereRadius;
    10.  
    11.     public LayerMask layerMask;
    12.  
    13.     private Vector3 origin;
    14.     private Vector3 direction;
    15.  
    16.     public Collider[] enemyList;
    17.     public ArrayList[] targetList;
    18.     public int i;
    19.    
    20.  
    21.     private void Start()
    22.     {
    23.         lockedOn = false;
    24.         i = 0;
    25.     }
    26.  
    27.     private void LateUpdate()
    28.     {
    29.         if (currentTarget == null)
    30.         {
    31.             lockedOn = false;
    32.             player.GetComponent<CharController>().isTargetLocked = false;
    33.         }
    34.  
    35.         if (Input.GetButtonDown("Fire2"))
    36.         {
    37.             CollectTargetArray();
    38.         }
    39.         if (Input.GetButtonDown("Fire3"))
    40.         {
    41.             DumpTarget();
    42.         }
    43.     }
    44.  
    45.     public void CollectTargetArray()
    46.     {
    47.         origin = transform.position + transform.up;
    48.         Collider[] enemyList = Physics.OverlapSphere(origin, sphereRadius, layerMask);
    49.         Array.Sort(enemyList, new DistanceComparer(transform)); //Sorted by Distance
    50.  
    51.         if (!lockedOn)
    52.         {
    53.             currentTarget = enemyList[i].transform.gameObject;
    54.             player.GetComponent<CharController>().isTargetLocked = true;
    55.             lockedOn = true;
    56.         } else if (lockedOn)
    57.         {
    58.             if (i >= enemyList.Length - 1)
    59.             {
    60.                 i = 0;
    61.                 currentTarget = enemyList[i].transform.gameObject;
    62.                 player.GetComponent<CharController>().isTargetLocked = true;
    63.                 lockedOn = true;
    64.             }
    65.             else if (i >= enemyList.Length)
    66.             {
    67.                 DumpTarget();
    68.             }
    69.             else
    70.             {
    71.                 i++;
    72.                 currentTarget = enemyList[i].transform.gameObject;
    73.                 player.GetComponent<CharController>().isTargetLocked = true;
    74.                 lockedOn = true;
    75.             }
    76.         }
    77.  
    78.  
    79.         //List all potential targets and array length
    80.         Debug.Log(enemyList.Length);
    81.         foreach (Collider hit in enemyList)
    82.         {
    83.             Debug.Log(hit.name);
    84.         }  
    85.     }  
    86.     void DumpTarget()
    87.     {
    88.         Debug.Log(currentTarget.transform.gameObject.name + " is target dumped.");
    89.         currentTarget = null;
    90.         lockedOn = false;
    91.         player.GetComponent<CharController>().isTargetLocked = false;
    92.     }
    93.  
    94.     void OnDrawGizmosSelected()
    95.     {
    96.         Gizmos.color = Color.red;
    97.         Debug.DrawLine(origin, origin);
    98.         Gizmos.DrawWireSphere(origin, sphereRadius);
    99.     }
    100.  
    101.  
    102. } //END OF SCRIPT