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

Bug LookAt() suddendly not working

Discussion in 'Scripting' started by Snipex01ITA_, Aug 29, 2023.

  1. Snipex01ITA_

    Snipex01ITA_

    Joined:
    Mar 20, 2021
    Posts:
    4
    Hi, I've been reworking some of my scripts now that I've started to use the Input Action system in Unity, and I've encountered a problem in my "CameraSwitcher" script that I can't really understand.

    To sum it up, my "CameraSwitcher" script basically changes the activeCamera based on where the Player is at that moment, and inside of this script I have a method called "LockOnTargetList()" that lets the player Lock-On an enemy. It used to work perfectly, shifting the focus of the camera to look directly in between the player and the enemy locked, while now the camera doesen't change from its normal position. This is the code:

    Code (CSharp):
    1. public void LockOnTargetList(){
    2.     List<GameObject> enemiesGameObject = new List<GameObject>(GameObject.FindGameObjectsWithTag("Enemy"));
    3.     List<EnemyCreature> enemies = new List<EnemyCreature>();
    4.  
    5.     foreach (GameObject e in enemiesGameObject){
    6.         EnemyCreature enemy = e.GetComponent<EnemyCreature>();
    7.         enemies.Add(enemy);
    8.     }
    9.  
    10.  
    11.     EnemyCreature closestEnemy = null;
    12.     float closestEnemyDistance = 0f;
    13.  
    14.     Vector3 connectingVector = new Vector3(0.0f, 0.0f, 0.0f);
    15.     float distance = 0;
    16.  
    17.     foreach(EnemyCreature e in enemies){
    18.         connectingVector = (e.transform.position - target.transform.position);
    19.         distance = connectingVector.magnitude;
    20.  
    21.         if(closestEnemyDistance == 0f || distance < closestEnemyDistance){
    22.             closestEnemyDistance = distance;
    23.             closestEnemy = e;
    24.         }
    25.     }
    26.  
    27.     Vector3 direction = connectingVector.normalized;
    28.  
    29.     Vector3 focusPoint = target.transform.position + direction * (closestEnemyDistance/2);
    30.  
    31.     if(distance!=0 && closestEnemyDistance<10f){
    32.         activeCamera.transform.LookAt(focusPoint);
    33.         isEnemyLocked = true;
    34.     } else if(closestEnemy == null){
    35.         isEnemyLocked = false;
    36.     }
    37. }
    I've checked with a couple of Debug.Logs and from what it looks like the problem is just in the LookAt function. The focus point seems to be calculated properly.

    I'm fairly new to Unity so I'm sure it's just some dumb mistake I made that I can't see, but I'd appreciate if someone could lend a hend :)
     
    Last edited: Aug 29, 2023
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    3,899
    You know, you do need to tell us what makes you think that it "looks like" to be the problem. We don't know what you logged. For all we know you could be drawing the wrong conclusions. ;)

    Likewise, a value cannot "seem to be" correct - it either is or it isn't. If you don't know for sure, you haven't actually confirmed anything and cannot draw a conclusion.

    So either the condition before the LookAt evaluates to false or the focusPoint is incorrect.
     
    Snipex01ITA_ likes this.
  3. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    8,955
  4. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    3,899
    I refactored your code and introduced a "container" object to make finding enemies faster, easier and reliable (tags could be renamed or set incorrectly, breaking the code). So this code will only work if you assign the respective container object and make sure to spawn enemies into that container.
    Code (CSharp):
    1. // this is the root/parent object where all enemies are spawned into
    2.         [SerializeField] private GameObject enemyContainer;
    3.  
    4.         public void LockOnTargetList()
    5.         {
    6.             EnemyCreature closestEnemy = null;
    7.             var closestEnemyDistance = Single.MaxValue;
    8.             var connectingVector = Vector3.zero;
    9.  
    10.             foreach (var e in enemyContainer.GetComponentsInChildren<EnemyCreature>())
    11.             {
    12.                 connectingVector = e.transform.position - target.transform.position;
    13.  
    14.                 var distance = connectingVector.magnitude;
    15.                 if (distance < closestEnemyDistance)
    16.                 {
    17.                     closestEnemyDistance = distance;
    18.                     closestEnemy = e;
    19.                 }
    20.             }
    21.  
    22.             var direction = connectingVector.normalized;
    23.             var focusPoint = target.transform.position + direction * (closestEnemyDistance / 2f);
    24.  
    25.             isEnemyLocked = closestEnemyDistance != 0f && closestEnemyDistance < 10f;
    26.             if (isEnemyLocked)
    27.                 activeCamera.transform.LookAt(focusPoint);
    28.         }
    You'll notice that distance is no longer checked at the bottom, instead it's closestEnemyDistance. Pretty sure you did not want to check for the last enemy's distance not to be 0 but rather the enemy you determined as being the closest.
     
  5. Snipex01ITA_

    Snipex01ITA_

    Joined:
    Mar 20, 2021
    Posts:
    4
    Thanks for the reply,
    you're right, it was stupid of me not to think about that haha.

    I did a Debug.Log(focusPoint) right before "activeCamera.transform.LookAt(focusPoint);" to check if the focus point was correct (focusPoint is a Vector3 representing the central point of the distance between the player and the enemy that is being locked at that time). So what I expected from it was the exact central position of the distance that divided the player and the enemy, and it was correct so I'm sure the focus point is not the problem.

    I think the problem is in the LookAt() function because of the fact that every other variable that is used to calculate the focusPoint is correct, and so is the focusPoint.
    So the only part of the code that I think could be causing the problem is the actual LookAt() function, altough I don't really understand why.

    Sorry if there are other errors in logic in this post, I'm not really good at explaining myself at times :) , but I appreciate the help!
     
  6. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    It's very unlikely that a Unity API method that's been around since the days of yore, used by tons of users, is the issue here.

    Most likely your surrounding logic is faulty in some way, and just needs a thorough debugging.
     
  7. Snipex01ITA_

    Snipex01ITA_

    Joined:
    Mar 20, 2021
    Posts:
    4
    Fixed it. I had to change the way the Inputs called the LockOnTarget method in another script, I feel very dumb haha.
    Thanks for the help everybody :)
     
  8. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    First, I would have all the enemies just add their script(component reference) to a
    List<EnemyScripts> allEnemies;
    , So that way you don't need to beat around the bush with cycling through all enemies by finding tag, then getting script(component). You'd already have them.

    Second, I can see where this would cause a problem:
    Code (CSharp):
    1. foreach(EnemyCreature e in enemies){
    2.         connectingVector = (e.transform.position - target.transform.position);
    3.         distance = connectingVector.magnitude;
    4.         if(closestEnemyDistance == 0f || distance < closestEnemyDistance){
    5.             closestEnemyDistance = distance;
    6.             closestEnemy = e;
    7.         }
    8.     }
    9.     Vector3 direction = connectingVector.normalized;
    As your "direction" would just be the last iteration of the foreach loop, not the one who is closest. So judging by this, once your "direction" is wrong, then any result you calculate off of that, would also be wrong.
     
  9. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    This should be more appropriate:
    Code (CSharp):
    1. foreach(EnemyCreature e in enemies)
    2. {
    3.     distance = Vector3.Distance(e.transform.position, target.transform.position);
    4.    
    5.     if(closestEnemyDistance == 0f || distance < closestEnemyDistance)
    6.     {
    7.         connectingVector = e.transform.position - target.transform.position;
    8.         closestEnemyDistance = distance;
    9.         closestEnemy = e;
    10.     }
    11. }
    12. Vector3 direction = connectingVector.normalized;
    13.  
    :)
     
  10. Snipex01ITA_

    Snipex01ITA_

    Joined:
    Mar 20, 2021
    Posts:
    4
    Thanks, appreciate the help!
    In the end I found out what was causing the problem but this reply was also really useful to make my code better, thanks