其他分享
首页 > 其他分享> > Unity2019-粒子系统的碰撞测试

Unity2019-粒子系统的碰撞测试

作者:互联网

使用unity2019.4.24f1的粒子系统

组件简介

碰撞和触发是单独的
碰撞时可以进行反弹操作,设置粒子的速度
触发时分4种状态,目标碰撞盒内外,进入退出,有三种操作可选

实例代码

实例代码,注意:脚本需要挂载到粒子节点上生效
触发器的回调在其他位置不起作用。

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

public class SuperParticle : MonoBehaviour
{
	/// <summary>
	/// 粒子系统对象-本节点-方法只有挂载到自身节点才会起作用
	/// </summary>
	private ParticleSystem ps;

	[Header("使用碰撞器")]
	public bool useCollider = false;
	[Header("使用触发器")]
	public bool useTrigger = false;

	void OnEnable()
    {
		ps = GetComponent<ParticleSystem>();

		var coll = ps.collision;
		coll.enabled = useCollider;

		if (useCollider)
		{
			coll.type = ParticleSystemCollisionType.World;
			coll.sendCollisionMessages = useCollider;

			// 无法修改 ParticleSystem.collision 的返回值 因为它不是变量
			//pt.collision.type = ParticleSystemCollisionType.World;//触发1612错误
		}

		var tri = ps.trigger;
		tri.enabled = useTrigger;

		if (useTrigger)
		{
			
		}
	}

	/// <summary>
	/// 碰撞信息-用于包含匹配每帧触发碰撞条件的粒子。
	/// </summary>
	private List<ParticleCollisionEvent> collisionEvents = new List<ParticleCollisionEvent>();

	/// <summary>
	/// 粒子的碰撞方法 反弹
	/// </summary>
	/// <param name="other"></param>
	private void OnParticleCollision(GameObject other)
	{
		if (!useCollider) return;
		if (other.name == "ParticleCollider")
		{
			int numCollisionEvents = ps.GetCollisionEvents(other, collisionEvents);

			Rigidbody rb = other.GetComponent<Rigidbody>();
			int i = 0;

			while (i < numCollisionEvents)
			{
				if (rb)
				{
					Vector3 pos = collisionEvents[i].intersection;
					Vector3 force = collisionEvents[i].velocity * 10;
					rb.AddForce(force);
				}
				i++;
			}
		}
	}

	/// <summary>
	/// 触发信息列表-用于包含匹配每帧触发进入条件的粒子。
	/// </summary>
	List<ParticleSystem.Particle> enter = new List<ParticleSystem.Particle>();
	/// <summary>
	/// 触发信息列表-用于包含匹配每帧触发退出条件的粒子。 
	/// </summary>
	List<ParticleSystem.Particle> exit = new List<ParticleSystem.Particle>();

	/// <summary>
	/// 粒子的触发器的方法 可以变更颜色
	/// </summary>
	void OnParticleTrigger()
	{
		if (!useTrigger) return;
		// get the particles which matched the trigger conditions this frame
		int numEnter = ps.GetTriggerParticles(ParticleSystemTriggerEventType.Enter, enter);
		int numExit = ps.GetTriggerParticles(ParticleSystemTriggerEventType.Exit, exit);

		// iterate through the particles which entered the trigger and make them red
		for (int i = 0; i < numEnter; i++)
		{
			ParticleSystem.Particle p = enter[i];
			p.startColor = new Color(255, 0, 0, 255);
			enter[i] = p;
		}

		// iterate through the particles which exited the trigger and make them green
		for (int i = 0; i < numExit; i++)
		{
			ParticleSystem.Particle p = exit[i];
			p.startColor = new Color(0, 255, 0, 255);
			exit[i] = p;
		}

		// re-assign the modified particles back into the particle system
		ps.SetTriggerParticles(ParticleSystemTriggerEventType.Enter, enter);
		ps.SetTriggerParticles(ParticleSystemTriggerEventType.Exit, exit);
	}
}

关于1612错误:

// 摘要:
// Script interface for the CollisionModule of a Particle System.
   public CollisionModule collision { get; }
// 摘要:
// Script interface for the CollisionMmodule of a Particle System.
   public struct CollisionModule{
	//---------------------------略
	}

collider是CollisionModule类型的结构体 并且设置了get属性 获取时会直接return


微软官方对于此错误的具体描述和解决方案

尝试修改作为中间表达式结果产生但未存储在变量中的值类型。当您试图直接修改泛型集合中的结构时,可能会发生此错误

List<myStruct> list = {…};  
list[0].Name = "MyStruct42"; //CS1612  

若要修改结构,首先将其分配给局部变量,然后修改变量,然后将变量分配回集合中的项。

List<myStruct> list = {…};  
MyStruct ms = list[0];  
ms.Name = "MyStruct42";  
list[0] = ms;  

发生此错误是因为在赋值时复制值类型。当从属性或索引器检索值类型时,将得到对象的副本,而不是对象本身的引用。属性或索引器不会存储返回的副本,因为它们实际上是方法,而不是存储位置(变量)。在修改副本之前,必须将副本存储到声明的变量中。

引用类型不会出现错误,因为在这种情况下,属性或索引器返回对现有对象(即存储位置)的引用。

如果要定义类或结构,则可以通过修改属性声明以提供对结构成员的访问权限来解决此错误。如果您正在编写客户端代码,则可以通过创建您自己的struct实例、修改其字段,然后将整个struct重新分配给属性来解决错误。作为第三种选择,您可以将结构更改为类。

// CS1612.cs  
using System;  
  
public struct MyStruct  
{  
    public int Width;  
}  
  
public class ListView  
{  
    MyStruct ms;  
    public MyStruct Size  
    {  
        get { return ms; }  
        set { ms = value; }  
    }  
}  
  
public class MyClass  
{  
    public MyClass()  
    {  
        ListView lvi;  
        lvi = new ListView();  
        lvi.Size.Width = 5; // CS1612  
  
        // You can use the following lines instead.  
        // 你可以使用以下代码替代
        // MyStruct ms;  
        // ms.Width = 5;  
        // lvi.Size = ms;
    }  
  
    public static void Main()
    {  
        MyClass mc = new MyClass();  
        // Keep the console open in debug mode.  
        Console.WriteLine("Press any key to exit.");  
        Console.ReadKey();
    }  
}  

demo和示例视频下载

下载链接

视频演示

标签:粒子系统,ps,int,List,碰撞,ms,new,Unity2019,public
来源: https://blog.csdn.net/weixin_38531633/article/details/116861287