在Unity C#中动态渲染GameObject

时间:2019-01-02 01:11:03

标签: c# unity3d augmented-reality gameobject culling

我正在研究一个AR项目,其中将基于文本文件中的信息在场景中显示/隐藏虚拟对象。文本文件将通过外部服务进行更新。因此,我需要经常读取文件并更新场景。结果,我只有Camera对象,并且正在使用OnPreCull()方法渲染场景。

文本文件包含许多对象,但在任何时间实例中并非所有对象都在场景内。我一直在寻找一种仅渲染场景中那些对象的方法。

OnPreCull()方法中创建并放置游戏对象会导致性能问题吗?

2 个答案:

答案 0 :(得分:1)

  

将游戏对象创建并放置在OnPreCull()方法中会导致性能问题吗?

是的,绝对……如果您使用Update或任何其他重复调用的方法来这样做,也会如此。

相反,您应该实例化Awake中的对象,而仅激活或停用它们。

比方说,您拥有3个对象ABC,而我将使之成为一种看起来像这样的控制器类

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);
    }
}

如果您具有同一预制件的多个实例,则还应该查看Object Pooling

答案 1 :(得分:0)

我建议将每个游戏对象添加到注册表中,并通过注册表类的Update()周期将其打开或关闭(禁用/启用SetActive)。

一个Update()进程检索和处理服务器文件,另一个Update()进程禁用/启用对象。声音可能过于简单了,但这是我想获得结果的最快方法。

祝你好运!

相关问题