2026-06-09 룸 프로토타입 디자인 (진행중)
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace StylizedWater3
|
||||
{
|
||||
/// <summary>
|
||||
/// Emulates the particle system "Rate over Distance" emission behaviour, but with accurate support for RigidBody's
|
||||
/// </summary>
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu("Effects/Particle Trail Emitter")]
|
||||
public class ParticleTrailEmitter : MonoBehaviour
|
||||
{
|
||||
#pragma warning disable 108,114 //New keyword
|
||||
[Tooltip("The Emission module on this particle system should have its Rate Over Distance value set 0.")]
|
||||
public ParticleSystem particleSystem;
|
||||
private ParticleSystem.EmissionModule emissionModule;
|
||||
#pragma warning restore 108,114
|
||||
|
||||
[Tooltip("If this particle system is parented under a RigidBody, then assign it here for correct positional tracking")]
|
||||
public Rigidbody rigidBody;
|
||||
|
||||
[Space]
|
||||
|
||||
public float spawnRatePerUnit = 1f;
|
||||
|
||||
private float distanceAccumulation = 0f;
|
||||
private Vector3 previousPosition;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
particleSystem = GetComponent<ParticleSystem>();
|
||||
|
||||
if (particleSystem)
|
||||
{
|
||||
emissionModule = particleSystem.emission;
|
||||
|
||||
if (emissionModule.rateOverDistance.constant > 0f)
|
||||
{
|
||||
ParticleSystem.MinMaxCurve rateOverDistance = emissionModule.rateOverDistance;
|
||||
rateOverDistance.constant = 0f;
|
||||
emissionModule.rateOverDistance = rateOverDistance;
|
||||
|
||||
Debug.LogWarning($"The Rate Over Distance has been set to 0 on the particle system \"{particleSystem.name}\". This is because the Particle Trail Emitter component will be responsible for emission");
|
||||
}
|
||||
}
|
||||
rigidBody = GetComponentInParent<Rigidbody>();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
previousPosition = this.transform.position;
|
||||
|
||||
if (particleSystem)
|
||||
{
|
||||
ParticleSystem.MainModule main = particleSystem.main;
|
||||
main.playOnAwake = false;
|
||||
}
|
||||
}
|
||||
|
||||
private float GetDistance()
|
||||
{
|
||||
float distanceThisFrame = 0;
|
||||
|
||||
if(rigidBody)
|
||||
{
|
||||
//Distance = speed * deltaTime
|
||||
float movementSpeed = Mathf.Max(rigidBody.linearVelocity.magnitude, rigidBody.angularVelocity.magnitude);
|
||||
distanceThisFrame = movementSpeed * Time.deltaTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
distanceThisFrame = Vector3.Distance(transform.position, previousPosition);
|
||||
previousPosition = this.transform.position;
|
||||
}
|
||||
|
||||
return distanceThisFrame;
|
||||
}
|
||||
|
||||
public void FixedUpdate()
|
||||
{
|
||||
if (!particleSystem || !enabled) return;
|
||||
|
||||
emissionModule = particleSystem.emission;
|
||||
if (emissionModule.enabled == false) return;
|
||||
|
||||
float distance = GetDistance();
|
||||
|
||||
//Teleportation safeguard
|
||||
if (distance > 50f) return;
|
||||
|
||||
distanceAccumulation += distance;
|
||||
|
||||
var particlesToEmit = Mathf.CeilToInt(distanceAccumulation * spawnRatePerUnit);
|
||||
|
||||
if (particlesToEmit > 0)
|
||||
{
|
||||
particleSystem.Emit(particlesToEmit);
|
||||
|
||||
distanceAccumulation -= particlesToEmit / spawnRatePerUnit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[CustomEditor(typeof(ParticleTrailEmitter))]
|
||||
class ParticleTrailEmitterInspector : Editor
|
||||
{
|
||||
private ParticleTrailEmitter component;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
component = (ParticleTrailEmitter)target;
|
||||
}
|
||||
|
||||
private void OnSceneGUI()
|
||||
{
|
||||
component.FixedUpdate();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user