• 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 /
This post has been wikified, any user with enough reputation can edit it.
avatar image
Question by yotingo · Jul 10, 2013 at 12:47 PM · stringintegersequencenumbers

Sequential GameObject Activation

This seems like the simplest thing but I can't figure it out for the life of me.

I have 400 unique GameObjects that I would like to Activate at different times during an animation. Each GameObject needs to be at very exact location and rotation so I believe .SetActive would be better than trying to Instantiate each one individually. It would also be nice to avoid writing a 400 item Hashtable or Dictionary.


I am simply trying to create a script that will:

  1. Disable Current GameObject

  2. Find next GameObject

  3. Enable next GameObject


Here is my current attempt at naming each GameObject a number 1-400 and converting a variable back-and-forth between a String and an Int:

 private var currentObject : int = 1;
 
 function NextFrame () {
 
     currentObject.ToString();
     
     GameObject.Find("currentObject").SetActive (false);
     
     int.Parse(currentObject) += 1;
     
     GameObject.Find("currentObject").SetActive (true);
 }
Comment

People who like this

0 Show 4
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 supercouge · Jul 10, 2013 at 12:50 PM 0
Share

Using GameObject.Find each frame is a bad idea. Why don't you want to use a hashtable/dico ?

avatar image DavidDebnar · Jul 10, 2013 at 01:51 PM 0
Share

I agree with supercouge. If you don't want a dictionary, atleast store the Game Objects in a Generic List and access them that way.

avatar image Jamora · Jul 10, 2013 at 11:08 PM 0
Share

In case you're wondering why your original script wasn't working, it is because the ToString-method only returns a representation of the object as a string, it doesn't change the type; currentObject remains an int even after calling its ToString(). Also, the parsing is unnecessary, since it is already an int.

Furthermore, you are trying to find GameObjects named "currentObject". the correct way would have been to call currentObject.ToString(); instead.

An additional complication arises from the fact that each instance of the script (on the different GameObjects) keeps track of its own variables. Thus, adding one to currentObject in each script results in a currentObject that has a value of 2 in each instance of the script. This can be remedied by either accessing currentObject in the following script, or using a static variable.

avatar image yotingo · Jul 10, 2013 at 11:24 PM 0
Share

supercouge - I wasn't planning to use GameObject.Find each frame, I plan to call the 'NextFrame' function every few seconds via the animation window. I don't have a problem with Hastables or Dictionaries if they can be populated automatically and referred to sequentially (each time I call the 'NextFrame' function the next GameObject is referenced). I am honestly not too familiar with them.

David Debnar - You gave me a great answer on how I would accomplish this using my idea and an array but you are a lot more experienced than me. Do you have a better approach that you might suggest?

2 Replies

· Add your reply
  • Sort: 
avatar image
Best Answer

Answer by DavidDebnar · Jul 10, 2013 at 01:57 PM

Here's a modified version of your method. First, the gameobjects tagged 'Animate' are stored in a list and then sorted by name. Then each tick, it does basically the same as your script, but uses the array to look the gameobjects up instead of the .Find method.

 import System.Linq;
 
 private var gameObjectList : GameObject[];
 private var currentObject : int = -1;
  
 function Start () {
     gameObjectList = GameObject.FindGameObjectsWithTag("Animate").OrderBy(function(g){g.SetActive(false);return g.name;}).ToArray();
 }
  
 function NextFrame () {
     gameObjectList[(currentObject++%gameObjectList.Length+gameObjectList.Length)%gameObjectList.Length].SetActive(false);
     gameObjectList[currentObject].SetActive(true);
 }

--David--

Comment

People who like this

0 Show 4 · 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 yotingo · Jul 10, 2013 at 11:17 PM 0
Share

Thanks for the response! Your answer is very helpful.

I am unfamiliar with System.Linq apparently it is a part of the .net framework, according to my research. Everything else I understand except: OrderBy(function(g) g.name).

I set up all my GameObjects with the Animate tag and everything seems to be function except the script doesn't proceed to activate the second game object after disabling the first. So the first time function 'NextFrame' is called GameObject "0" is disabled but GameObject "1" is never set active.

I appreciate your help.

avatar image DavidDebnar · Jul 10, 2013 at 11:43 PM 0
Share

I've editted the code a bit, but also make sure, that all your gameobjects are active.

avatar image DavidDebnar · Jul 10, 2013 at 11:47 PM 0
Share

And as for Linq, it's used to do stuff like sorting with arrays/lists/dictionaries/etc.

avatar image yotingo · Jul 11, 2013 at 09:27 AM 0
Share

All your help has been great, it works perfectly! I can't thank you enough for taking the time to help me out with this. I am going to include a special thanks to you in the credits of my project and a link to your answer.

Thanks!

avatar image

Answer by TonyLi · Jul 10, 2013 at 01:49 PM

Try this:

 var objectHolder : GameObject;
 private var objects : Transform[];
 private var current : int;
 
 function Start() {
     objects = objectHolder.GetComponentsInChildren(Transform) as Transform[];
     for (var t : Transform in objects) {
         t.gameObject.SetActive(false);
     }
     current = 0;
     objects[current].gameObject.SetActive(true);
 }
 
 function NextFrame() {
     objects[current].gameObject.SetActive(false);
     current = (current + 1) % objects.Length;
     objects[current].gameObject.SetActive(true);
 }

Notes:

  1. Put your 400 objects under a single game object in the hierarchy, and assign this object to the objectHolder property of the script.

  2. The Start() function makes an array of all of the objects under the objectHolder, and activates only the first one.

  3. The NextFrame() function just cycles through the array.

  4. You should check bounds and check for null, but I omitted that for clarity.

  5. Untested code, but it should get the idea across. [Edit: Still untested, but should probably work now. :-)]

Comment

People who like this

0 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 yotingo · Jul 10, 2013 at 10:51 PM 0
Share

Thanks for the fast response, I really appreciate it. I was unaware that an array could be filled automatically.

The script you suggested seems pretty straightforward but for some reason the screen turns grey at start and remains that way. All objects inside my 'objectHolder' are disabled properly on start but the first object (0 in the array) is never set active (same with the following objects). I'm not sure what is causing the script to freeze. When I disable the script in the inspector, the grey screen no longer appears and the rest of the game functions as intended.

I'm sure the answer is obvious, I apologize for my oversight.

avatar image TonyLi · Jul 11, 2013 at 03:05 AM 0
Share

Hence my note #5 (untested code) :-). I edited my answer. I wasn't thinking before. FindObjectsOfType grabbed all the objects in the whole scene, which turned off everything.

The edited version above uses GetComponentsInChildren() to get every Transform component in the objectHolder hierarchy (and just the objectHolder hierarchy, not the whole scene). Be aware that it also grabs objectHolder's transform, but I don't if that's a big deal for you or not.

avatar image yotingo · Jul 11, 2013 at 09:36 AM 0
Share

Thank you again for taking the time to help me. Your approach to the problem really helped me understand what I was doing wrong in my attempts.

I wish I had enough rep to up-vote your answer! I will give thanks in the credits of my project and I hope it will raise awareness of your mad coding skillz :)

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

19 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

Related Questions

A node in a childnode? 1 Answer

Why can't I save an array? 1 Answer

How do you display a saved name on the screen? 2 Answers

How to make an int not pass 0 2 Answers

How to split string into two integers? 3 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