在 Unity C# 中动态渲染游戏对象
Dynamically render GameObject in Unity C#
我正在开发一个 AR 项目,其中虚拟对象将根据在文本文件中找到的信息 shown/hide 在场景中。文本文件将从外部服务更新。所以我需要经常读取文件并更新场景。结果,我只有 Camera 对象,并且我在 OnPreCull()
方法中渲染场景。
文本文件包含许多对象,但并非所有对象在任何时候都在场景中。我一直在寻找一种方法来只渲染场景中的那些对象。
在 OnPreCull()
方法中创建和放置游戏对象是否会产生任何性能问题?
我建议将每个游戏对象添加到注册表并通过注册表 class 的 Update() 周期打开或关闭它们 (dis/enable SetActive)。
一个 Update() 进程用于检索和处理服务器文件,另一个 Update() 进程用于 dis/enable 个对象。可能听起来过于简单,但这是我认为获得结果的最快方式。
祝你好运!
Will creating and placing the gameobjects in the OnPreCull() method crate any performance issue?
绝对是......如果你在 Update
或任何其他重复调用的方法中这样做,也会如此。
相反,您应该在 Awake
中实例化对象,并且只激活或停用它们。
假设你有 3 个对象 A
、B
和 C
,我会制作一种看起来像
的控制器 class
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
我正在开发一个 AR 项目,其中虚拟对象将根据在文本文件中找到的信息 shown/hide 在场景中。文本文件将从外部服务更新。所以我需要经常读取文件并更新场景。结果,我只有 Camera 对象,并且我在 OnPreCull()
方法中渲染场景。
文本文件包含许多对象,但并非所有对象在任何时候都在场景中。我一直在寻找一种方法来只渲染场景中的那些对象。
在 OnPreCull()
方法中创建和放置游戏对象是否会产生任何性能问题?
我建议将每个游戏对象添加到注册表并通过注册表 class 的 Update() 周期打开或关闭它们 (dis/enable SetActive)。
一个 Update() 进程用于检索和处理服务器文件,另一个 Update() 进程用于 dis/enable 个对象。可能听起来过于简单,但这是我认为获得结果的最快方式。
祝你好运!
Will creating and placing the gameobjects in the OnPreCull() method crate any performance issue?
绝对是......如果你在 Update
或任何其他重复调用的方法中这样做,也会如此。
相反,您应该在 Awake
中实例化对象,并且只激活或停用它们。
假设你有 3 个对象 A
、B
和 C
,我会制作一种看起来像
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