using Cysharp.Threading.Tasks; using PrimeTween; using UnityEngine; using UnityEngine.UIElements; namespace DanieleMarotta.RiversongCodeShowcase { public class BuildMenuButtonUIView : UIView { private static readonly Color UnlockGlowColor = new(0, 1, 0.7f); private VisualElement _icon; private Material _iconMaterial; public override UniTask InitializeAsync(UIService uiService, VisualElement rootElement) { base.InitializeAsync(uiService, rootElement); _icon = RootElement.Q(className: "build-menu__button-icon"); return UniTask.CompletedTask; } public async UniTask PlayRevealAnimationAsync() { await Tween.Custom(0, 1, 1, value => RootElement.SetScale(value), Ease.OutBounce, useUnscaledTime: true); } public async UniTask PlayUnlockAnimationAsync() { CacheIconMaterial(); _ = PlayUnlockVfxAsync(); await Sequence.Create(useUnscaledTime: true) .Group( Tween.Custom( _iconMaterial.GetColor(ShaderProperties.Color), UnlockGlowColor, 1.2f, value => _iconMaterial.SetColor(ShaderProperties.Color, value), Ease.OutQuad)) .Chain(Tween.Custom(1, 0, 0.8f, value => _iconMaterial.SetFloat(ShaderProperties.Amount, value))); } private async UniTask PlayUnlockVfxAsync() { var vfx = new VisualElement(); RootElement.panel.visualTree.Q(className: "vfx-layer").Add(vfx); vfx.AddToClassList("vfx__build-menu-button-unlock"); vfx.pickingMode = PickingMode.Ignore; var position = RootElement.Q().worldBound.center; vfx.style.left = position.x; vfx.style.top = position.y; vfx.SetScale(0); await UniTask.NextFrame(); var material = vfx.resolvedStyle.unityMaterial.material; material.SetColor(ShaderProperties.Color, UnlockGlowColor); await Sequence.Create(useUnscaledTime: true) .Group(Tween.Custom(0.25f, 1, 1, value => vfx.SetScale(value), Ease.OutQuad)) .Group(Tween.Custom(0, 1, 0.25f, value => vfx.style.opacity = value, Ease.OutQuad)) .Group(Tween.Custom(1, 0, 0.25f, value => vfx.style.opacity = value, startDelay: 0.75f)); vfx.RemoveFromHierarchy(); } private Material CacheIconMaterial() { if (_iconMaterial) return _iconMaterial; var sourceMaterial = _icon.resolvedStyle.unityMaterial.material; if (!sourceMaterial) { Debug.LogError($"Icon material in {nameof(BuildMenuButtonUIView)} is null"); return null; } _iconMaterial = new Material(sourceMaterial); _icon.style.unityMaterial = _iconMaterial; return _iconMaterial; } } }