c# - 如何在不减慢至 0.3 FPS 的情况下移动 500 个 Rigidbody 立方体?

标签 c# performance unity-game-engine instance frame-rate

过去几周我一直在尝试 Unity;我还是个新人。我稍微深入研究了 ECS、计算着色器等,但如果没有必要,由于复杂性,我真的不想实现这些解决方案。

默认的 Unity 物理引擎真的无法处理使用 RigidBodies 一次性移动 500 个立方体实例吗?或者我做事的方式对性能特别不利?

这是我正在使用的代码;它只是一个空游戏对象上的一个脚本。实例化 500 个立方体时,速度减慢至 16FPS;通过 Rigidbody MoveTowards 一次性移动它们时,速度减慢至 0.3 FPS。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SpawnAndMove : MonoBehaviour
{
    public TargetCube TargetCube;
    public GameObject CubePrefab;
    public Vector3 brickPosition = new Vector3(10, 0, 0);
    GameObject[] objects;
    int moveCubeInstances;

    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine(Countdown());
    }

    IEnumerator Countdown()
    {
        yield return new WaitForSeconds(3f);
        for (int i = 0; i < 500; i++)
        {
            var cubeClone = Instantiate(CubePrefab, transform.position + brickPosition, transform.rotation);
            cubeClone.tag = "CubeInstance";
        }

        objects = GameObject.FindGameObjectsWithTag("CubeInstance");

        yield return new WaitForSeconds(3f);
        moveCubeInstances = 1;

        while (moveCubeInstances == 1)
        {
            for (int i = 0; i < 500; i++)
            {
                objects[i].GetComponent<Rigidbody>().transform.position =
                            Vector3.MoveTowards(objects[i].GetComponent<Rigidbody>().transform.position, TargetCube.transform.position, 12f);
            }
            yield return new WaitForFixedUpdate();
        }

        print("exited while loop");
    }
}

感谢您在这里提供的任何帮助。

最佳答案

  • 您调用 FindGameObjectsWithTag进行额外的搜索,不仅针对新的 500 个对象,还针对该场景中的所有其他对象
  • transform已经缓存的字段,要调用它,您不需要执行 GetComponent<>
  • Instantiate是一个非常困难的操作,最好提前完成,甚至可以将其分成每帧多次调用,例如每次 50 个,但绝对不是一帧 500 个,而是使用 Pooling ( https://docs.unity3d.com/Manual/MobileOptimizationPracticalScriptingOptimizations.html )

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    public class SpawnAndMove : MonoBehaviour
    {
        public TargetCube TargetCube;
        public Rigidbody CubePrefab;
        public Vector3 brickPosition = new Vector3(10, 0, 0);
        Rigidbody[] objects;
        int moveCubeInstances;
    
        void Start()
        {
            StartCoroutine(Countdown());
        }
    
        IEnumerator Countdown()
        {
            yield return new WaitForSeconds(3f);
            objects = new Rigidbody[500];
            for (int i = 0 ; i < 500 ; i++)
            {
                Rigidbody cubeClone = Instantiate(CubePrefab, transform.position + brickPosition, transform.rotation);
                cubeClone.tag = "CubeInstance";
                objects[i] = cubeClone;
                if (i % 50 == 0)
                {
                    yield return new WaitForFixedUpdate();
                }
            }
    
            yield return new WaitForSeconds(3f);
            moveCubeInstances = 1;
    
            while (moveCubeInstances == 1)
            {
                for (int i = 0 ; i < 500 ; i++)
                {
                    objects[i].transform.position =
                            Vector3.MoveTowards(objects[i].transform.position, TargetCube.transform.position, 12f);
                }
                yield return new WaitForFixedUpdate();
            }
    
            print("exited while loop");
        }
    }
    

关于c# - 如何在不减慢至 0.3 FPS 的情况下移动 500 个 Rigidbody 立方体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57015417/

相关文章:

C# : Distinctions between various <string, 字符串> 集合

c# - JSON.NET 序列化对象,其中属性名称以点开头

c# - 在 mvc 之类的文件夹中而不是站点根目录中的 Webform 路由主页

c# - 如何正确加载预制件

ios 设备上的构建大小更大

ios - 如何减小 Unity iOS Build 的大小并提高速度

c# - EventWaitHandle 是否必须处理虚假唤醒?

c++ - 处理器真的计算乘以零或一吗?为什么?

ios - 使用 VBO 的 OpenGL ES iOS 绘图性能比不使用 VBO 慢很多

java - JProfiler : knowing which method is calling for java objects