Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Aiming At Nearest Problem

Discussion in 'Scripting' started by RiokuTheSlayer, Oct 21, 2014.

  1. RiokuTheSlayer

    RiokuTheSlayer

    Joined:
    Aug 22, 2013
    Posts:
    356
    Hellooo everyone, RiokuTheSlayer here, with another problem with one of my scripts. I'm such a noob, I know haha. This time it's with aiming at the nearest object. Basically, I stole a script from the Unity website, and it's not working. Here's my entire script.


    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class CameraController : MonoBehaviour {
    5.  
    6.     public Texture sprCrosshair;
    7.     bool autoAiming=false;
    8.  
    9.     // Use this for initialization
    10.     void Start () {
    11.    
    12.     }
    13.    
    14.     // Update is called once per frame
    15.     void Update () {
    16.         GameObject Enemies = GameObject.FindGameObjectWithTag("Enemy");
    17.         GameObject gun = GameObject.FindGameObjectWithTag("HandGun");
    18.         if(Input.GetKey(KeyCode.I)){
    19.             transform.Rotate(-Vector3.right*2);
    20.         }
    21.         if(Input.GetKey(KeyCode.K)){
    22.             transform.Rotate(Vector3.right*2);
    23.         }
    24.  
    25.         if(autoAiming && Enemies!=null){
    26.             gun.transform.LookAt(GameObject.FindGameObjectWithTag("Enemy").transform.position);
    27.         }
    28.  
    29.     }
    30.     void OnGUI () {
    31.         Vector2 ScreenCenter = new Vector2(Screen.width/2,Screen.height/2);
    32.         GUI.DrawTexture(new Rect(ScreenCenter.x-50,ScreenCenter.y-50, 100, 100), sprCrosshair, ScaleMode.ScaleToFit, true, 0.0F);
    33.         GameObject Enemies = FindClosestEnemy();
    34.         if(Enemies!=null){
    35.             Vector2 coords = Camera.main.WorldToScreenPoint(Enemies.transform.position);
    36.             if(Vector2.Distance(coords,ScreenCenter) <= 200){
    37.                 GUI.DrawTexture(new Rect(coords.x-25,-coords.y+Screen.height-25,50,50), sprCrosshair, ScaleMode.ScaleToFit, true, 0.0F);
    38.                 autoAiming=true;
    39.             }else if(Vector2.Distance(coords,ScreenCenter) >= 200){
    40.                 GUI.DrawTexture(new Rect(ScreenCenter.x-15,ScreenCenter.y-15, 30, 30), sprCrosshair, ScaleMode.ScaleToFit, true, 0.0F);
    41.                 autoAiming=false;
    42.             }
    43.         } else if(Enemies==null){
    44.             GUI.DrawTexture(new Rect(ScreenCenter.x-15,ScreenCenter.y-15, 30, 30), sprCrosshair, ScaleMode.ScaleToFit, true, 0.0F);
    45.             autoAiming=false;
    46.         }
    47.     }
    48.     GameObject FindClosestEnemy() {
    49.         GameObject[] gos;
    50.         gos = GameObject.FindGameObjectsWithTag("Enemy");
    51.         GameObject closest;
    52.         float distance = Mathf.Infinity;
    53.         Vector3 position = transform.position;
    54.         foreach (GameObject go in gos) {
    55.             Vector3 diff = go.transform.position - position;
    56.             float curDistance = diff.sqrMagnitude;
    57.             if (curDistance < distance) {
    58.                 closest = go;
    59.                 distance = curDistance;
    60.             }
    61.         }
    62.         return null;
    63.     }
    64. }

    So three things. First, I have NO idea how to properly use FindClosestEnemy(). I'm completely new to Arrays and such. Second, the result of this script is the auto-aiming icon resetting to the default position. Third, is there a way to move all of my logic for the Auto-Aiming out of the OnGui() method, and move it to it's own method (Like aimLogic() or something), without it giving me the error because the GUI elements need to be in OnGui()?

    Thanks for all the help! Looking forward to learning something soon!

    (Also, thanks website formatting ,you make my code look ugly... Oh well..)
     
  2. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Calling getComponent all the time in Update should be avoided, the last method does kind of nothing, you (i assume you've made it because i've seen that method a bit differently/better in another thread) have made everything local to the FindClosestEnemy() method, which on top of that always returns null. Short: it does nothing useful for you.

    And yes, you can put the code into its own method but you will only be able to call it in OnGUI if it contains GUI-related stuff.
    There's quite a lot to improve, i'd simply recommend to have a look at the coding parts you haven't used so far and design your own class/methods etc, random scripts often do not fit your needs, they usually just sound as if they would.
     
  3. RiokuTheSlayer

    RiokuTheSlayer

    Joined:
    Aug 22, 2013
    Posts:
    356
    Well, as I said, I'm rather new to how arrays work and such >.< How would I make the FindClosestEnemy() actually return the game object? Right now I'm just using GameObject.FindObjectWithTag("Enemy"), but that only aims at a specific enemy. And as for the getComponent on the main thread, I know. I'm just throwing stuff around, I'm going to clean up later.
     
  4. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Try to return 'closest' instead of null.
    I still really recommend to invest some time and play around with arrays and lists, they're needed quite a lot of times and are really helpful. :)
     
  5. RiokuTheSlayer

    RiokuTheSlayer

    Joined:
    Aug 22, 2013
    Posts:
    356
    I already tried to let it return "Closest" but it says "Assets/Scripts/CameraController.cs(62,24): error CS0165: Use of unassigned local variable `closest' "

    This is what I changed
    Code (CSharp):
    1. GameObject Enemies = FindClosestEnemy();
     
  6. RiokuTheSlayer

    RiokuTheSlayer

    Joined:
    Aug 22, 2013
    Posts:
    356
  7. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    'closest' needs a value for the case that either the loop does not even run once (i.e. gos is empty) or for the case that no distance is less than your comparison value).
    You could either just say 'closest = null' as an initial value or assign the first object in gos to it which is gos[0], latter can and should only be done when 'gos.length > 0' is true, otherwise an exception will most likely be thrown.
     
  8. RiokuTheSlayer

    RiokuTheSlayer

    Joined:
    Aug 22, 2013
    Posts:
    356
    Thanks :D I changed the GameObject closest; to GameObject closest = null;, and added an if statement to make sure the enemy is in range of the auto-aiming, and it works perfectly!

    Almost >.< I noticed that the aiming works in reverse as well. I.E. whenever an enemy is behind me, and i'm aiming away from them, it aims at them. Any way to fix that? It just seems to think that when the enemy is on the opposite side of the screen, it counts as being on the screen still... And yet the cursor moves opposite of it.... I don't know. Is there any way to tell if an object is directly visible in the window?
     
  9. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    renderer.isVisible (the renderer of your enemy of course, not your 'own') returns true when the object is being rendered, false if not. Noe quite sure if that's already enough for your needs.
     
  10. RiokuTheSlayer

    RiokuTheSlayer

    Joined:
    Aug 22, 2013
    Posts:
    356
    Didn't work, I had just found out about this the other day and I was gunna try it.


    Code (CSharp):
    1. //Changed
    2. if(autoAiming && Enemies!=null){            
    3.             gun.transform.LookAt(Enemies.transform.position);
    4.         }
    5.  
    6. //To
    7. if(autoAiming && Enemies!=null && Enemies.tag== "Enemy" && Enemies.renderer.isVisible == true)
    8.             gun.transform.LookAt(Enemies.transform.position);
    9.        
     
  11. RiokuTheSlayer

    RiokuTheSlayer

    Joined:
    Aug 22, 2013
    Posts:
    356
    Nevermind, got it
     
    Suddoha likes this.