using System.Collections; using BlueWaterProject.Type; using PixelCrushers.DialogueSystem; 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; //test character ani TODO : 나중에 스파인으로 바꾸고 삭제 public SpriteRenderer spriteRenderer; public Sprite sideSprite; public Sprite backSprite; public Sprite frontSprite; //test character ani protected PlayerInput playerInput; protected Vector2 movementInput; public ProximitySelector ProximitySelector { get; set; } private void Init() { characterSpeed = 10; visualLook = transform.Find("UnitRoot"); ProximitySelector = GetComponent(); rb = GetComponent(); spriteRenderer = visualLook.GetComponent(); playerInput = GetComponent(); } private void Awake() { Init(); } private void Start() { ProximitySelector.enabled = false; } private void FixedUpdate() { MoveCharacterPlayer(); } public void OnMove(InputValue value) // WASD { movementInput = value.Get(); } 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 GotoShipDeck() { var point = GameManager.Inst.ShipPlayer.transform.Find("TeleportPoint"); transform.position = point.position; } public void StartInteraction(Transform target) { ProximitySelector.enabled = false; interactionTarget = target; interactionTarget.GetComponent()?.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().OnConversationStart(interactionTarget); UiManager.Inst.InShipInteraction.gameObject.SetActive(false); } } public void EndInteraction() { ProximitySelector.enabled = true; interactionTarget.GetComponent()?.RestoreState(); } public void EndConversation() { UiManager.Inst.InShipInteraction.gameObject.SetActive(true); } } }