Files
FueraDeEscala/Assets/Game/Test/Scripts/GhostTrailGhost.cs

130 lines
3.7 KiB
C#
Raw Normal View History

using UnityEngine;
using UnityEngine.Rendering;
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
public class GhostTrailGhost : MonoBehaviour
{
private static readonly int BaseColorId = Shader.PropertyToID("_BaseColor");
private static readonly int ColorId = Shader.PropertyToID("_Color");
private MeshRenderer _meshRenderer;
private GhostTrailEmitter _owner;
private Material _runtimeMaterial;
private Mesh _runtimeMesh;
private bool _ownsRuntimeMesh;
private float _lifeElapsed;
private float _lifetime;
private float _startAlpha;
private float _endAlpha;
private Color _baseColor;
private bool _usesBaseColor;
public void Initialize(
Mesh mesh,
Material templateMaterial,
float lifetime,
float startAlpha,
float endAlpha,
GhostTrailEmitter owner,
bool ownsRuntimeMesh = false)
{
_owner = owner;
_lifetime = Mathf.Max(0.01f, lifetime);
_startAlpha = Mathf.Clamp01(startAlpha);
_endAlpha = Mathf.Clamp01(endAlpha);
_runtimeMesh = mesh;
_ownsRuntimeMesh = ownsRuntimeMesh;
MeshFilter meshFilter = GetComponent<MeshFilter>();
_meshRenderer = GetComponent<MeshRenderer>();
meshFilter.sharedMesh = _runtimeMesh;
_runtimeMaterial = new Material(templateMaterial);
ConfigureTransparentMaterial(_runtimeMaterial);
_usesBaseColor = _runtimeMaterial.HasProperty(BaseColorId);
if (_usesBaseColor)
{
_baseColor = _runtimeMaterial.GetColor(BaseColorId);
}
else if (_runtimeMaterial.HasProperty(ColorId))
{
_baseColor = _runtimeMaterial.GetColor(ColorId);
}
else
{
_baseColor = Color.white;
}
_meshRenderer.sharedMaterial = _runtimeMaterial;
ApplyAlpha(_startAlpha);
}
private void Update()
{
_lifeElapsed += Time.deltaTime;
float t = Mathf.Clamp01(_lifeElapsed / _lifetime);
float alpha = Mathf.Lerp(_startAlpha, _endAlpha, t);
ApplyAlpha(alpha);
if (_lifeElapsed >= _lifetime)
{
Destroy(gameObject);
}
}
private void OnDestroy()
{
if (_owner != null)
{
_owner.NotifyGhostDestroyed(this);
}
if (_runtimeMaterial != null)
{
Destroy(_runtimeMaterial);
}
if (_ownsRuntimeMesh && _runtimeMesh != null)
{
Destroy(_runtimeMesh);
}
}
private void ApplyAlpha(float alpha)
{
Color color = _baseColor;
color.a = alpha;
if (_usesBaseColor)
{
_runtimeMaterial.SetColor(BaseColorId, color);
return;
}
if (_runtimeMaterial.HasProperty(ColorId))
{
_runtimeMaterial.SetColor(ColorId, color);
}
}
private static void ConfigureTransparentMaterial(Material material)
{
if (material.HasProperty("_Surface")) material.SetFloat("_Surface", 1f);
if (material.HasProperty("_Blend")) material.SetFloat("_Blend", 0f);
if (material.HasProperty("_AlphaClip")) material.SetFloat("_AlphaClip", 0f);
if (material.HasProperty("_SrcBlend")) material.SetFloat("_SrcBlend", (float)BlendMode.SrcAlpha);
if (material.HasProperty("_DstBlend")) material.SetFloat("_DstBlend", (float)BlendMode.OneMinusSrcAlpha);
if (material.HasProperty("_ZWrite")) material.SetFloat("_ZWrite", 0f);
material.DisableKeyword("_ALPHATEST_ON");
material.EnableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
material.renderQueue = (int)RenderQueue.Transparent;
}
}