using DDD.Interfaces; using DDD.Items; using DDD.ScriptableObjects; using DDD.Tycoons; using DDD.Uis; using Sirenix.OdinInspector; using Spine.Unity; using UnityEngine; using UnityEngine.Serialization; namespace DDD.Players.Tycoons { public static class TycoonPlayerSpineAnimation { public const string Idle = "Idle"; public const string Walking = "RunFast"; public const string ServingIdle = "Serving/ServingIdle"; public const string Serving = "Serving/ServingFast"; public const string Dash = "Dash"; public const string CleaningFloor = "Cleaning/CleaningFloor"; public const string CleaningTable = "Cleaning/CleaningTable"; public const string MakingCocktail = "BeerMaker"; public const string Pumping = "Attack/AttackWhip"; public const string AttackSlime = "Attack/AttackSlime"; public const string AttackLimeTree = "Attack/AttackBat"; public const string CookingFried = "Cooking/CookingFried"; public const string CookingStew = "Cooking/CookingStew"; } [DefaultExecutionOrder(-1)] public class TycoonPlayer : MonoBehaviour { // Variables #region Variables // Components [field: SerializeField] public Rigidbody Rigidbody { get; private set; } [field: SerializeField] public CapsuleCollider CharacterCollider { get; private set; } [field: SerializeField] public Transform VisualLook { get; private set; } [field: SerializeField] public SkeletonAnimation SkeletonAnimation { get; private set; } [field: SerializeField] public InteractionCanvas InteractionCanvas { get; private set; } [field: SerializeField] public SpineController SpineController { get; private set; } [field: SerializeField] public PlayerHealthPoint PlayerHealthPoint { get; private set; } [field: SerializeField] public TycoonInput TycoonInput { get; private set; } [field: SerializeField] public TycoonMovement TycoonMovement { get; private set; } [field: SerializeField] public TycoonPickupHandler TycoonPickupHandler { get; private set; } [SerializeField] private PayMoneyUi _payMoneyUiObject; [SerializeField] private Vector3 _offset = new(0f, 1.5f, 0f); [Title("연출")] [SerializeField] private Transform _restaurantSpawnLocation; [SerializeField] private Transform _favorabilitySpawnLocation01; [SerializeField] private Transform _favorabilitySpawnLocation02; public Material MaterialInstance { get; protected set; } public bool IsCleaningFloor { get; set; } public bool IsCleaningTable { get; set; } public bool IsCleaningMold { get; set; } public bool IsMakingCocktail { get; set; } public bool IsPumping { get; set; } public bool IsInteractedSlimeGarnish { get; set; } public bool IsInteractedLimeTreeGarnish { get; set; } public bool IsCookingFried { get; set; } public bool IsCookingStew { get; set; } // State public StateMachineController StateMachineController { get; private set; } public IStateMachine IdleState { get; private set; } public IStateMachine WalkingState { get; private set; } public IStateMachine DashState { get; private set; } public IStateMachine InteractionState { get; private set; } #endregion // Unity events #region Unity events private void Awake() { InitializeComponents(); if (!GameManager.Instance.CurrentTycoonPlayer) { GameManager.Instance.SetCurrentTycoonPlayer(this); } } private void Start() { EventManager.OnDead += Die; EventManager.OnMakeCocktailCompleted += MakeCocktailCompleted; EventManager.OnCocktailDiscarded += DiscardCocktail; EventManager.OnCocktailServedToCustomer += ServedCocktail; EventManager.OnChangedRandomCocktail += ChangeCocktail; EventManager.OnPickupCocktail += PickupCocktail; EventManager.OnPlaceOnServingTable += PlaceOnServingTable; // 밀키트 이벤트 EventManager.OnPickupMealKit += PickupCook; EventManager.OnServedCookToCustomer += ServedCook; EventManager.OnMoveRestaurant += MoveRestaurant; EventManager.OnMoveFavorability01 += MoveFavorability01; EventManager.OnMoveFavorability02 += MoveFavorability02; TycoonMovement.OnSucceedDash += DashSucceed; var originalMaterial = SpineController.SkeletonAnimation.SkeletonDataAsset.atlasAssets[0].PrimaryMaterial; var newMaterial = SpineController.SkeletonAnimation.CustomMaterialOverride[originalMaterial]; MaterialInstance = Instantiate(newMaterial); SpineController.SkeletonAnimation.CustomMaterialOverride[originalMaterial] = MaterialInstance; PlayerHealthPoint.SetMaterialInstance(MaterialInstance); IdleState = new IdleState(); WalkingState = new WalkingState(); DashState = new DashState(); InteractionState = new InteractionState(); StateMachineController = new StateMachineController(this, IdleState); } private void Update() { StateMachineController.UpdateState(this); } private void OnDestroy() { EventManager.OnDead -= Die; EventManager.OnMakeCocktailCompleted -= MakeCocktailCompleted; EventManager.OnCocktailDiscarded -= DiscardCocktail; EventManager.OnCocktailServedToCustomer -= ServedCocktail; EventManager.OnChangedRandomCocktail -= ChangeCocktail; EventManager.OnPickupCocktail -= PickupCocktail; EventManager.OnPlaceOnServingTable -= PlaceOnServingTable; // 밀키트 이벤트 EventManager.OnPickupMealKit -= PickupCook; EventManager.OnServedCookToCustomer -= ServedCook; EventManager.OnMoveRestaurant -= MoveRestaurant; EventManager.OnMoveFavorability01 -= MoveFavorability01; EventManager.OnMoveFavorability02 -= MoveFavorability02; TycoonMovement.OnSucceedDash -= DashSucceed; } #endregion // Initialize methods #region Initialize methods [Button("컴포넌트 초기화")] private void InitializeComponents() { Rigidbody = GetComponent(); CharacterCollider = GetComponent(); VisualLook = transform.Find("VisualLook"); SkeletonAnimation = VisualLook.GetComponent(); InteractionCanvas = transform.GetComponentInChildren(); SpineController = GetComponent(); PlayerHealthPoint = GetComponent(); TycoonInput = GetComponent(); TycoonMovement = GetComponent(); TycoonPickupHandler = GetComponent(); var renderer = VisualLook.GetComponent(); renderer.sortingLayerName = "Default"; renderer.sortingOrder = 5; } #endregion // Methods #region Methods private void Die() { } public void MakeCocktailCompleted(CocktailData cocktailData, bool isMadePlayer) { if (!isMadePlayer) return; InteractionCanvas.BalloonUi.SetItemImage(cocktailData); TycoonPickupHandler.PickupItem(cocktailData, isMadePlayer); if (!TycoonManager.Instance.TycoonStatus.ContainsPassiveCard(PassiveCard.MakingBonus) || cocktailData.Idx == "Cocktail000") return; var tip = (int)(TycoonManager.Instance.GetCurrentLevelData().Gold * TycoonManager.Instance.TycoonStatus.TipMultiplier); if (tip > 0) { var payMoneyUi = Instantiate(_payMoneyUiObject, transform.position + _offset, Quaternion.identity, TycoonUiManager.Instance.WorldCanvas.transform); payMoneyUi.Initialize(tip, true); } } public void PickupCocktail(CocktailData cocktailData) { TycoonPickupHandler.PickupItem(cocktailData, true); InteractionCanvas.BalloonUi.SetItemImage(cocktailData); } public void PickupCook(CraftRecipeData craftRecipeData) { bool succeedPickUp = TycoonPickupHandler.PickupCook(craftRecipeData); if (succeedPickUp) { InteractionCanvas.BalloonUi.SetItemImage(craftRecipeData.Sprite); } } public void ServedCook(bool isServedPlayer) { if (!isServedPlayer) return; TycoonPickupHandler.DiscardCook(); InteractionCanvas.BalloonUi.DiscardItem(); } public void PlaceOnServingTable() { TycoonPickupHandler.DiscardItem(); InteractionCanvas.BalloonUi.DiscardItem(); } public void DiscardCocktail(CocktailData cocktailData, bool isDiscardedPlayer) { if (!isDiscardedPlayer) return; TycoonPickupHandler.DiscardItem(); InteractionCanvas.BalloonUi.DiscardItem(); } public void ServedCocktail(CocktailData cocktailData, bool isServedPlayer) { if (!isServedPlayer) return; TycoonPickupHandler.ServedItem(cocktailData); InteractionCanvas.BalloonUi.DiscardItem(); } public void ChangeCocktail(CocktailData cocktailData) { InteractionCanvas.BalloonUi.SetItemImage(cocktailData); TycoonPickupHandler.ChangeItem(cocktailData); } private void DashSucceed() { StateMachineController.TransitionToState(DashState, this); } public bool IsInteracting() { return IsMakingCocktail || IsCleaningFloor || IsCleaningTable || IsCleaningMold || IsPumping || IsInteractedSlimeGarnish || IsInteractedLimeTreeGarnish || IsCookingFried || IsCookingStew; } public void Teleport(Vector3 position) => transform.position = position; public void MoveRestaurant() { VisualLook.rotation = Quaternion.Euler(new Vector3(40f, 0f, 0f)); Teleport(_restaurantSpawnLocation.position); } public void MoveFavorability01() { VisualLook.rotation = Quaternion.Euler(new Vector3(0f, 0f, 0f)); Teleport(_favorabilitySpawnLocation01.position); } public void MoveFavorability02() { VisualLook.rotation = Quaternion.Euler(new Vector3(0f, 0f, 0f)); Teleport(_favorabilitySpawnLocation02.position); } public void ShowInteractionUi() { EventManager.InvokeHoldInteracting(0f); EventManager.InvokeShowInteractionUi("대화하기"); } public void HideInteractionUi() { EventManager.InvokeHideInteractionUi(); } #endregion } }