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 /
avatar image
0
Question by vittu1994 · Sep 22, 2015 at 07:37 AM · c#arraygameobjectselement

how to check if an element has been removed from a GameObject array C#

Hi, i have four GameObject[] arrays where i store certain gameObjects inside once they spawn.

For example:

public GameObject[] battleshipAmount;

//i can find and place them in the array once they spawn thanks to their tag

battleshipAmount = GameObject.FindGameObjectsWithTag("battleship");

The thing that happens is that these objects will get destroyed and i want to do something once one of these gameObjects becomes null and gets removed from the array. I want to it detect if an element from just this array has been destroyed and then i want to do something (increasing an int by 1 for example).

I figure since this is happening during game time it has to be updated when an element has been removed from the array so i will need to loop through the array to see if the index of it has been decreased by a certain amount. How will i go about doing this the correct but most simplest way (not that good with unity and c#).

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 Hellium · Sep 22, 2015 at 09:06 AM 0
Share

Do you plan to call

 battleshipAmount = GameObject.FindGameObjectsWithTag("battleship");

every frame ?

avatar image vittu1994 Hellium · Sep 22, 2015 at 09:38 AM 0
Share

Yes, that way i can know if a new object with that tag has been instantiated and is active

2 Replies

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

Answer by Hellium · Sep 22, 2015 at 07:41 AM

I would use a property (the equivalent of a getter & setter in another programming language)

 // C#
 // Note : I haven't tested this code, I  wrote it in a simple Notepad, do not hesitate to tell me if there is an error.
 private GameObject[] battleshipAmount ;
 
 public GameObject[] BattleshipAmount
 {
     get { return battleshipAmount ; }
     set
     {
         if( battleshipAmount == null )
         {
              battleshipAmount = value ;
             return ;
         }

         if( battleshipAmount.Length > value.Length )
         {
             // A GameObject has been destroyed
         
             // Check which gameobject has been destroyed
             for( int i = 0 ; i < battleshipAmount.Length ; ++i )
             {
                 for( int j = 0 ; j < value.Length ; ++j )
                 {
                     // Check if gameobject is in the new array
                     if( battleshipAmount[i].GetInstanceID() == value[j].GetInstanceID() )
                     {
                         // GameObject still here
                         continue ;
                     }
                 }
                 // If this part of the code is reached, a destroyed gameobject has been found
                 Debug.Log( "The gameobject #" + i + " has been destroyed!" ) ;
             }
         }
         else if( battleshipAmount.Length < value.Length )
         {
             // A GameObject has been added
         }    
         battleshipAmount  = value ;
     }
 }

Then, in your code, never use battleshipAmount, but use BattleshipAmount instead (notice the capital letter). BattleshipAmount can be use in the exact same way you would use battleshipAmount.

Comment
Add comment · Show 9 · 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 vittu1994 · Sep 22, 2015 at 08:15 AM 0
Share

NullReferenceException: Object reference not set to an instance of an object Placement.set_BattleshipAmount (UnityEngine.GameObject[] value) (at Assets/Scripts/Placement.cs:20) Placement.Update () (at Assets/Scripts/Placement.cs:138)

for the line:

if( battleshipAmount.Length > value.Length )

avatar image Hellium vittu1994 · Sep 22, 2015 at 08:25 AM 0
Share

Oops, indeed.

 [...]
 set
 {
     if( battleshipAmount == null )
     {
         battleshipAmount = value ;
         return ;
      }

 [...]
avatar image vittu1994 Hellium · Sep 22, 2015 at 08:39 AM 0
Share

$$anonymous$$issingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object. Placement.set_BattleshipAmount (UnityEngine.GameObject[] value) (at Assets/Scripts/Placement.cs:42) Placement.Update () (at Assets/Scripts/Placement.cs:143)

i managed to get this from the line:

// If this part of the code is reached, a destroyed gameobject has been found Debug.Log( "The GameObject named " + battleshipAmount[i].name + " has been destroyed!" );

which seems to be correct, or should it display the Debug.Log and not the error?

another side note, even though the array is public i cant find it in the inspector of the script holder.

Show more comments
avatar image vittu1994 · Sep 22, 2015 at 09:27 AM 0
Share

It seems to work now! Do you know a good way to use this method on 3 other arrays aswell? It will be alot of code (a lot of repeated code aswell). Thanks for your contribution anyways @Hellium

avatar image Hellium vittu1994 · Sep 22, 2015 at 09:51 AM 0
Share

Here is a more generic code.

I use delegates to call a function I want when a gameobject is missing. Thus, for every array, you can have a different function. I don't have time to explain you how delegates works, but I invite you to read about it, it's very useful.

 // Prototype of the functions to call when a gameobject is missing
 private delegate void $$anonymous$$yDelegate();
 
 [SerializeField]
 private GameObject[] battleshipAmount ;
 
 [SerializeField]
 private GameObject[] anotherArray ;
 
 public GameObject[] BattleshipAmount
 {
     get { return battleshipAmount ; }
     set
     {
         CheckArray( battleshipAmount, value, Foo ) ;
     }
 }
 
 public GameObject[] AnotherArray
 {
     get { return anotherArray ; }
     set
     {
         CheckArray( anotherArray, value, Bar ) ;
     }
 }
 
 private void CheckArray( oldArray, newArray, $$anonymous$$yDelegate delegate )
 {
     if( oldArray == null )
     {
         oldArray = newArray ;
         return ;
     }
     
     if( oldArray.Length > newArray.Length )
     {
         // A GameObject has been destroyed
     
         // Check which gameobject has been destroyed
         for( int i = 0 ; i < oldArray.Length ; ++i )
         {
             for( int j = 0 ; j < newArray.Length ; ++j )
             {
                 // Check if gameobject is in the new array
                 if( oldArray[i].GetInstanceID() == newArray[j].GetInstanceID() )
                 {
                     // GameObject still here
                     continue ;
                 }
             }
             // If this part of the code is reached, a destroyed gameobject has been found
             delegate() ;
         }
     }
     else if( oldArray.Length < newArray.Length )
     {
         // A GameObject has been added
     }
     
     oldArray = newArray ;
 }
 
 // The prototype of this function $$anonymous$$UST be the same as the prototype of the delegate
 private void Bar()
 {
     Debug.Log( "Bar" );
 }
 
 // The prototype of this function $$anonymous$$UST be the same as the prototype of the delegate
 private void Foo()
 {
     Debug.Log( "Foo" );
 }
avatar image vittu1994 Hellium · Sep 22, 2015 at 10:03 AM 0
Share

seems complex, ill go with the repeated code for now but i bookmarked this question so i can look into ur view on delegates at some other point. Thanks for your time!

Show more comments
avatar image sandeepsmartest · Sep 22, 2015 at 09:58 AM 0
Share

Hi, Have a look On This

Hope this may help you. Nsks

avatar image
0

Answer by Suddoha · Sep 22, 2015 at 12:07 PM

You can also use an event-based approach to not rely on a loop each time a battleship is destroyed.

Basically, you'd have a script on each battleship which contains the following:

 Action <BattleshipScript> DestroyShip;

From your script that handles the changes (you mentioned an int that will increase, for example) you would then subscribe to this action. Before a ship is destroyed, call DestroyShip(this) and it will execute all methods that have been subscribed to that particular ship. This allows for more control and less polling, no loops etc.

Unfortunately i cannot provide a code sample as it is not exactly clear what you already have, but this will only need a couple of lines to set up, probably not more than 3-4.

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

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

How do i access the variables of a class that is in an array? 1 Answer

how can i check if there is a blanc spot in my list 3 Answers

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

comparing variables of gameobjects in an array 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