using System; using Lean.Pool; using Sirenix.OdinInspector; using UnityEngine; using UnityEngine.Serialization; namespace Cielonos.MainGame { public class TransformAdjustment : MonoBehaviour, IPoolable { [Required] public VFXObject vfxObject; [Required] public Transform targetTransform; [Tooltip("在特效生成时是否立刻启用渐变,注意,必须通过对象池生成。\n为true时,渐变效果从默认transform开始,否则需要调用EnableFade方法启用渐变")] public bool playOnSpawn = true; [Tooltip("生命周期")] public float life = 1f; [Tooltip("是否应用本地位置变化")] public bool applyLocalPosition = true; [Tooltip("初始位置")] [ShowIf("applyLocalPosition")] public Vector3 initialLocalPosition; [Tooltip("目标位置")] [ShowIf("applyLocalPosition")] public Vector3 targetLocalPosition = Vector3.zero; [Tooltip("X位置曲线")] [ShowIf("applyLocalPosition")] public AnimationCurve positionCurveX; [Tooltip("Y位置曲线")] [ShowIf("applyLocalPosition")] public AnimationCurve positionCurveY; [Tooltip("Z位置曲线")] [ShowIf("applyLocalPosition")] public AnimationCurve positionCurveZ; [Tooltip("是否应用本地旋转变化")] public bool applyLocalRotation = false; [Tooltip("初始旋转")][ShowIf("applyLocalRotation")]public Vector3 initialEulerAngles; [Tooltip("初始旋转")][ShowIf("applyLocalRotation")] public Vector3 targetEulerAngles = Vector3.zero; [Tooltip("X旋转曲线")][ShowIf("applyLocalRotation")] public AnimationCurve rotationCurveX; [Tooltip("Y旋转曲线")][ShowIf("applyLocalRotation")] public AnimationCurve rotationCurveY; [Tooltip("Z旋转曲线")][ShowIf("applyLocalRotation")] public AnimationCurve rotationCurveZ; [Tooltip("是否应用本地缩放变化")] public bool applyLocalScale = false; [Tooltip("初始缩放")][ShowIf("applyLocalScale")] public Vector3 initialLocalScale; [Tooltip("目标缩放")][ShowIf("applyLocalScale")] public Vector3 targetLocalScale = Vector3.one; [Tooltip("X缩放曲线")][ShowIf("applyLocalScale")] public AnimationCurve scaleCurveX; [Tooltip("Y缩放曲线")][ShowIf("applyLocalScale")] public AnimationCurve scaleCurveY; [Tooltip("Z缩放曲线")][ShowIf("applyLocalScale")] public AnimationCurve scaleCurveZ; [HideInEditorMode] [SerializeField] private bool isFading; [HideInEditorMode] [SerializeField] private float time; private void Reset() { targetTransform = transform; positionCurveX = AnimationCurve.EaseInOut(0, 0, 1, 1); positionCurveY = AnimationCurve.EaseInOut(0, 0, 1, 1); positionCurveZ = AnimationCurve.EaseInOut(0, 0, 1, 1); rotationCurveX = AnimationCurve.EaseInOut(0, 0, 1, 1); rotationCurveY = AnimationCurve.EaseInOut(0, 0, 1, 1); rotationCurveZ = AnimationCurve.EaseInOut(0, 0, 1, 1); scaleCurveX = AnimationCurve.EaseInOut(0, 0, 1, 1); scaleCurveY = AnimationCurve.EaseInOut(0, 0, 1, 1); scaleCurveZ = AnimationCurve.EaseInOut(0, 0, 1, 1); } public void OnSpawn() { if (playOnSpawn && !isFading) { Enable(targetLocalPosition, targetEulerAngles, targetLocalScale); } } public void OnDespawn() { isFading = false; } public void Enable(Vector3 position, Vector3 eulerAngles, Vector3 scale) { if (targetTransform == null) throw new NullReferenceException("Target Transform is null"); time = 0; isFading = true; if (applyLocalPosition) { this.targetLocalPosition = position; targetTransform.localPosition = initialLocalPosition; } if (applyLocalRotation) { this.targetEulerAngles = eulerAngles; targetTransform.localEulerAngles = initialEulerAngles; } if (applyLocalScale) { this.targetLocalScale = scale; targetTransform.localScale = initialLocalScale; } } void Update() { if (!isFading) return; time += vfxObject?.DeltaTime ?? Time.deltaTime; if (applyLocalPosition) { targetTransform.localPosition = initialLocalPosition + new Vector3( (targetLocalPosition.x - initialLocalPosition.x) * positionCurveX.Evaluate(time / life), (targetLocalPosition.y - initialLocalPosition.y) * positionCurveY.Evaluate(time / life), (targetLocalPosition.z - initialLocalPosition.z) * positionCurveZ.Evaluate(time / life) ); } if (applyLocalRotation) { targetTransform.localEulerAngles = initialEulerAngles + new Vector3( (targetEulerAngles.x - initialEulerAngles.x) * rotationCurveX.Evaluate(time / life), (targetEulerAngles.y - initialEulerAngles.y) * rotationCurveY.Evaluate(time / life), (targetEulerAngles.z - initialEulerAngles.z) * rotationCurveZ.Evaluate(time / life) ); } if (applyLocalScale) { targetTransform.localScale = initialLocalScale + new Vector3( (targetLocalScale.x - initialLocalScale.x) * scaleCurveX.Evaluate(time / life), (targetLocalScale.y - initialLocalScale.y) * scaleCurveY.Evaluate(time / life), (targetLocalScale.z - initialLocalScale.z) * scaleCurveZ.Evaluate(time / life) ); } if (time > life) { time = 0; isFading = false; } } } }