Search code examples
c#unity-game-engineaugmented-realitygameobjectculling

Dynamically render GameObject in Unity C#


I am working on a AR project, where the virtual objects will be shown/hide in the scene based on information found in a text file. The text files will be updated from an external service. So I need to read the file on a frequent interval and update the scene. As a result I only have the Camera object and I am rendering the scene in OnPreCull() method.

The text files contain many objects but not all the objects are within the scene at any instance of time. I was looking for a way to render only those objects that are within the scene.

Will creating and placing the gameobjects in the OnPreCull() method crate any performance issue?


Solution

  • Will creating and placing the gameobjects in the OnPreCull() method crate any performance issue?

    Yes absolutely ... so would it if you do it in Update or any other repeatedly called method.

    Instead you should rather Instantiate objects in Awake and only activate or deactivate them.

    Let's say you have 3 objects A, B and C than I would make a kind of controller class that looks like

    public class ObjectsController : MonoBehaviour
    {
        // Define in which intervals the file should be read/ the scene should be updated
        public float updateInterval;
    
        // Prefabs or simply objects that are already in the Scene
        public GameObject A;
        public GameObject B;
        public GameObject C;
        /* Etc ... */
    
        // Here you map the names from your textile to according object in the scene
        private Dictionary<string, GameObject> gameObjects = new Dictionary<string, gameObjects>();
    
        private void Awake ()
        {
            // if you use Prefabs than instantiate your objects here; otherwise you can skip this step
            var a = Instantiate(A);
            /* Etc... */
    
            // Fill the dictionary
            gameObjects.Add(nameOfAInFile, a);
    
            // OR if you use already instantiated references instead
            gameObjects.Add(nameOfAInFile, A);
        }
    }
    
    private void Start()
    {
        // Start the file reader
        StartCoroutine (ReadFileRepeatedly());
    }
    
    // Read file in intervals
    private IEnumerator ReadFileRepeatedly ()
    {
        while(true)
        {
            //ToDo Here read the file
    
            //Maybe even asynchronous?
            // while(!xy.done) yield return null;
    
            // Now it depends how your textile works but you can run through 
            // the dictionary and decide for each object if you want to show or hide it
            foreach(var kvp in gameObjects)
            {
                bool active = someConditionDependingOnTheFile;
    
                kvp.value.SetActive(active);
    
                // And e.g. position it only if active
                if (active)
                {
                    kvp.value.transform.position = positionFromFile;
                }
            }
    
            // Wait for updateInterval and repeat
            yield return new WaitForSeconds (updateInterval);
        }
    }
    

    If you have multiple instances of the same prefab you also should have a look at Object Pooling