using UnityEngine; public class FlipbookAnimationStarter : MonoBehaviour { [Header("设置")] [Tooltip("是否在OnEnable时自动设置StartTime")] public bool autoSetOnEnable = true; [Tooltip("使用 MaterialPropertyBlock(推荐,支持GPU Instancing)还是Material实例")] public bool usePropertyBlock = true; [Tooltip("是否也处理子对象的Renderer")] public bool includeChildren = false; private static readonly int StartTimePropertyID = Shader.PropertyToID("_StartTime"); private MaterialPropertyBlock _propertyBlock; private Renderer[] _renderers; private void Awake() { if (usePropertyBlock) { _propertyBlock = new MaterialPropertyBlock(); } if (includeChildren) { _renderers = GetComponentsInChildren(true); } else { var renderer = GetComponent(); _renderers = renderer != null ? new[] { renderer } : new Renderer[0]; } } private void OnEnable() { if (autoSetOnEnable) { SetStartTime(); } } public void SetStartTime() { SetStartTime(Time.time); } public void SetStartTime(float startTime) { foreach (var renderer in _renderers) { if (renderer == null) continue; if (usePropertyBlock) { renderer.GetPropertyBlock(_propertyBlock); _propertyBlock.SetFloat(StartTimePropertyID, startTime); renderer.SetPropertyBlock(_propertyBlock); } else { renderer.material.SetFloat(StartTimePropertyID, startTime); } } } public void ResetAnimation() { SetStartTime(0f); } public void RestartAnimation() { SetStartTime(Time.time); } #if UNITY_EDITOR [ContextMenu("设置StartTime为当前时间")] private void EditorSetStartTime() { if (Application.isPlaying) { SetStartTime(); Debug.Log($"已设置 {gameObject.name} 的StartTime为 {Time.time}"); } else { Debug.LogWarning("请在运行时执行此操作"); } } [ContextMenu("重置StartTime为0")] private void EditorResetStartTime() { if (Application.isPlaying) { ResetAnimation(); Debug.Log($"已重置 {gameObject.name} 的StartTime为0"); } else { Debug.LogWarning("请在运行时执行此操作"); } } #endif }