• 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 Alturis2 · Jul 29, 2017 at 05:28 PM · gameobjectgameobjectsinstantiation

Tips on improving instantiate performance?

I am working on a game that uses items and slots to put them in. There is a store menu with a grid of slots that fill in dynamically when the menu opens using a slot prefab that is also used at runtime for the player inventory.

Each slot has multiple UI components in it for different things like icon, text, status indicators etc.

What I am seeing is that the frame that the shop menu is opened it fills in a grid of 64 of these slot prefabs to then display items for sale. The CPU ms it takes to instantiate those slots is enormous like 250ms on my particular rig. At any rate, it causes a noticeable frame hitch compared to the regular framerate of the game.

I looked at the profiler and all this time seems to be tied up within the internal Instantiate code (Copy, Awake, Produce).

I was wondering if there were some secrets I could use to help increase the performance of this. Is there any way to batch instantiate? Would that even help? Should I think about just reducing the amount of stuff that is in each slot? Instantiating them over many game frames and then making the menu grid visible only after they are done? Just looking for tips from the community.

It's not a huge issue for the game but its noticeable and I would like to polish it up.

Edit: grammar

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 Alturis2 · Jul 29, 2017 at 05:34 PM 0
Share

NOTE: Each slot prefab consists of 19 game objects including the prefab itself.

So instantiating 64 of them is creating 1,216 game objects.

avatar image Alturis2 · Jul 29, 2017 at 05:43 PM 0
Share

Actually, what I am thinking I need to do is invent some kind of GameObjectCache component that is always present. And the menu system could pull objects already pre-instantitated and set them to be a child, then put them back in the cache when done.

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Alturis2 · Jul 30, 2017 at 01:44 AM

Yeah creating a GameObjectCache concept completely wiped out this hitch. I have it in the DontDestroyOnLoad scene and keep a static reference to it in a global static GameState object.

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 #if UNITY_EDITOR
 using UnityEditor;
 #endif //#if UNITY_EDITOR
 
 public class GameObjectCache : MonoBehaviour
 {
     public Dictionary< string, List<GameObject> >    cache;
     public Dictionary< string, GameObject >         root;
 
     public GameObjectCache()
     {
         cache = new Dictionary<string, List<GameObject>>();
         root = new Dictionary<string, GameObject>();
     }
 
     public void Start()
     {
         if ( GameState.ObjectCache == null )
             GameState.ObjectCache = this;
     }
 
     public void OnDestroy()
     {
         if ( GameState.ObjectCache == this )
             GameState.ObjectCache = null;
     }
 
     public List<GameObject> GetList( string prefabPath )
     {
         prefabPath = prefabPath.ToLower();
 
         GameObject prefab = Resources.Load<GameObject>( prefabPath );
 
         if ( prefab == null )
         {
             Debug.LogError( "GameObjectCache - invalid prefab path '" + prefabPath + "'" );
             return null;
         }
 
         if ( !cache.ContainsKey( prefabPath ) )
             cache.Add( prefabPath, new List<GameObject>() );
 
         if ( !root.ContainsKey( prefabPath ) )
         {
             GameObject newRoot = new GameObject();
             newRoot.transform.SetParent( transform );
             newRoot.SetActive( false );
             newRoot.name = prefabPath;
             root.Add( prefabPath, newRoot );
         }
 
         return cache[prefabPath];
     }
 
     public void Precache( string prefabPath, int count )
     {
         prefabPath = prefabPath.ToLower();
 
         GameObject prefab = Resources.Load<GameObject>( prefabPath );
 
         List<GameObject> list = GetList( prefabPath );
         if ( list != null && prefab != null )
         {
             for ( int i = count - list.Count; i > 0; i-- )
             {
                 GameObject obj = GameObject.Instantiate<GameObject>( prefab, root[prefabPath].transform );
                 if ( obj != null )
                     cache[prefabPath].Add( obj );
             }
         }
     }
 
     public GameObject Pop( string prefabPath )
     {
         prefabPath = prefabPath.ToLower();
 
         List<GameObject> list = GetList( prefabPath );
 
         if ( list.Count == 0 )
         {
             GameObject prefab = Resources.Load<GameObject>( prefabPath );
             if ( prefab != null )
                 return GameObject.Instantiate<GameObject>( prefab );
         }
 
         GameObject result = list[0];
 
         list.RemoveAt( 0 );
 
         if ( result == null )
         {
             GameObject prefab = Resources.Load<GameObject>( prefabPath );
             if ( prefab != null )
                 return GameObject.Instantiate<GameObject>( prefab );
         }
 
         return result;
     }
 
     public void Push( string prefabPath, GameObject gameObj )
     {
         if ( gameObj == null )
             return;
 
         prefabPath = prefabPath.ToLower();
 
         List<GameObject> list = GetList( prefabPath );
         if ( list != null )
         {
             list.Add( gameObj );
             gameObj.transform.SetParent( root[prefabPath].transform );
         }
     }
 }
 
 #if UNITY_EDITOR
 [CustomEditor( typeof( GameObjectCache ), true )]
 public class EditorGameObjectCache : Editor
 {
     public override void OnInspectorGUI()
     {
         Handles.BeginGUI();
 
         GUI.changed = false;
 
         GameObjectCache editObject = (GameObjectCache)target;
 
         int total = 0;
         EditorGUILayout.Space();
         EditorGUILayout.LabelField( "Cached Game Objects:" );
         foreach ( string key in editObject.cache.Keys )
         {
             for ( int i = editObject.cache[key].Count - 1; i >= 0; i-- )
             {
                 if ( editObject.cache[key][i] == null )
                     editObject.cache[key].RemoveAt( i );
             }
 
             EditorGUILayout.LabelField( "   " + key + ": " + editObject.cache[key].Count );
 
             total += editObject.cache[key].Count;
         }
         EditorGUILayout.LabelField( "Total: " + total);
         EditorGUILayout.Space();
 
         if ( GUI.changed )
             editObject.SetDirty();
 
         Handles.EndGUI();
     }
 }
 #endif //#if UNITY_EDITOR
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.

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

132 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 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 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

How can I move a gameobjects box Collider with another asset? 0 Answers

Keep UI object disabled unless it's inside canvas 0 Answers

gameObjects working in one scene, but none of the others? 1 Answer

List of unused game objects and prefabs 1 Answer

Make objects not interactable 0 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