Unity AddComponent非常低效而缓慢

问题描述 投票:0回答:4

[我有一个近120,000星的数据集和215个星的测试数据集(取自主要数据集),并且我正在编写一个程序来读取数据集并在3D地球模型周围绘制恒星图。

  1. 读取数据集并将信息存储在多个列表中(在一个单例脚本中)
  2. 然后,模拟脚本读取列表(Singleton被破坏以使程序更高效):
void listStars()
{
    int i = 0;
    while (i < (StarDataBank.Instance.NumOfStars))
    {
        int primaryID = int.Parse(StarDataBank.Instance.StarIDID[i]);
        string properName = StarDataBank.Instance.StarName[i];
        string HIPID = StarDataBank.Instance.StarIDHIP[i];
        string HDID = StarDataBank.Instance.StarIDHD[i];
        string HRID = StarDataBank.Instance.StarIDHR[i];
        string GLID = StarDataBank.Instance.StarIDGL[i];
        string BFID = StarDataBank.Instance.StarIDBF[i];
        decimal rightAscension = Convert.ToDecimal(StarDataBank.Instance.StarRA[i]);
        decimal declination = Convert.ToDecimal(StarDataBank.Instance.StarDec[i]);
        decimal Mag;
        decimal CI;
        float scale = 0;
        int r = 0;
        int g = 0;
        int b = 0;

        Decimal.TryParse((StarDataBank.Instance.StarMag[i]), out Mag);
        Decimal.TryParse((StarDataBank.Instance.StarCI[i]), out CI);

        if (PlayerPrefs.GetInt("dynamicSize") == 1)
        {
            if (Mag < -1)
            {
                scale = 77.5f;
            }
            else
            {
                if (Mag > -1 && Mag <= 5)
                {
                    scale = 52.5f;
                }
                else
                {
                    if (Mag > 5 && Mag <= 10)
                    {
                        scale = 32.5f;
                    }
                    else
                    {
                        if (Mag > 10 && Mag <= 15)
                        {
                            scale = 17.5f;
                        }
                        else
                        {
                            if (Mag > 15 && Mag <= 20)
                            {
                                scale = 7.5f;
                            }
                            else
                            {
                                if (Mag > 20 && Mag <= 25)
                                {
                                    scale = 2.5f;
                                }
                            }
                        }
                    }
                }
            }
        } 
        else
        {
            scale = 20;
        }
        StartCoroutine(placeStars(primaryID, properName, HIPID, HDID, HRID, GLID, BFID, rightAscension, declination, Mag, CI, scale));
        i++;
    }
    DestroyImmediate(StarDataBank.Instance.gameObject);
}
  1. 使用此方法绘制每颗星星:
    IEnumerator placeStars(int primaryID, string properName, string HIPID, string HDID, string HRID, string GLID, string BFID, decimal rightAscension, decimal declination, decimal magnitude, decimal colourIndex, float scale)
    {
        var thisStar = (GameObject)Instantiate(prefabStar, transform.position + getVectors(Convert.ToDecimal(rightAscension), Convert.ToDecimal(declination)), Quaternion.identity);
        thisStar.name = (primaryID).ToString();
        thisStar.transform.parent = StarObject.transform;
        thisStar.transform.localScale = new Vector3(scale, scale, scale);
        thisStar.AddComponent<Star>().newStar(primaryID, properName, HIPID, HDID, HRID, GLID, BFID, rightAscension, declination, magnitude, colourIndex);
        yield return null;
    }

使用只有215星的较小测试数据集,我可以将Star类附加到每个实例化星。

但是对于拥有约12万颗星的大型完整数据集,Unity编辑器仅在按下播放按钮后挂起。当我注释掉以下行时:thisStar.AddComponent<Star>().newStar(...);程序按预期工作,场景中绘制了每颗星星,唯一的事情是Star类未附加到每个新实例化的星星上。

这意味着AddComponent函数不能很好地与我的代码配合使用,尤其是在使用大型数据集的情况下。

是否有更有效的方法将Star类附加到每个实例化的Star GameObject?

而且,当我用完单例后销毁单例时,它会有所不同吗?我使用IEnumerator实例化是否有所不同?

编辑:这是星级班:

public class Star : MonoBehaviour
{


    Simulation simulationInstance;


    public int primaryID;  // primary key                                      NEEDS TO BE SET
    public string properName;  // some stars have names                        NEEDS TO BE SET
    public string HIPID;   // ID of star from Hipparcos catalogue              NEEDS TO BE SET
    public string HDID;    // ID of star from Henry Draper catalogue           NEEDS TO BE SET
    public string HRID;    // ID of star from Harvard Revised catalogue        NEEDS TO BE SET
    public string GLID;    // ID of star from Gliese catalogue                 NEEDS TO BE SET
    public string BFID;    // ID of star from BayerFlamsteed catalogue         NEEDS TO BE SET
    public decimal rightAscension; // right ascension of star                  NEEDS TO BE SET
    public decimal declination;    // declination of star                      NEEDS TO BE SET
    public decimal magnitude;  // magnitude of the star                        NEEDS TO BE SET
    public decimal colourIndex;    // colour index of the star                 NEEDS TO BE SET
    public int scale;  // size of the sphere that will represent the star      AUTOMATICALLY SET
    public int red;    // red colour (0-255)                                   AUTOMATICALLY SET
    public int green;  // green colour (0-255)                                 AUTOMATICALLY SET  
    public int blue;   // blue colour (0-255)                                  AUTOMATICALLY SET
    public double x;   //                                                      AUTOMATICALLY SET
    public double y;   //                                                      AUTOMATICALLY SET
    public double z;   //                                                      AUTOMATICALLY SET

    void Start()
    {
        simulationInstance = FindObjectOfType<Simulation>();
    }

    public void newStar(int primaryID, string properName, string HIPID, string HDID, string HRID, string GLID, string BFID, decimal rightAscension, decimal declination, decimal magnitude, decimal colourIndex)
    {
        this.primaryID = primaryID;
        this.properName = properName;
        this.HIPID = HIPID;
        this.HDID = HDID;
        this.HRID = HRID;
        this.GLID = GLID;
        this.BFID = BFID;
        this.rightAscension = rightAscension;
        this.declination = declination;
        this.magnitude = magnitude;
        this.colourIndex = colourIndex;

    }

    public void tellStarInfoPanel()
    {
        simulationInstance.starInfoPanelManager(primaryID, properName, HIPID, HDID, HRID, GLID, BFID, rightAscension, declination, magnitude, colourIndex);
    }
}

编辑:我已将listStars()用作协程,而将placeStars()用作常规方法

    public void placeStars(int primaryID, string properName, string HIPID, string HDID, string HRID, string GLID, string BFID, decimal rightAscension, decimal declination, decimal magnitude, decimal colourIndex, float scale)
    {
        var thisStar = (GameObject)Instantiate(prefabStar, transform.position + getVectors(Convert.ToDecimal(rightAscension), Convert.ToDecimal(declination)), Quaternion.identity);
        thisStar.name = (primaryID).ToString();
        thisStar.transform.parent = StarObject.transform;
        thisStar.transform.localScale = new Vector3(scale, scale, scale);
        thisStar.GetComponent<Star>().newStar(primaryID, properName, HIPID, HDID, HRID, GLID, BFID, rightAscension, declination, magnitude, colourIndex);
        starsRendered++;  
    }

我有一个将近120,000个恒星的数据集和一个215个恒星的测试数据集(取自主要数据集),并且我正在编写一个程序来读取数据集并在3D地球模型周围绘制恒星。 ...

c# class unity3d instantiation large-data
4个回答
0
投票

避免在AddComponent中使用performance critical code


0
投票

如果您认为AddComponent()在计算上过于繁琐,那么最好仔细看一下Start组件,或者甚至更好地运行应该准确查明罪魁祸首的Unity探查器工具,将是明智的。


0
投票

您需要知道,这不是Monobehaviour / Component OOP模型的好用例。为此,您可能需要考虑切换到preview


0
投票

是否有更有效的方法将Star类附加到每个实例化的Star GameObject?

© www.soinside.com 2019 - 2024. All rights reserved.