using UnityEngine; /// 混沌裂缝传送门:主层(静态椭圆框)+ 内层(原地波动),支持白/红/蓝三色切换。 [ExecuteAlways] public class RiftPortalVisual : MonoBehaviour { [Header("裂缝渲染层(主层 + 内层)")] [SerializeField] private Renderer[] riftRenderers; [SerializeField] private Transform innerLayer; [Header("颜色状态(配色与水晶矿一致)")] [SerializeField] private Color currentColor = Color.white; [SerializeField] private Color neutralColor = Color.white; [SerializeField] private Color blueColor = new Color(0.1f, 0.65f, 1f, 1f); [SerializeField] private Color redColor = new Color(1f, 0.12f, 0.08f, 1f); [Header("原地波动动画(仅运行时,无位移无旋转)")] [SerializeField, Min(0f)] private float pulseSpeed = 2.2f; [Tooltip("内层整体缩放的呼吸幅度")] [SerializeField, Range(0f, 0.2f)] private float pulseAmplitude = 0.04f; [Tooltip("亮度明暗波动幅度 0~1")] [SerializeField, Range(0f, 1f)] private float glowPulseAmount = 0.25f; private MaterialPropertyBlock propertyBlock; private Vector3 innerBaseScale; private bool baseScaleCached; public Color CurrentColor => currentColor; private void OnEnable() => ApplyColor(); private void OnValidate() => ApplyColor(); private void Reset() => CollectRenderers(); public void SetRiftColor(Color color) { currentColor = color; ApplyColor(); } /// teamId: 0=蓝, 1=红, 其他=白(中立),与水晶矿争夺语义一致。 public void SetTeam(int teamId) { SetRiftColor(teamId == 0 ? blueColor : teamId == 1 ? redColor : neutralColor); } private void ApplyColor(float brightness = 1f) { if (riftRenderers == null || riftRenderers.Length == 0) { CollectRenderers(); } if (riftRenderers == null) return; propertyBlock ??= new MaterialPropertyBlock(); Color tint = new Color( currentColor.r * brightness, currentColor.g * brightness, currentColor.b * brightness, currentColor.a); foreach (Renderer renderer in riftRenderers) { if (renderer == null) continue; renderer.GetPropertyBlock(propertyBlock); // Legacy Shaders/Particles/Additive 用 _TintColor 作为颜色入口 propertyBlock.SetColor("_TintColor", tint); propertyBlock.SetColor("_Color", tint); renderer.SetPropertyBlock(propertyBlock); } } private void CollectRenderers() { riftRenderers = GetComponentsInChildren(true); } private void Update() { if (!Application.isPlaying) return; float t = Time.time; float wave = Mathf.Sin(t * pulseSpeed); // 内层整体缩放的轻微呼吸(围绕自身中心,原地) if (innerLayer != null) { if (!baseScaleCached) { innerBaseScale = innerLayer.localScale; baseScaleCached = true; } float pulse = 1f + wave * pulseAmplitude; innerLayer.localScale = new Vector3( innerBaseScale.x * pulse, innerBaseScale.y * pulse, innerBaseScale.z); } // 亮度明暗波动(原地能量涌动) float brightness = 1f - glowPulseAmount * (0.5f - 0.5f * wave); ApplyColor(brightness); } }