VR模拟枪支打靶,消灭鬼怪,换弹以及上弦等等硬核枪支操作。 使用HTCVive设备,开启SteamVR进行游玩。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

88 lines
3.0 KiB

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class ME_ParticleCollisionDecal : MonoBehaviour
{
public ParticleSystem DecalParticles;
public bool IsBilboard;
public bool InstantiateWhenZeroSpeed;
public float MaxGroundAngleDeviation = 45;
public float MinDistanceBetweenDecals = 0.1f;
public float MinDistanceBetweenSurface = 0.03f;
private List<ParticleCollisionEvent> collisionEvents = new List<ParticleCollisionEvent>();
ParticleSystem.Particle[] particles;
ParticleSystem initiatorPS;
List<GameObject> collidedGameObjects = new List<GameObject>();
void OnEnable()
{
collisionEvents.Clear();
collidedGameObjects.Clear();
initiatorPS = GetComponent<ParticleSystem>();
particles = new ParticleSystem.Particle[DecalParticles.main.maxParticles];
if (InstantiateWhenZeroSpeed) InvokeRepeating("CollisionDetect", 0, 0.1f);
}
void OnDisable()
{
if (InstantiateWhenZeroSpeed) CancelInvoke("CollisionDetect");
}
void CollisionDetect()
{
int aliveParticles = 0;
if (InstantiateWhenZeroSpeed)
aliveParticles = DecalParticles.GetParticles(particles);
foreach (var collidedGameObject in collidedGameObjects)
{
OnParticleCollisionManual(collidedGameObject, aliveParticles);
}
}
private void OnParticleCollisionManual(GameObject other, int aliveParticles = -1)
{
collisionEvents.Clear();
var aliveEvents = initiatorPS.GetCollisionEvents(other, collisionEvents);
for (int i = 0; i < aliveEvents; i++)
{
var angle = Vector3.Angle(collisionEvents[i].normal, Vector3.up);
if (angle > MaxGroundAngleDeviation) continue;
if (InstantiateWhenZeroSpeed)
{
if (collisionEvents[i].velocity.sqrMagnitude > 0.1f) continue;
var isNearDistance = false;
for (int j = 0; j < aliveParticles; j++)
{
var distance = Vector3.Distance(collisionEvents[i].intersection, particles[j].position);
if (distance < MinDistanceBetweenDecals) isNearDistance = true;
}
if (isNearDistance) continue;
}
var emiter = new ParticleSystem.EmitParams();
emiter.position = collisionEvents[i].intersection + collisionEvents[i].normal * MinDistanceBetweenSurface;
var rotation = Quaternion.LookRotation(-collisionEvents[i].normal).eulerAngles;
rotation.z = Random.Range(0, 360);
emiter.rotation3D = rotation;
DecalParticles.Emit(emiter, 1);
}
}
void OnParticleCollision(GameObject other)
{
if (InstantiateWhenZeroSpeed)
{
if (!collidedGameObjects.Contains(other))
collidedGameObjects.Add(other);
}
else
{
OnParticleCollisionManual(other);
}
}
}