项目中有时候会用到粒子碰撞或者触发,比如水枪打到哪里 需要打到的时候有方法回调
水枪粒子的设置
这里要注意的是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)