如何调整粒子系统中所有粒子的大小?

时间:2019-01-16 12:46:37

标签: unity3d particle-system

我正在尝试使用滑块动态调整粒子大小,以及更改其颜色。

粒子用于在3D散点图中显示数据点。我正在使用以下代码:https://github.com/PrinzEugn/Scatterplot_Standalone

private ParticleSystem.Particle[] particlePoints;
void Update () {
    pointScale = sizeSlider.value;
    for (int i = 0; i < pointList.Count; i++) {
        Quaternion quaternion = Camera.current.transform.rotation;
        Vector3 angles = quaternion.eulerAngles;
        // Set point color
        particlePoints[i].startColor = new Color(angles.x, angles.y, angles.z, 1.0f);
        particlePoints[i].transform.localScale = new Vector3(pointScale, pointScale, pointScale);
    }

}

问题是粒子没有转换方法,并且更改“ startColour”不会更改任何内容。

API指出“粒子的当前大小是根据此值和活动大小模块按程序计算的。”

这是什么意思,我该如何更改粒子的大小?

2 个答案:

答案 0 :(得分:0)

我刚刚看过PointRenderer.cs-> CreateParticlesPlacePrefabPoints很好地提示了必须更改的地方。

所以我想您只需更改比例值

foreach (var point in particlePoints) 
{
    Quaternion quaternion = Camera.current.transform.rotation;
    Vector3 angles = quaternion.eulerAngles;
    // Set point color
    point.startColor = new Color(angles.x, angles.y, angles.z, 1.0f);
    point.startSize = sizeSlider.value;
}

然后调用

GetComponent<ParticleSystem>().SetParticles(particlePoints, particlePoints.Length);

尽管您是否真的会在Update中进行此操作,这还是个问题。我宁愿在sizeSlider.onValueChanged中执行此操作,仅在必要时进行此操作(您甚至可以在更新视图之前设置一定的阈值,但必须对其进行更改),但是对于颜色来说,除了在其中进行操作外,别无选择Update,但至少要在此使用阈值:

privtae ParticleSystem ps;

// I assume you have that referenced in the inspector
public Slider sizeSlider;

// flag to control whether system should be updated
private bool updateSystem;

privtae void Awake()
{
    ps = GetComponent<ParticleSystem>();
}

private void OnEnable()
{
    // add a listener to onValueChanged
    // it is secure to remove it first (even if not there yet)
    // this makes sure it is not added twice
    sizeSlider.onValueChanged.RemoveListener(OnsliderChanged());
    sizeSlider.onValueChanged.AddListener(OnsliderChanged());
}

private void OnDisable()
{
    // cleanup listener
    sizeSlider.onValueChanged.RemoveListener(OnsliderChanged());
}

private void OnSliderChanged()
{
    foreach (var point in particlePoints) 
    {
        point.startSize = sizeSlider.value; 
    }

    // do the same also for the instantiated prefabs
    foreach(Transform child in PointHolder.transform)
    {
        child.localScale = Vecto3.one * sizeSlider.value;
    }

    updateSystem = true;
}

private Quaternion lastCameraRot;

public float CameraUpdateThreshold;

private void Update()
{
    if(Quaternion.Angle(Camera.current.transform.rotation, lastCameraRot) > CameraUpdateThreshold)
    {
        foreach (var point in particlePoints) 
        {
            Quaternion quaternion = Camera.current.transform.rotation;
            Vector3 angles = quaternion.eulerAngles;
            // Set point color
            point.startColor = new Color(angles.x, angles.y, angles.z, 1.0f);
        }

        lastCameraRot = Camera.current.transform.rotation;
        updateSystem = true;
    }

    if(!updateSystem) return;

    updateSystem = false;
    ps.SetParticles(particlePoints, particlePoints.Length);
}

答案 1 :(得分:0)

由于以前的回答,我设法使它起作用:

在PlacePrefabPoints方法中,我将每个实例化的预制件添加到列表中,并向滑块添加一个侦听器,如下所示:

void changedPointSize(){
    pointScale = sizeSlider.value;
    for (int i = 0; i < objects.Count; i++) {
        objects[i].transform.localScale = new Vector3(pointScale, pointScale, pointScale);
    }
}

谢谢!