using System.Collections; using BlueWater.Interfaces; using BlueWater.Players; using Sirenix.OdinInspector; using Spine.Unity; using UnityEngine; namespace BlueWater.Enemies.Bosses { public abstract class SpineBoss : Boss, ICurrentDirection { // Variables #region Variables // Components [field: Title("스파인 보스 컴포넌트")] [field: SerializeField] public MeshRenderer MeshRenderer { get; private set; } // Classes [field: SerializeField] public SpineController SpineController { get; private set; } public bool IsMoving { get; private set; } private Vector3 _currentDirection = Vector3.right; public Vector3 CurrentDirection { get => _currentDirection; set { if (value == Vector3.zero) return; _currentDirection = value; } } #endregion // Unity events #region Unity events protected override void Start() { base.Start(); var originalMaterial = SpineController.SkeletonAnimation.SkeletonDataAsset.atlasAssets[0].PrimaryMaterial; var newMaterial = SpineController.SkeletonAnimation.CustomMaterialOverride[originalMaterial]; MaterialInstance = Instantiate(newMaterial); SpineController.SkeletonAnimation.CustomMaterialOverride[originalMaterial] = MaterialInstance; BossHealthPoint.SetMaterialInstance(MaterialInstance); IsInitialized = true; } protected override void Update() { base.Update(); HandleMovement(); FlipVisualLook(); } #endregion // Initialize methods #region Initialize methods [Button("컴포넌트 초기화")] protected override void InitializeComponents() { base.InitializeComponents(); MeshRenderer = VisualLook.GetComponent(); MeshRenderer.enabled = false; SpineController = GetComponent(); // var originalMaterial = VisualLook.GetComponent().SkeletonDataAsset.atlasAssets[0].PrimaryMaterial; // MaterialInstance = Instantiate(MeshRenderer.material); // SpineController.SkeletonAnimation.CustomMaterialOverride[originalMaterial] = MaterialInstance; // print($"originalMaterial : {originalMaterial.name}, custom : {SpineController.SkeletonAnimation.CustomMaterialOverride[originalMaterial]}"); // // BossHealthPoint.SetMaterialInstance(MaterialInstance); } #endregion // Methods #region Methods protected override IEnumerator DissolveCoroutine(float start, float end, float dissolveTime) { if (!IsDissolveActive) { MaterialInstance.SetFloat(_dissolveValueHash, end); yield break; } MaterialInstance.SetFloat(_dissolveValueHash, start); MeshRenderer.enabled = true; var elapsedTime = 0f; while (elapsedTime <= dissolveTime) { var value = Mathf.Lerp(start, end, elapsedTime / dissolveTime); MaterialInstance.SetFloat(_dissolveValueHash, value); elapsedTime += Time.deltaTime; yield return null; } MaterialInstance.SetFloat(_dissolveValueHash, end); } protected virtual void FlipVisualLook() { var localScale = VisualLook.localScale; localScale.x = CurrentDirection.x switch { > 0.01f => -Mathf.Abs(localScale.x), < -0.01f => Mathf.Abs(localScale.x), _ => localScale.x }; VisualLook.localScale = localScale; } protected virtual void HandleMovement() { if (AstarAi == null) return; if (!AstarAi.canMove || AstarAi.isStopped) { IsMoving = false; return; } CurrentDirection = AstarAi.velocity.normalized; IsMoving = AstarAi.velocity != Vector3.zero || AstarAi.velocity != Vector3.positiveInfinity; } #endregion } }