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.
This commit is contained in:
194
Assets/Game/Test/Scripts/AntManScaleController.cs
Normal file
194
Assets/Game/Test/Scripts/AntManScaleController.cs
Normal file
@@ -0,0 +1,194 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
public class AntManScaleController : MonoBehaviour
|
||||
{
|
||||
private enum ScaleMode
|
||||
{
|
||||
Absolute,
|
||||
RelativeToInitial
|
||||
}
|
||||
|
||||
[Header("Input")]
|
||||
[SerializeField] private bool readToggleInput = true;
|
||||
[SerializeField] private KeyCode toggleKey = KeyCode.Space;
|
||||
|
||||
[Header("Objetivo de Escala")]
|
||||
[SerializeField] private Transform scaleTarget;
|
||||
[SerializeField] private bool keepPivotWorldPosition = true;
|
||||
[SerializeField] private Transform pivotReference;
|
||||
|
||||
[Header("Escalas")]
|
||||
[SerializeField] private ScaleMode scaleMode = ScaleMode.RelativeToInitial;
|
||||
[SerializeField] private Vector3 smallScale = Vector3.one;
|
||||
[SerializeField] private Vector3 largeScale = new Vector3(20f, 20f, 20f);
|
||||
[SerializeField] [Min(0.001f)] private float smallScaleMultiplier = 0.2f;
|
||||
[SerializeField] [Min(0.001f)] private float largeScaleMultiplier = 1f;
|
||||
[SerializeField] private bool startLarge;
|
||||
|
||||
[Header("Transicion")]
|
||||
[SerializeField] [Min(0.01f)] private float transitionDuration = 0.45f;
|
||||
[SerializeField] private AnimationCurve transitionCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
|
||||
|
||||
[Header("Debug")]
|
||||
[SerializeField] private bool showStateLogs;
|
||||
|
||||
public event Action<Vector3, Vector3> TransitionStarted;
|
||||
public event Action<Vector3> TransitionCompleted;
|
||||
|
||||
public bool IsTransitioning => _transitionRoutine != null;
|
||||
public bool IsLarge => _isLarge;
|
||||
public Transform ScaleTarget => scaleTarget;
|
||||
|
||||
private bool _isLarge;
|
||||
private bool _hasQueuedToggle;
|
||||
private Coroutine _transitionRoutine;
|
||||
private Vector3 _initialScale;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (scaleTarget == null)
|
||||
{
|
||||
scaleTarget = transform;
|
||||
}
|
||||
|
||||
if (pivotReference == null)
|
||||
{
|
||||
pivotReference = scaleTarget;
|
||||
}
|
||||
|
||||
_initialScale = scaleTarget.localScale;
|
||||
|
||||
_isLarge = startLarge;
|
||||
ApplyScale(_isLarge ? GetLargeScale() : GetSmallScale());
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!readToggleInput)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Input.GetKeyDown(toggleKey))
|
||||
{
|
||||
RequestToggle();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetReadToggleInputState(bool state)
|
||||
{
|
||||
readToggleInput = state;
|
||||
}
|
||||
|
||||
public Vector3 GetCurrentScale()
|
||||
{
|
||||
if (scaleTarget == null)
|
||||
{
|
||||
return transform.localScale;
|
||||
}
|
||||
|
||||
return scaleTarget.localScale;
|
||||
}
|
||||
|
||||
public void RequestToggle()
|
||||
{
|
||||
if (IsTransitioning)
|
||||
{
|
||||
_hasQueuedToggle = !_hasQueuedToggle;
|
||||
if (showStateLogs)
|
||||
{
|
||||
Debug.Log($"[AntManScaleController] Toggle en cola: {_hasQueuedToggle}", this);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
StartScaleTransition();
|
||||
}
|
||||
|
||||
private void StartScaleTransition()
|
||||
{
|
||||
Vector3 from = scaleTarget.localScale;
|
||||
_isLarge = !_isLarge;
|
||||
Vector3 to = _isLarge ? GetLargeScale() : GetSmallScale();
|
||||
|
||||
_transitionRoutine = StartCoroutine(TransitionRoutine(from, to));
|
||||
}
|
||||
|
||||
private IEnumerator TransitionRoutine(Vector3 from, Vector3 to)
|
||||
{
|
||||
if (showStateLogs)
|
||||
{
|
||||
Debug.Log($"[AntManScaleController] Transicion {from} -> {to}", this);
|
||||
}
|
||||
|
||||
TransitionStarted?.Invoke(from, to);
|
||||
|
||||
float elapsed = 0f;
|
||||
while (elapsed < transitionDuration)
|
||||
{
|
||||
elapsed += Time.deltaTime;
|
||||
float t = Mathf.Clamp01(elapsed / transitionDuration);
|
||||
float eased = transitionCurve.Evaluate(t);
|
||||
ApplyScale(Vector3.LerpUnclamped(from, to, eased));
|
||||
yield return null;
|
||||
}
|
||||
|
||||
ApplyScale(to);
|
||||
TransitionCompleted?.Invoke(to);
|
||||
|
||||
if (showStateLogs)
|
||||
{
|
||||
Debug.Log($"[AntManScaleController] Escala final: {to}", this);
|
||||
}
|
||||
|
||||
_transitionRoutine = null;
|
||||
|
||||
if (_hasQueuedToggle)
|
||||
{
|
||||
_hasQueuedToggle = false;
|
||||
StartScaleTransition();
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyScale(Vector3 newScale)
|
||||
{
|
||||
if (scaleTarget == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!keepPivotWorldPosition || pivotReference == null)
|
||||
{
|
||||
scaleTarget.localScale = newScale;
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 pivotPositionBefore = pivotReference.position;
|
||||
scaleTarget.localScale = newScale;
|
||||
Vector3 pivotPositionAfter = pivotReference.position;
|
||||
Vector3 delta = pivotPositionBefore - pivotPositionAfter;
|
||||
scaleTarget.position += delta;
|
||||
}
|
||||
|
||||
private Vector3 GetSmallScale()
|
||||
{
|
||||
if (scaleMode == ScaleMode.RelativeToInitial)
|
||||
{
|
||||
return _initialScale * smallScaleMultiplier;
|
||||
}
|
||||
|
||||
return smallScale;
|
||||
}
|
||||
|
||||
private Vector3 GetLargeScale()
|
||||
{
|
||||
if (scaleMode == ScaleMode.RelativeToInitial)
|
||||
{
|
||||
return _initialScale * largeScaleMultiplier;
|
||||
}
|
||||
|
||||
return largeScale;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user