CapersProject/Assets/02.Scripts/Character/Npc/Customer.cs
Nam Tae Gun fd688231c2 타이쿤 맵 수정 및 손님 기능 추가
+ 요리 주문 기능 추가
+ Props 프리팹 일부 수정
+ 오늘의 메뉴 기능 연동
2024-07-17 01:05:53 +09:00

287 lines
7.9 KiB
C#

using System;
using BehaviorDesigner.Runtime;
using BlueWater.Enemies;
using BlueWater.Interfaces;
using BlueWater.Items;
using BlueWater.Players;
using BlueWater.Tycoons;
using BlueWater.Uis;
using Pathfinding;
using PixelCrushers.DialogueSystem;
using Sirenix.OdinInspector;
using UnityEngine;
namespace BlueWater.Npcs.Customers
{
public enum CustomerSpineAnimation
{
Idle = 0,
Run,
RunSlow,
Eat,
Eat2
}
public class Customer : MonoBehaviour, IPlayerInteraction
{
// Variables
#region Variables
// Components
[field: SerializeField]
public Transform Transform { get; private set; }
[field: SerializeField]
public Rigidbody Rigidbody { get; private set; }
[field: SerializeField]
public CapsuleCollider CharacterCollider { get; private set; }
[field: SerializeField]
public BehaviorTree BehaviorTree { get; private set; }
[field: SerializeField]
public Transform VisualLook { get; private set; }
[field: SerializeField]
public MeshRenderer MeshRenderer { get; private set; }
[field: SerializeField]
public BarkTrigger BarkTrigger { get; private set; }
[field: SerializeField]
public Canvas InteractionCanvas { get; private set; }
[field: SerializeField]
public Transform InteractionUi { get; private set; }
[field: SerializeField]
public FoodBalloonUi FoodBalloonUi { get; private set; }
// Classes
[field: SerializeField, Required]
public CustomerData CustomerData { get; private set; }
[field: SerializeField, Required]
public SpineController SpineController { get; private set; }
[field: SerializeField, Required]
public AiMovement AIMovement { get; private set; }
[field: SerializeField]
public bool EnableInteraction { get; private set; } = true;
[field: SerializeField]
public float InteractionRadius { get; private set; } = 2f;
private IAstarAI _astarAi;
public TableSeat TableSeat { get; private set; }
private int _happyPoint;
public int HappyPoint
{
get => _happyPoint;
private set
{
var newHappyPoint = Mathf.Max(0, value);
_happyPoint = newHappyPoint;
}
}
private bool _isMoving;
public bool IsMoving
{
get => _isMoving;
set
{
if (_isMoving == value) return;
_isMoving = value;
SpineController.PlayAnimation(_isMoving
? CustomerSpineAnimation.Run.ToString()
: CustomerSpineAnimation.Idle.ToString(), true);
}
}
private Vector3 _currentDirection = Vector3.right;
public Vector3 CurrentDirection
{
get => _currentDirection;
set
{
if (value == Vector3.zero) return;
_currentDirection = value;
}
}
private bool _isQuitting;
public Action OnInteraction;
#endregion
// Unity events
#region Unity events
private void Awake()
{
InitializeComponents();
}
private void OnApplicationQuit()
{
_isQuitting = true;
}
private void Update()
{
HandleMovement();
FlipVisualLook();
}
private void OnDestroy()
{
if (_isQuitting) return;
CustomerManager.Instance.UnregisterCustomer(this);
}
#endregion
// Initialize methods
#region Initialize methods
[Button("컴포넌트 초기화")]
protected virtual void InitializeComponents()
{
Transform = transform;
Rigidbody = GetComponent<Rigidbody>();
CharacterCollider = GetComponent<CapsuleCollider>();
BehaviorTree = GetComponent<BehaviorTree>();
VisualLook = transform.Find("VisualLook");
MeshRenderer = VisualLook.GetComponent<MeshRenderer>();
BarkTrigger = transform.Find("DialogueSystem").GetComponent<BarkTrigger>();
InteractionCanvas = transform.Find("InteractionCanvas").GetComponent<Canvas>();
InteractionCanvas.worldCamera = TycoonCameraManager.Instance.UiCamera;
InteractionUi = InteractionCanvas.transform.Find("InteractionUi");
InteractionUi.localScale = Vector3.one * (1 / transform.localScale.x);
FoodBalloonUi = InteractionCanvas.transform.Find("FoodBalloonUi").GetComponent<FoodBalloonUi>();
SpineController = GetComponent<SpineController>();
AIMovement = GetComponent<AiMovement>();
_astarAi = GetComponent<IAstarAI>();
}
public void Initialize()
{
CustomerData = CustomerManager.Instance.GetRandomCustomerData();
AIMovement.SetMoveSpeed(CustomerData.MoveSpeed);
HappyPoint = CustomerData.BaseHappyPoint;
BehaviorTree.EnableBehavior();
}
#endregion
// Methods
#region Methods
private void HandleMovement()
{
if (!_astarAi.canMove || _astarAi.isStopped)
{
IsMoving = false;
return;
}
CurrentDirection = _astarAi.velocity.normalized;
IsMoving = _astarAi.velocity != Vector3.zero || _astarAi.velocity != Vector3.positiveInfinity;
}
private 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;
}
public void SetTableSeat(TableSeat tableSeat)
{
TableSeat = tableSeat;
FoodBalloonUi.Initialize(TableSeat);
}
public void SetCurrentDirection(Vector3 normalDirection) => CurrentDirection = normalDirection;
public void SetTableSeatPositionAndDirection()
{
transform.position = TableSeat.SeatTransform.position;
SetCurrentDirection(TableSeat.TableDirection);
}
public void SetFood(ItemData foodData)
{
TableSeat.SetFood(foodData.Sprite);
}
public void Interaction()
{
OnInteraction?.Invoke();
}
public bool CanInteraction() => true;
public void ShowInteractionUi()
{
if (!InteractionUi) return;
InteractionUi.gameObject.SetActive(true);
}
public void HideInteractionUi()
{
if (!InteractionUi) return;
InteractionUi.gameObject.SetActive(false);
}
public void RegisterPlayerInteraction()
{
if (EnableInteraction)
{
GameManager.Instance.CurrentTycoonPlayer.TycoonInput.RegisterPlayerInteraction(this);
}
}
public void UnregisterPlayerInteraction()
{
if (EnableInteraction)
{
GameManager.Instance.CurrentTycoonPlayer.TycoonInput.UnregisterPlayerInteraction(this);
}
}
public void AddHappyPoint(int value) => HappyPoint += value;
public void Bark(string conversation = null)
{
if (!string.IsNullOrEmpty(conversation))
{
BarkTrigger.conversation = conversation;
}
BarkTrigger.OnUse();
}
#endregion
}
}