Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 MachCUBED · Apr 29, 2012 at 06:36 PM · guigameobjectnearestfallback

Nearest object code not falling back on alternate in OnGUI()

Hi guys,

I have a compass that points to the nearest checkpoint in my game. If all the checkpoints have been passed (and therefore removed), it's supposed to point to the finish loop. This is the relevant code:

function GetClosestObject(tag:String, altTag:String) : GameObject { var objectsWithTag = GameObject.FindGameObjectsWithTag(tag);

 if (!objectsWithTag)
     GameObject.FindGameObjectsWithTag(altTag);
 
 var closestObject : GameObject;
 
 for (var obj : GameObject in objectsWithTag)
 {
     if(!closestObject)
     {
        closestObject = obj;
     }
     //compares distances
     if(Vector3.Distance(transform.position, obj.transform.position) <= Vector3.Distance(transform.position, closestObject.transform.position))
     {
        closestObject = obj;
     }
 }
 return closestObject;

}

function OnGUI() {

 target = GetClosestObject("Checkpoint", "Finish").transform;
     ...

}

It works fine as long as there is at least one checkpoint. However, when there is only the finish loop remaining (which has the tag "Finish"), the arrow dial disappears and prints the following console error:


NullReferenceException: Object reference not set to an instance of an object

What seems to be the problem? All the game objects have their tags set right in the scene.

MachCUBED DirectionArrow.OnGUI () (at Assets/Entities/Player/Character/Scripts/DirectionArrow.js:44)

Comment
Add comment · Show 1
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 -hiTo- · May 01, 2012 at 05:57 AM 0
Share

I'm not familiar at all with the JavaScript approach, but can you actually do if (!objectsWithTag) ? If it's null, shouldn't it be if (objectsWithTag == null) ? Other than that, I can only suggest chainedlupine's response and to print stuff everywhere to find out what your array consists of.

3 Replies

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

Answer by IssamKhalil · May 14, 2012 at 03:53 AM

Try doing this:

 function GetClosestObject(tag:String, altTag:String) : GameObject
 {
     var objectsWithTag;
     
     Debug.Log("Finish loop:" + GameObject.FindGameObjectsWithTag(altTag));
 
     objectsWithTag = GameObject.FindGameObjectsWithTag(tag);
         
     if (objectsWithTag.Length == 0)
     {
        Debug.Log("Finding finish");
        objectsWithTag = GameObject.FindGameObjectsWithTag(altTag);
     }
     
     var closestObject : GameObject;
     
     for (var obj : GameObject in objectsWithTag)
     {
         if(!closestObject)
         {
            closestObject = obj;
         }
         //compares distances
         if(Vector3.Distance(transform.position, obj.transform.position) <= Vector3.Distance(transform.position, closestObject.transform.position))
         {
            closestObject = obj;
         }
     }
     return closestObject;
 }
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 MachCUBED · May 14, 2012 at 04:11 AM 0
Share

It got the following compile-time error:

Assets/Entities/Player/Character/Scripts/DirectionArrow.js(25,24): BCE0019: 'Length' is not a member of 'Object'. 

At the following line:

if (objectsWithTag.Length == 0)

So I typed objectsWithTag like so:

var objectsWithTag : GameObject[];

It worked as expected, but with one caveat: the compass sometimes points in the wrong direction.

Final code:

#pragma strict

var cam : Camera; //Camera to use

var arrow: Texture2D; // drag the arrow texture here

var dialPos: Vector2;

private var target : Transform; //Target to point at (you could set this to any gameObject dynamically) private var targetPos : Vector3; //Target position on screen private var screen$$anonymous$$iddle : Vector3; //$$anonymous$$iddle of the screen

function Start () { }

function GetClosestObject(tag:String, altTag:String) : GameObject { var objectsWithTag : GameObject[];

 Debug.Log("Finish loop:" + GameObject.FindGameObjectsWithTag(altTag));

 objectsWithTag = GameObject.FindGameObjectsWithTag(tag);

 if (objectsWithTag.Length == 0)
 {
    objectsWithTag = GameObject.FindGameObjectsWithTag(altTag);
 }
 
 // Check again if the length is 0
 
 if (objectsWithTag.Length == 0)
 {
    return null;
 }

 var closestObject : GameObject;

 for (var obj : GameObject in objectsWithTag)
 {
     if(!closestObject)
     {
        closestObject = obj;
     }
     //compares distances
     if(Vector3.Distance(transform.position, obj.transform.position) <= Vector3.Distance(transform.position, closestObject.transform.position))
     {
        closestObject = obj;
     }
 }
 return closestObject;

}

function OnGUI() {

 target = GetClosestObject("Checkpoint", "Finish").transform;

if (target != null) { //Get the targets position on screen into a Vector3 targetPos = cam.WorldToScreenPoint (target.transform.position);

 //Get the middle of the screen into a Vector3
 screen$$anonymous$$iddle = Vector3(Screen.width/2, Screen.height/2, 0); 
 
 //Compute the angle from screen$$anonymous$$iddle to targetPos
 var tarAngle = ($$anonymous$$athf.Atan2(targetPos.x-screen$$anonymous$$iddle.x,Screen.height-targetPos.y-screen$$anonymous$$iddle.y) * $$anonymous$$athf.Rad2Deg)+90;
 
 if (tarAngle < 0) tarAngle +=360;

 //Calculate the angle from the camera to the target
 var targetDir = target.transform.position - cam.transform.position;
 var forward = cam.transform.forward;
 var angle = Vector3.Angle(targetDir, forward);

 //If the angle exceeds 90deg inverse the rotation to point correctly
 if(angle<90)
 {
     transform.localRotation = Quaternion.Euler(-tarAngle,90,270);
 } 
 else 
 {
     transform.localRotation = Quaternion.Euler(tarAngle,270,90);
 }
 
 // Draw compass
 
 var centre = Vector2(dialPos.x + arrow.width / 2,  dialPos.y + arrow.height / 2);
 var saved$$anonymous$$atrix = GUI.matrix;
 
 if (tarAngle != 0) 
     GUIUtility.RotateAroundPivot(angle, centre);
     
 GUI.DrawTexture(Rect(centre.x - (arrow.width / 2), centre.y - (arrow.height / 2), arrow.width, arrow.height), arrow);
 GUI.matrix = saved$$anonymous$$atrix;
 }

}

Thanks $$anonymous$$halil!

avatar image
2

Answer by chainedlupine · May 01, 2012 at 04:05 AM

Shouldn't that be...?

 if (!objectsWithTag)
     objectsWithTag = GameObject.FindGameObjectsWithTag(altTag);
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 MachCUBED · May 01, 2012 at 05:36 AM 0
Share

I tried the above code and it still didn't work.

avatar image Seth-Bergman · May 01, 2012 at 06:01 AM 0
Share

chainedlupines answer should definitely work. $$anonymous$$aybe you failed to save before running? Also, no need to go through the whole function if we know there are no checkpoints left:

if (!objectsWithTag) {

var finish : GameObject = GameObject.FindWithTag("Finish");

return finish;

}

(that is, unless there are multiple "Finish" objects, if so, my mistake)

avatar image MachCUBED · May 01, 2012 at 03:58 PM 0
Share

I did save it and it still didn't work. I then tried your code:

function GetClosestObject(tag:String, altTag:String) : GameObject { var objectsWithTag = GameObject.FindGameObjectsWithTag(tag);

 if (!objectsWithTag) 
 {
     var finish : GameObject = GameObject.FindWithTag("Finish");

     return finish;
 }
 
 var closestObject : GameObject;
 
 for (var obj : GameObject in objectsWithTag)
 {
     if(!closestObject)
     {
        closestObject = obj;
     }
     //compares distances
     if(Vector3.Distance(transform.position, obj.transform.position) <= Vector3.Distance(transform.position, closestObject.transform.position))
     {
        closestObject = obj;
     }
 }
 return closestObject;

}

And I still got this error:


NullReferenceException: Object reference not set to an instance of an object
DirectionArrow.OnGUI () (at Assets/Entities/Player/Character/Scripts/DirectionArrow.js:48)

avatar image Seth-Bergman · May 01, 2012 at 04:16 PM 0
Share

did you try it as suggested above : if (objectsWithTag == null)? don't think that's it though... how about this:

add this to your script:

var finish : GameObject;

function Start() {

finish = GameObject.FindWithTag("Finish")

}

then hit play and see if the finish slot in the inspector gets set. otherwise, maybe the tag is spelled differently or not set to the object.. no other way this wouldn't work..

avatar image Bunny83 · May 01, 2012 at 04:21 PM 0
Share

So how about starting to debug your script? What code is at line 48 in "DirectionArrow.js" ?

It's clearly that a reference you're using is null. Probably because FindWithTag returned null because it can't find an object with this tag. Are you sure your tag is correct and there is an active object tagged with this tag?

We don't have your code, your have to fight your logic errors or tagging mistakes yourself. @chainedlupines answer is correct from what we can see here.

Show more comments
avatar image
1

Answer by Piflik · May 13, 2012 at 06:11 PM

Try this:

 function GetClosestObject(tag:String, altTag:String) : GameObject
 {
     var objectsWithTag = null;
     
     objectsWithTag = GameObject.FindGameObjectsWithTag(tag);

     if (objectsWithTag == null) 
     {
         Debug.Log("Finding finish");
         objectsWithTag = GameObject.FindGameObjectsWithTag(altTag);
     }
     
     var closestObject : GameObject;
     
     for (var obj : GameObject in objectsWithTag)
     {
         if(!closestObject)
         {
            closestObject = obj;
         }
         //compares distances
         if(Vector3.Distance(transform.position, obj.transform.position) <= Vector3.Distance(transform.position, closestObject.transform.position))
         {
            closestObject = obj;
         }
     }
     return closestObject;
 }

It probably doesn't work, since FindGameObjectsWithTag would return 'null' anyway, but it's worth a try....

Comment
Add comment · Show 3 · 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 MachCUBED · May 13, 2012 at 06:19 PM 0
Share

I tried it, and it still doesn't work. From my debugging, my problem appears to be that this block:


if (objectsWithTag == null) 
    {
        Debug.Log("Finding finish");
       objectsWithTag = GameObject.FindGameObjectsWithTag(altTag);
    }

Isn't being executed. It appears that if objectsWithTag is set to a null value, the if statement isn't firing.

avatar image Piflik · May 13, 2012 at 06:24 PM 0
Share

I have if statements with anything == null and they work...try printing objectsWithTag to the console before the loop.

avatar image MachCUBED · May 13, 2012 at 11:43 PM 0
Share

If I make my code look like this:

function GetClosestObject(tag:String, altTag:String) : GameObject { var objectsWithTag;

 Debug.Log("Finish loop:" + GameObject.FindGameObjectsWithTag(altTag));

 objectsWithTag = GameObject.FindGameObjectsWithTag(tag);
     
 if (objectsWithTag == null)
 {
     Debug.Log("Finding finish");
     objectsWithTag = GameObject.FindGameObjectsWithTag(altTag);
 }
 
 var closestObject : GameObject;
 
 for (var obj : GameObject in objectsWithTag)
 {
     if(!closestObject)
     {
        closestObject = obj;
     }
     //compares distances
     if(Vector3.Distance(transform.position, obj.transform.position) <= Vector3.Distance(transform.position, closestObject.transform.position))
     {
        closestObject = obj;
     }
 }
 return closestObject;

}

I get this result for my Finish loop debug message:

Finish loop:UnityEngine.GameObject[]
UnityEngine.Debug:Log(Object)
DirectionArrow:GetClosestObject(String, String) (at Assets/Entities/Player/Character/Scripts/DirectionArrow.js:21)
DirectionArrow:OnGUI() (at Assets/Entities/Player/Character/Scripts/DirectionArrow.js:51)

So it's printing an array for the name of the finish loop. $$anonymous$$ore importantly, "Finding finish" does not show up when all the checkpoints are passed, indicating that the reason why it's not finding the finish loop is because the following code isn't being executed:


if (objectsWithTag == null)
    {
        Debug.Log("Finding finish");
        objectsWithTag = GameObject.FindGameObjectsWithTag(altTag);
    }

I'm still stumped. Why oisn't objectsWithTag being set to null when OnGUI() is called after all objects tagged "Checkpoint" are removed from the scene?

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

6 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Setting Scroll View Width GUILayout 1 Answer

Help with sanity script loading death screen 1 Answer

How do I handle object selection and GUI response ingame? 5 Answers

Problems using NGUI for in-game options sliders 0 Answers

Unity3D Game Time 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