在OnParticleCollision中区分不同的碰撞器

时间:2018-09-24 04:53:39

标签: c# unity3d

我目前有一个技工,不断喷水。 如果水碰到玩家,他们会受到伤害。如果水打到雨伞,他不会。

由于不知道如何使用OnParticleCollision区分不同的父/子对撞机,因此无法集成此机制

using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;

public class Health : MonoBehaviour {

public float startingHealth = 100f;
public float health;



public Slider healthSlider;

// Use this for initialization
void Start () {
    health = startingHealth;
}

void OnParticleCollision(GameObject offender)
{
    if (offender.gameObject.name == "hoseSystem") //collided with BoxCollider. 
    {
        health -= 0.5f;
        healthSlider.value = health;
    }
}
// Update is called once per frame
void Update () {
}
}

1 个答案:

答案 0 :(得分:2)

首先,让我们澄清一些事情,以使我们对Unity中一般工作中的碰撞方式有所了解。

碰撞

  • 实体需要一个刚体才能使碰撞起作用。
  • 当父对象或其任何子对象被对象击中时,会发生
  • 碰撞事件。在这种情况下,它们被视为单个实体。
  • 碰撞事件在两侧都触发。。即水软管颗粒也将发生碰撞事件。

粒子系统

  • 粒子系统主要用于视觉效果,因为它们非常注重性能。
  • 粒子系统的OnParticleCollision不能提供与RigidBody.OnCollisionEnter几乎相同级别的功能。这是在Unity中设计的。
  • 通常建议不要将粒子用于您想要实现的互动。

现在回答您的问题,尽管这实际上不是最佳选择,但一种解决方法是检查粒子系统的碰撞,并通过滥用{{1 }}不会浏览被击中物体的孩子和/或父母。

逻辑如下:

  1. 粒子与对象碰撞。

  2. 粒子获取对象的“健康”成分。

  3. 粒子在上述组件上称为“损坏”。

实际上,这将转换为:

GetComponent

public class WaterHose : MonoBehaviour {

private void OnParticleCollision(GameObject other)
{
    //Get the component specifically in the gameobject we hit
    //This by default ignores parents/children.
    Health health = other.GetComponent<Health>();
    if (health != null)
        health.Damage(5);
}
}

public class Health : MonoBehaviour { public float health; void Start () { health = 150f; } public void Damage(float amount) { health -= amount; } } 进入玩家,Health进入水枪。

请记住,这仍然是非常错误的设计。

我建议改为按设置的间隔使用WaterHose,就像在Unity中发射无弹枪一样,并且仅将粒子用于效果。

更新: 根据OP的要求,您可以在伞中添加RayCasts,并确保将RigidBody字段设置为isKinematic。 默认情况下,这将启用与truePlayerUmbrella不同的碰撞检测,以知道它撞到了哪个物体。

以下代码段对此进行了演示:

WaterHose

值得注意的是,这仍然是非常糟糕的设计,我强烈建议改用public class WaterHose : MonoBehaviour { private void OnParticleCollision(GameObject other) { Collider col = other.GetComponent<Collider>(); if (col is CapsuleCollider) Debug.Log("We hit the player!"); else if (col is BoxCollider) Debug.Log("We hit the umbrella!"); } }