OldBlueWater/BlueWater/Assets/02.Scripts/Tycoon/TycoonPlayer.cs
2023-12-19 11:31:29 +09:00

197 lines
6.6 KiB
C#

using System.Collections;
using BlueWaterProject.Type;
using PixelCrushers.DialogueSystem;
using SoulGames.EasyGridBuilderPro;
using UnityEngine;
using UnityEngine.InputSystem;
using DialogueSystemTrigger = PixelCrushers.DialogueSystem.Wrappers.DialogueSystemTrigger;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[RequireComponent(typeof(Rigidbody))]
public class TycoonPlayer : MonoBehaviour
{
private float characterSpeed;
private Transform interactionTarget;
private Transform visualLook;
private Rigidbody rb;
//TODO : 나중에 스파인으로 바꾸고 삭제
public SpriteRenderer spriteRenderer;
public Sprite sideSprite;
public Sprite backSprite;
public Sprite frontSprite;
protected PlayerInput playerInput;
protected Vector2 movementInput;
private MultiGridUIManager multiGridUIManager;
private void Init()
{
characterSpeed = 10;
visualLook = transform.Find("UnitRoot");
rb = GetComponent<Rigidbody>();
spriteRenderer = visualLook.GetComponent<SpriteRenderer>();
playerInput = GetComponent<PlayerInput>();
multiGridUIManager = GameObject.Find("EGB Pro UI").GetComponent<MultiGridUIManager>();
}
private void Awake()
{
Init();
}
private void Start()
{
}
private void FixedUpdate()
{
MoveCharacterPlayer();
}
public void OnMove(InputValue value) // WASD
{
movementInput = value.Get<Vector2>();
}
private void OnMouse0(InputValue value)
{
}
private void OnInteraction(InputValue value)
{
}
private void OnCancel(InputValue value)
{
}
private void MoveCharacterPlayer()
{
var extraGravityForce = (Physics.gravity * rb.mass) * 2f;
rb.AddForce(extraGravityForce);
Vector3 movement = Vector3.zero;
movement = transform.rotation * new Vector3(movementInput.x, 0, movementInput.y) *
(characterSpeed * Time.deltaTime);
gameObject.transform.position += movement;
var localScale = visualLook.localScale;
// 왼쪽
if (movement.x < 0)
{
localScale.x = Mathf.Abs(localScale.x);
spriteRenderer.sprite = sideSprite;
}
// 오른쪽
else if (movement.x > 0)
{
localScale.x = -Mathf.Abs(localScale.x);
spriteRenderer.sprite = sideSprite;
}
// 뒤로
else if (movement.z > 0)
{
spriteRenderer.sprite = backSprite;
}
// 앞으로
else if (movement.z < 0)
{
spriteRenderer.sprite = frontSprite;
}
visualLook.localScale = localScale;
// var movement = transform.rotation * new Vector3(-movementInput.y, 0, movementInput.x) * (characterSpeed * Time.deltaTime);
// rb.MovePosition(rb.position + movement);
}
private IEnumerator MoveCharacterToPosition(Vector3 position, float scaleX)
{
var elapsedTime = 0f;
var duration = 1f; // 이동에 걸리는 시간 (초)
var startingPosition = transform.position;
// 방향 즉시 변경
visualLook.localScale = new Vector3(scaleX, visualLook.localScale.y, visualLook.localScale.z);
while (elapsedTime < duration)
{
transform.position = Vector3.Lerp(startingPosition, position, elapsedTime / duration);
elapsedTime += Time.deltaTime;
yield return null;
}
transform.position = position;
}
public void StartInteraction(Transform target)
{
interactionTarget = target;
interactionTarget.GetComponent<InShipNpc>()?.ChangeStateToInteraction();
var targetPosition = interactionTarget.position;
var playerPosition = transform.position;
var directionToTarget = (targetPosition - playerPosition).normalized;
// 캐릭터가 NPC의 왼쪽 또는 오른쪽에 있는지 확인
var crossProduct = Vector3.Cross(directionToTarget, transform.forward).y;
Vector3 desiredPosition;
float desiredScaleX; // 캐릭터의 방
if (crossProduct > 0) // 캐릭터가 NPC의 왼쪽에 있는 경우
{
desiredPosition = targetPosition + interactionTarget.right * 2f;
desiredScaleX = 1f; // 오른쪽을 바라봄
}
else // 캐릭터가 NPC의 오른쪽에 있는 경우
{
desiredPosition = targetPosition + interactionTarget.right * -2f;
desiredScaleX = -1f; // 왼쪽을 바라봄
}
// 장애물 감지
if (Physics.Raycast(playerPosition, (desiredPosition - playerPosition).normalized, Vector3.Distance(playerPosition, desiredPosition), LayerMask.GetMask("Obstacle")))
{
// 장애물이 감지되면, 반대쪽으로 이동
desiredPosition = crossProduct > 0 ? targetPosition + interactionTarget.right * -2f : targetPosition + interactionTarget.right * 2f;
desiredScaleX = -desiredScaleX; // 방향을 반전
}
// 캐릭터를 원하는 위치와 방향으로 부드럽게 이동 및 회전
StartCoroutine(MoveCharacterToPosition(desiredPosition, desiredScaleX));
UiManager.Inst.InShipInteraction.gameObject.SetActive(true);
}
public void StartConversation()
{
if (interactionTarget != null)
{
interactionTarget.GetComponent<DialogueSystemTrigger>().OnConversationStart(interactionTarget);
UiManager.Inst.InShipInteraction.gameObject.SetActive(false);
}
}
public void EndInteraction()
{
interactionTarget.GetComponent<InShipNpc>()?.RestoreState();
}
public void EndConversation()
{
UiManager.Inst.InShipInteraction.gameObject.SetActive(true);
}
}
}