c# - 如何在 Unity 中为特定的克隆游戏对象播放粒子?
问题描述
我现在正在 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);
}
}
第一个脚本附加到锥形预制件,第二个脚本附加到立方体。但问题是,当一个锥体撞击立方体时,其他锥体会发射粒子,而不是撞击立方体的锥体。我该如何解决这个问题?任何帮助是极大的赞赏!
解决方案
正如我所看到的,您(ab!)对所有事情都使用单例模式,并调用了很多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);
}
}
但似乎你也可以让你的 Player 直接自己处理整个事情。而是将粒子系统附加到它上,然后像这样放在move
播放器(立方体)上
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
听起来像是场景中只存在一次的东西。
推荐阅读
- string - 如何从 vb.net 中的字符串中删除一个非常特殊的部分
- python - 从文件中读取行并在 Python 中的最后一个分隔符处拆分行并将其保存到另一个文件
- javascript - 在数组上循环时键入脚本错误减少
- r - 更改pairs_text 中pairs_text 的字体大小(以R 为底)
- php - 在结果php中显示从表单获得的url到图像
- pytorch - model.load_state_dict 没有给出相同的评估结果
- css - 角度材质样式未正确应用
- python - 如何使用 python-flask 进行高效的“广播到本地主机”?
- python - 我在清理 DataFrame 中的 str 系列时遇到问题
- sql-server - .FromSql 用于空存储过程结果的替代方案