using UnityEngine; [ExecuteAlways] public class PortalEnergyVisual : MonoBehaviour { public enum PortalTeamColor { Neutral, Blue, Red } [SerializeField] private PortalTeamColor teamColor = PortalTeamColor.Neutral; [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); [SerializeField, Min(0f)] private float emissionIntensity = 2.2f; [SerializeField, Min(0f)] private float pulseSpeed = 1.6f; [SerializeField, Range(0f, 0.2f)] private float pulseAmount = 0.06f; [SerializeField] private Vector2 scrollSpeed = new Vector2(0f, -0.08f); private Renderer targetRenderer; private MaterialPropertyBlock propertyBlock; private static readonly int BaseColorId = Shader.PropertyToID("_Color"); private static readonly int TintColorId = Shader.PropertyToID("_TintColor"); private static readonly int EmissionColorId = Shader.PropertyToID("_EmissionColor"); private static readonly int MainTexStId = Shader.PropertyToID("_MainTex_ST"); private void OnEnable() { targetRenderer = GetComponent(); propertyBlock ??= new MaterialPropertyBlock(); ApplyVisuals(0f); } private void Update() { ApplyVisuals(Application.isPlaying ? Time.time : Time.realtimeSinceStartup); } private void OnValidate() { targetRenderer = GetComponent(); propertyBlock ??= new MaterialPropertyBlock(); ApplyVisuals(0f); } public void SetTeamColor(PortalTeamColor color) { teamColor = color; ApplyVisuals(0f); } public PortalTeamColor GetTeamColor() => teamColor; private void ApplyVisuals(float time) { if (targetRenderer == null) { return; } Color color = teamColor == PortalTeamColor.Blue ? blueColor : teamColor == PortalTeamColor.Red ? redColor : neutralColor; float pulse = 1f + Mathf.Sin(time * pulseSpeed) * pulseAmount; Color emission = color * (emissionIntensity * pulse); targetRenderer.GetPropertyBlock(propertyBlock); propertyBlock.SetColor(BaseColorId, color); propertyBlock.SetColor(TintColorId, color); propertyBlock.SetColor(EmissionColorId, emission); propertyBlock.SetVector(MainTexStId, new Vector4(1f, 1f, scrollSpeed.x * time, scrollSpeed.y * time)); targetRenderer.SetPropertyBlock(propertyBlock); } }