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 /
  • Help Room /
avatar image
0
Question by Biggzlar · Dec 22, 2015 at 11:58 AM · c#guigameobjecttransformcoroutine

Transform search function only sporadically works?!

Hello everybody,

so I am trying to implement a "Zelda"- or "Dark Souls"-like z-targeting system. You'll see in the code, that the function compiles a list of every enemy in the current scene. I'm still in the prototyping phase so the only credential for the targeting is the distance between enemy and player. The script is attached to my player and there are three enemies in the scene.

Now for the problem: The function is not reliable. Sometimes it updates the 'target', sometimes it doesn't. The debug.log fires as expected, only the most important thing appears to zoom in and out. This function is supposed to toggle the lockon as well, which doesn't reliably work either.

Tips on how to make the code lighter are appreciated as well!

 void LockOnEnemy(){
         bool check = false;
         if (target == null) {
             float enemyDistance = 100000000; //max lockon distance here
             float enemyDelta = enemyDistance;
             int enemyID = 0;
             GameObject[] enemyList = GameObject.FindGameObjectsWithTag ("Enemy");
             if (enemyList.Length > 0) {
                 for (int i = 0; i < enemyList.Length; i++) {
                     enemyDelta = (transform.position - enemyList [i].transform.position).magnitude;
                     if (enemyDelta < enemyDistance) {
                         enemyDistance = enemyDelta;
                         enemyID = i;
                     }
                 }
                 target = enemyList [enemyID].transform;
                 Debug.Log ("Found: Enemy( " + enemyID + ") at " + enemyDistance);
             }
             check = true;
         } 
         if(check == false) {
             this.target = null;
         }
     }
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

Answer by wibble82 · Dec 22, 2015 at 12:10 PM

Interesting!

Making your code a bit neater, the logic with the 'check' variable does seem a little odd:

             void LockOnEnemy()
             {
                 //we default to check == false
                 bool check = false;
 
                 //we will ONLY scan for new targets if current target is null
                 if (target == null)
                 {
                     GameObject[] enemyList = GameObject.FindGameObjectsWithTag("Enemy");
                     if (enemyList.Length > 0)
                     {
                         int enemyID = -1; //default this to 'invalid' value (just good practice!)
                         float closestEnemyDistanceSqr = float.MaxValue; //max lockon distance here (use float.MaxValue unless you have a good reason not to!)
 
                         //find closest enemy (only change is I'm looking at squared magnitudes, as they do the job and are more efficient)
                         for (int i = 0; i < enemyList.Length; i++)
                         {
                             float enemyDeltaSqr = (transform.position - enemyList[i].transform.position).sqrMagnitude;
                             if (enemyDeltaSqr < closestEnemyDistanceSqr)
                             {
                                 closestEnemyDistanceSqr = enemyDeltaSqr;
                                 enemyID = i;
                             }
                         }
 
                         //store the target. we can safely assume enemyID is no longer -1, as we know there is at least 1 enemy in enemyList
                         target = enemyList[enemyID].transform;
                         Debug.Log("Found: Enemy( " + enemyID + ") at " + Mathf.Sqrt(closestEnemyDistanceSqr));
                     }
 
                     //now we set check to true regardless of whether we found an enemy - is this what we want
                     check = true;
                 }
 
                 //if check is false (i.e. we didn't go through the above if statement), we clear 'target'.
                 if (check == false)
                 {
                     this.target = null;
                 }
             }

That's mostly the same, aside from a little clean up (using squared distance as its faster, and putting variables inside the correct scope).

However it highlights that the behaviour will be:

  • If 'LockOnEnemy' is called when target != null, check will always be left false, so target will be instantly cleared

  • if 'LockOnEnemy' is called when target == null, check will always be set t true

So basically, assuming there are enemies in range, LockOnEnemy will flip between having a target and not having a target.

-Chris

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 Biggzlar · Dec 22, 2015 at 01:38 PM 0
Share

Thanks for the cleanup. The tip with the default enemyID is really useful as well. I was searching for something like this but never considered putting in a negative value.

Sadly the problem is still present. Sometimes it works immediately, other times I have to press the button three+ times to lock on to an enemy. I just don't know what's causing this...

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

58 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

Related Questions

Access GameObject Array and Turn Render on via the key pressed - Keys are already named based on game object. 0 Answers

Why does Unity lock the transform of prefabs in my scene in playmode? 0 Answers

Setting EventTrigger in Unity with JavaScript 0 Answers

Coroutine: delay transform rotation but start transform movement immediately 2 Answers

Move gameObject on UI Button Press 2 Answers


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