Md Monjur Ul Hasan
Md Monjur Ul Hasan

Reputation: 1801

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?

Upvotes: 0

Views: 1618

Answers (2)

derHugo
derHugo

Reputation: 90852

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

Upvotes: 1

Monza
Monza

Reputation: 755

I'd recommend adding each of the game objects to a registry and the switching them on or off (dis/enable SetActive) via the registry class's Update() cycle.

One Update() process to retrieve and handle the server file, another Update() process to dis/enable objects. Might sound oversimplified however it's the fastest way I think of getting the result.

Good Luck!

Upvotes: 0

Related Questions