【Unity】unity 粒子触发器

项目中有时候会用到粒子碰撞或者触发,比如水枪打到哪里 需要打到的时候有方法回调


水枪粒子的设置


这里要注意的是Collision 和 Triggers


在水枪粒子身上有一个脚本

ParticleXFBase

#region Gavin

using System.Collections.Generic;
using UnityEngine;

#endregion
/// <summary>
/// 消防粒子
/// </summary>
public class ParticleXFBase : MonoBehaviour
{
    protected ParticleSystem PS;
    private GameObject Foam;
    private bool _isOpened;         //水阀是否打开

    public Vector3 StartPoint;
    //    public Vector3 Destination;
    public float ShotSpeed;
    public float LifeTime;


    public GameObject XFTarget { get; set; }
    public string FireGunPoint { get; set; }
    public double PointValue { get; set; }

    private int _triggerThreshold = 30;

    private float _ffTimer;                         //消防计时器     
    protected float Interval = 1.0f;                //两次喷上的间隔时间(默认)
    protected bool IsSendPoint = false;                     //消防炮评分是否发送过

    List<ParticleSystem.Particle> enter = new List<ParticleSystem.Particle>();
    List<ParticleSystem.Particle> exit = new List<ParticleSystem.Particle>();
    List<ParticleSystem.Particle> inside = new List<ParticleSystem.Particle>();
    List<ParticleSystem.Particle> outside = new List<ParticleSystem.Particle>();

    public int TriggerThreshold
    {
        get { return _triggerThreshold; }
        set { _triggerThreshold = value; }
    }

    public void ToggleWater(bool isOpen)
    {
        IsSendPoint = false;
        gameObject.SetActive(isOpen);
    }

    public virtual void Init()
    {
        transform.localPosition = Vector3.zero;
        transform.localEulerAngles = Vector3.zero;
        //****************核心代码
        PS = GetComponent<ParticleSystem>();
        if (XFTarget != null)
            PS.trigger.SetCollider(0, XFTarget.GetComponentInChildren<Collider>(true));
        //*******************
        var mainModule = PS.main;
        {
            mainModule.startSpeed = ShotSpeed;
            mainModule.startLifetime = LifeTime;
        }

    }

    //    protected virtual void OnParticleCollision(GameObject other)//检测到粒子碰撞
    //    {
    //        if (_isOpened == false) return;
    //
    //        if (other.CompareTag(XFTarget))//消防炮粒子需要增加XFP的Tag
    //        {        
    //            if (IsSendPoint) return;
    //            Debug.LogFormat("{0}___粒子来袭..", XFTarget);
    //            _ffTimer += Time.deltaTime;
    //            if (_ffTimer >= Interval)//连续检测到火粒子的碰撞时间差小于fDeltaTime
    //            {
    //                _ffTimer -= Interval;
    //                DataCommModule.Instance.SetPointValue(FireGunPoint, PointValue, RoleManager.Instance.currentRoleID, 1);
    //                Debug.LogFormat("{0}________发送了点值..", XFTarget);
    //                IsSendPoint = true;
    //            }
    //        }
    //    }
    private int debugCount = 0;
    protected virtual void OnParticleTrigger()
    {
        int enterNum = PS.GetTriggerParticles(ParticleSystemTriggerEventType.Enter, enter);
        int exitNum = PS.GetTriggerParticles(ParticleSystemTriggerEventType.Exit, exit);
        int insideNum = PS.GetTriggerParticles(ParticleSystemTriggerEventType.Inside, inside);
        int outsideNum = PS.GetTriggerParticles(ParticleSystemTriggerEventType.Outside, outside);

        if (enterNum > 0)
            OnEnterCollider(enter);
        if (exitNum > 0)
            OnExitCollider(exit);
        if (insideNum > 0)
            OnInSideCollider(inside);
        if (outsideNum > 0)
            OnOutSideCollider(outside);
#if UNITY_EDITOR

        //        if (debugCount <= 1)
        //        {
        //            Debug.Log("insideNum" + insideNum + " inside.Count" + inside.Count);
        //            Debug.Log("enterNum" + enterNum + " enter.Count" + enter.Count);
        //            Debug.Log("exitNum" + exitNum + " exit.Count" + exit.Count);
        //            Debug.Log("outsideNum" + outsideNum + " outside.Count" + outside.Count);
        //            debugCount++;
        //        } 
#endif
        PS.SetTriggerParticles(ParticleSystemTriggerEventType.Enter, enter);
        PS.SetTriggerParticles(ParticleSystemTriggerEventType.Exit, exit);
        PS.SetTriggerParticles(ParticleSystemTriggerEventType.Inside, inside);
        PS.SetTriggerParticles(ParticleSystemTriggerEventType.Outside, outside);
    }

    private void FixedAction()
    {
        if (IsSendPoint) return;

        _ffTimer += Time.deltaTime;

        if (_ffTimer >= Interval)
        {
            _ffTimer -= Interval;
            int id = RoleManager.Instance.currentRoleID;
            DataCommModule.Instance.SetPointValue(FireGunPoint, PointValue, id, 1);

            IsSendPoint = true;
            Debug.LogFormat("________发送了点..{0}值{1}", FireGunPoint, PointValue);
        }
    }
    public virtual void OnEnterCollider(List<ParticleSystem.Particle> enters) { }
    public virtual void OnExitCollider(List<ParticleSystem.Particle> exits) { }
    public virtual void OnInSideCollider(List<ParticleSystem.Particle> insides)
    {
        Debug.Log("Cc");
        if (insides.Count > _triggerThreshold)
        {
            FixedAction();
        }
    }
    public virtual void OnOutSideCollider(List<ParticleSystem.Particle> outsides) { }



}
光靠单纯的碰撞是不行 在代码中需要指定

  PS = GetComponent<ParticleSystem>();
        if (XFTarget != null)
            PS.trigger.SetCollider(0, XFTarget.GetComponentInChildren<Collider>(true));
这里的XFTarget 就是下图中的 Cube 碰撞器



这样的话粒子如果打到就会进入回调  

 public virtual void OnInSideCollider(List<ParticleSystem.Particle> insides)


  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Unity_阿黄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值