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 Oldskewl · Nov 22, 2013 at 12:22 AM · arraylistnullreferenceexceptionstruct

Nullreferenceexception, Struct, Array, List

I found the following script on the forums and it works well until targets are destroyed, then throws the aforementioned exception. The error occurs around line 53. I've tried adding "if (target != null)" to the script and get the following error:

Assets/_Scripts/TargetingHUD.cs(53,29): error CS0019: Operator !=' cannot be applied to operands of type TargetingHUD.TargetStruct' and `null'

Been looking for a way around this for a few hours now without much luck. Any help would be appreciated.

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;               //Use this so you can manipulate Lists
 
 public class TargetingHUD : MonoBehaviour
 {
     public Texture2D targetIcon;                //The target icon that will be placed in front of targets
     public float maxTargetIconSize = 300f;      //The maximum size of icons when close to the target
     public float minTargetIconSize = 20f;        //The minimum size of icons when they appear (far from the target)
     public float maxDistanceDisplay = 10f;      //The maximum distance from where you can see the icons appearing
     public float minDistanceDisplay = 2f;       //The minimum distance from where you see the icons disappearing when too close
     public float smoothGrowingParameter = 25f;  //The speed of the growing effect on icons
     public float smoothMovingParameter = 25f;   //The moving speed of items : high values means the icon is "attached" to the item
     public bool directViewEnabled = true;       //If you want to allow icon display even if targets aren't in direct view for the player
 
     public struct TargetStruct                  //Structure that contain every icon informations
     {
         public GameObject item;                 //-the item the icon is linked to
         public Vector3 screenPos;               //-the screen position of the icon (!= world position)
         public float xSize, ySize;              //-the current size of the icon on the screen
         public float xPos, yPos;                //-the current coordinates of the screen position
         public float xTargetSize, yTargetSize;  //-the coordinates you want the icon to reach
         public float xTargetPos, yTargetPos;    //-the size you want the icon to reach on the screen
         public float distance;                  //-the distance between player and the item linked to the icon
         public bool directView;                 //-tells you if the item is in direct view or not
     }
 
     public List<TargetStruct> TargetList = new List<TargetStruct>();//Your ICONS LIST
     public GameObject[] Targets;                                    //The GameObjects considered as targets
 
     private int targetsCount;                                       //Number of targets in the scene
 
     void Awake()                                                        
     {
         Targets = GameObject.FindGameObjectsWithTag("enemy");     //Get all the potential targets in the scene (just replace it by your own tag : "MyTag")
         foreach(GameObject target in Targets)                                   //Put every detected GameObject into your ICONS LIST
         {
             TargetStruct newTarget = new TargetStruct();
             newTarget.item = target;                                            //and attach each icon its GameObject
             TargetList.Add(newTarget);
         }
         
         targetsCount = TargetList.Count;                                        //Count the number of target in the scene
     }
 
     void Update()
     {       
         for(int i = 0; i<targetsCount; i++)                                                         //You have to repeat it for every icons : be aware that if you have too much that could use a lot of ressoures 
         {
             TargetStruct target = new TargetStruct();                                               //You have to create a temporary TargetStruct since you can't access a variable of an element in a list directly
 
             target = TargetList[i];                                                                 //You take the item attached to the icon
 //            if (target != null)
 //            {
                 target.screenPos = camera.WorldToScreenPoint(target.item.transform.position);           //Convert world coordinates of the item into screen ones
                 
                 target.distance = Vector3.Distance(target.item.transform.position, transform.position); //Get the distance between item and player
                 
                 if(target.distance>maxDistanceDisplay || target.distance<minDistanceDisplay)            //If the item is too far or too close
                 {
                     target.xTargetSize = minTargetIconSize;                                             //you want it to disappear
                     target.yTargetSize = minTargetIconSize;                                             //or at least to be in its smaller size
                 }
                 else
                 {
                     target.xTargetSize = maxTargetIconSize/(target.distance);                           //Else you get its size with the
                     target.yTargetSize = maxTargetIconSize/(target.distance);                           //distance : far<=>small / close<=>big
                 }
                 
                 if(target.distance>maxDistanceDisplay)                                                  //If the item is too far, you set its screen position : (this way it seems as if the icon was coming away from the screen to focus your target)
                 {
                     if(target.screenPos.x<Screen.width/2)                                               //-if it's under the center of the view field
                         target.xTargetPos = 0;                                                          //to the bottom of the screen
                     else                                                                                //-else
                         target.xTargetPos = Screen.width;                                               //to the top of the screen
                     
                     if(target.screenPos.y<Screen.height/2)                                              //-if it's on the right of the view field
                         target.yTargetPos = Screen.height;                                              //to the right of the screen
                     else                                                                                //-else
                         target.yTargetPos = 0;                                                          //to the left of the screen
                 }
                 else                                                                                    //If the item is NOT too far, you set its screen position :
                 {
                     target.xTargetPos = target.screenPos.x-target.xSize/2;                              //in x-axis to the item's x-position minus half of the icon's size
                     target.yTargetPos = Screen.height-target.screenPos.y-target.ySize/2;                //in y-axis to the item's y-position minus half of the icon's size
                 }
                 
                 target.xSize = Mathf.Lerp(target.xSize, target.xTargetSize, smoothGrowingParameter*Time.deltaTime); //You do lerps on your icons size so you can adjust
                 target.ySize = Mathf.Lerp(target.xSize, target.yTargetSize, smoothGrowingParameter*Time.deltaTime); //the speed of their resizing
                 target.xPos = Mathf.Lerp(target.xPos, target.xTargetPos, smoothMovingParameter*Time.deltaTime);     //You do lerps on your icons position so you can adjust
                 target.yPos = Mathf.Lerp(target.yPos, target.yTargetPos, smoothMovingParameter*Time.deltaTime);     //their moving speed
                 RaycastHit hitInfos = new RaycastHit();                                                                 //You create a new variable to stock the information of the coming raycast
                 Physics.Raycast(transform.position, target.item.transform.position-transform.position, out hitInfos);   //and you RayCast from the player's position to the item's position
                 if(hitInfos.collider.gameObject.layer==8)                                                               //HERE IS A BIT TRICKY : you have to creat new layers (I called them "Interactive Items" and "Obstacles") and to apply them to your various items.
                     target.directView=true;                                                                             //Then you select EVERY items in your scene and set their layer to "Ignore Raycast". After that you select your interactive items biggest shape (if you have big trigger colliders on them select the item that hold it),
                 else                                                                                                    //and set their layers to "Interactive Items". Last part is setting every potential obstacle item layer to "Obstacles".
                     target.directView=false;                                                                            //NOTE : Here my "Interactive Items" layer number is 8
                 TargetList[i] = target;                                                                 //You apply all the variables to your index-i icon in the ICONS LIST
 //            }
         }
     }
 
     void OnGUI()
     {
         for(int i = 0; i<targetsCount; i++)                                                                                             //For every icon
         {
             if(TargetList[i].screenPos.z>0 && (!directViewEnabled || (directViewEnabled && TargetList[i].directView)))                  //If the icon is in front of you and all the required conditions are okay
                 GUI.DrawTexture(new Rect(TargetList[i].xPos, TargetList[i].yPos, TargetList[i].xSize, TargetList[i].ySize), targetIcon);//you display the icon with it's size and position
         }
     }
 }
Comment
Add comment · Show 2
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 Huacanacha · Nov 22, 2013 at 12:34 AM 0
Share

TargetStruct is a struct, which can't be null. The problem is that the item (GameObject) is probably being destroyed so references to target.item.transform are invalid. I can't see where the objects are destroyed so I'm assu$$anonymous$$g that's in an unrelated script.

Try adding Debug.Logs for target.item, and if that's not null for target.item.transform. Then you will see what is actually failing.

Once you figure out what is going on you'll need to maintain the target list when targets are destroyed. The easiest way would be to remove fro the list in Update() once an item is gone. You could also look into using a callback when the target objects are destroyed.

avatar image Oldskewl · Nov 22, 2013 at 03:17 PM 0
Share

You are correct, the items are being destroyed by another script on a projectile. Putting in the debugs helped, target.item returned null so I was able to un-comment the "if(target != null)" and change to "if(target.item != null)", this solved my nullreference issue.

The icons seem to disappear intermittently now and tend to leave a "ghost" on the screen once the object is destroyed but that may be a different problem. I'll try updating the list in update like you suggested and note back what I find so others can see the answer too. Thanks for your help.

1 Reply

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

Answer by Oldskewl · May 29, 2014 at 05:38 PM

the coment above by "Huacanacha" answered this for me, reposting as an answer so I can mark this as answered

TargetStruct is a struct, which can't be null. The problem is that the item (GameObject) is probably being destroyed so references to target.item.transform are invalid. I can't see where the objects are destroyed so I'm assuming that's in an unrelated script. Try adding Debug.Logs for target.item, and if that's not null for target.item.transform. Then you will see what is actually failing. Once you figure out what is going on you'll need to maintain the target list when targets are destroyed. The easiest way would be to remove fro the list in Update() once an item is gone. You could also look into using a callback when the target objects are destroyed.

Comment
Add comment · 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

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

17 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

Related Questions

A node in a childnode? 1 Answer

List or Array for Rays 1 Answer

Lists and Structs instead of Arrays? 4 Answers

How to return index of List element? 1 Answer

How can I instantiate parented ui objects above previously instantiated children? 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