我现在正在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);
}
}
第一个脚本附加到圆锥形预制件,第二个脚本附加到立方体。但是问题在于,当一个圆锥撞击立方体时,其他圆锥会发出粒子,而不是撞击立方体的圆锥。我该如何解决这个问题?非常感谢您的帮助!
从多维数据集中删除与圆锥相关的逻辑:
private void OnCollisionEnter(碰撞冲突){如果(collision.gameObject.CompareTag(“ cone”)){// move.PlayParticles(); // ------------删除此行GameDirector.DecreaseHp(0.25f);}
}
使检查器中可分配的粒子变量-添加[SerializeField]属性。并在检查器中分配它。
类似这样的东西:
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();
}
}
}
正如我所看到的,您正在(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