Files
FueraDeEscala/Assets/Game/Test/Scripts/GhostTrailGhost.cs
Robii Aragon d5241c3bf7 Add AntMan scaling, ghost trail and test prefab
Introduce a set of test tools and demo assets for an AntMan-style scaling effect:

- Add AntManScaleController: handles smooth scale transitions (absolute/relative modes), pivot preservation, queued toggles and events.
- Add GhostTrailEmitter and GhostTrailGhost: spawn fading ghost meshes (supports skinned mesh baking, material fallback, lifetime and pooling limit).
- Add GKTInventoryScaleToggle: inventory-gated input wrapper to toggle scale with optional Ctrl bypass and auto reference resolution.
- Add AntManTestSceneBootstrap and TestBootstrap prefab to quickly construct a test scene (cube, light, camera) with components configured.
- Add AntManScaleTest scene and related prefab/meta files, plus .vsconfig for Unity workload.
- Update SampleScene LFS pointer (scene file checksum/size).

These changes provide a reusable demo and components to test scaling visuals and interactions during development.
2026-03-19 18:53:27 -07:00

130 lines
3.7 KiB
C#

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;
}
}