如何在Unity中播放特定克隆的游戏对象的粒子?

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

我现在正在Unity中制作一个简单的游戏。有一些锥从天而降,玩家需要控制一个立方体才能躲避它们。当圆锥体撞击立方体时,它会降低立方体的HP,并散发出一些颗粒。这是我的脚本:

public class move : MonoBehaviour{

ParticleSystem particle;

static move instance;

void Start()
{
    particle = FindObjectOfType<ParticleSystem>();
    instance = this;
}

public static void PlayParticles()
{
    instance.particle.Play();
}
}

第二:

private void OnCollisionEnter(Collision collision)
{
    if (collision.gameObject.CompareTag("cone"))
    {
        move.PlayParticles();
        GameDirector.DecreaseHp(0.25f);

    }

}

第一个脚本附加到圆锥形预制件,第二个脚本附加到立方体。但是问题在于,当一个圆锥撞击立方体时,其他圆锥会发出粒子,而不是撞击立方体的圆锥。我该如何解决这个问题?非常感谢您的帮助!

c# unity3d particles particle-system
2个回答
0
投票
  1. 从多维数据集中删除与圆锥相关的逻辑:

    private void OnCollisionEnter(碰撞冲突){如果(collision.gameObject.CompareTag(“ cone”)){// move.PlayParticles(); // ------------删除此行GameDirector.DecreaseHp(0.25f);}

    }

  2. 使检查器中可分配的粒子变量-添加[SerializeField]属性。并在检查器中分配它。

  3. 将碰撞处理添加到圆锥脚本中。
  4. 从脚本中删除不必要的静态变量。

类似这样的东西:

public class move : MonoBehaviour
{

[SerializeField] //------- Add attribute and do not forget to assign PS in inspector
ParticleSystem particle;

//static move instance; //----- Remove

//Remove Start:
/*
    void Start()
    {
        particle = FindObjectOfType<ParticleSystem>();
        instance = this;
    }
*/
//Remove PlayParticles:
/*
    public void PlayParticles()
    {
        Change:
        instance.particle.Play();
    }
*/
    //---- Add collision check
    private void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.CompareTag("cube")) //----- Set proper tag to your cube
        {
            particle.Play();
        }

    }

}

0
投票

正如我所看到的,您正在(ab!)使用Singleton模式进行所有操作,并调用了很多应该作为实例化方法/属性的东西static


因此,每个宁愿您在自己的层次结构中都有move脚本以及ParticleSystem,您宁愿这样做

public class move : MonoBehaviour
{
    // Already reference this via the Inspector by dragging the 
    // GameObject with the ParticleSystem into this slot
    [SerializeField] private ParticleSystem particle;

    private void Awake()
    {
        // As fallback get it on runtime
        if(!particle) particle = GetComponentInChildren<ParticleSystem>(true);
    }

    // Use a normal instanced method
    public void PlayParticles()
    {
        particle.Play();
    }
}

然后从冲突中获取实例:

private void OnCollisionEnter(Collision collision)
{
    if (collision.gameObject.CompareTag("cone"))
    {
        // Get the instance of the component
        var moveInstance = collision.gameObject.GetComponent<move>();
        if(!moveInstance)
        {
             Debug.LogError($"There is no {nameof(move)} component attached to the colliding object {collision.gameObject.name}!", this);   
        }
        else
        {
            // call the method of this instance
            moveInstance.PlayParticles();
        }
        GameDirector.DecreaseHp(0.25f);
    }
}

但是似乎您也可以让播放器自己直接处理整个事情,然后简单地做

public class move : MonoBehaviour
{
    // Already reference this via the Inspector by dragging the 
    // GameObject with the ParticleSystem into this slot
    [SerializeField] private ParticleSystem particle;

    void Start()
    {
        if(!particle) particle = GetComponentInChildren<ParticleSystem>(true);
    }

    private void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.CompareTag("cone"))
        {
            particle.Play();
            GameDirector.DecreaseHp(0.25f);
        }
    }
}

GameDirector可能是相同的,您应该有一个字段

[SerilaizeField] private GameDirector gameDirector;

并且可以通过Inspector引用它,或者(仅作为后备通过运行时通过]获取它

private void Awake()
{
    if(!gameDirector) gameDirector = FindObjectOfType<GameDirector>();
}

这里FindObjectOfType似乎是“正常”,因为GameDirector听起来像是场景中恰好存在的[[once

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