From 7c526a1f70eb57c9983301ba17c393b73a990d6d Mon Sep 17 00:00:00 2001 From: Jay <96156114+jaydev00a@users.noreply.github.com> Date: Fri, 18 Apr 2025 13:17:30 +0900 Subject: [PATCH] =?UTF-8?q?DEG-16=20[UPDATE]=20PlayerState=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JAY/Animator/PlayerController.controller | 4 +- Assets/JAY/Character Test Scene.unity | 4 +- Assets/JAY/Scripts/PlayerController.cs | 110 ++++++++++++------ Assets/JAY/Scripts/PlayerControllerEditor.cs | 71 +++++++++++ .../Scripts/PlayerControllerEditor.cs.meta | 3 + Assets/JAY/Scripts/PlayerState.meta | 3 + .../JAY/Scripts/PlayerState/IPlayerState.cs | 9 ++ .../Scripts/PlayerState/IPlayerState.cs.meta | 3 + .../Scripts/PlayerState/PlayerStateIdle.cs | 30 +++++ .../PlayerState/PlayerStateIdle.cs.meta | 3 + .../Scripts/PlayerState/PlayerStateMove.cs | 66 +++++++++++ .../PlayerState/PlayerStateMove.cs.meta | 3 + Assets/Prefabs/Player.prefab | 3 + Assets/Prefabs/Player.prefab.meta | 7 ++ Assets/Resources.meta | 8 ++ Assets/Resources/Player.meta | 8 ++ Assets/Resources/Player/Weapon.meta | 8 ++ .../Resources/Player/Weapon/Chopstick.prefab | 3 + .../Player/Weapon/Chopstick.prefab.meta | 7 ++ 19 files changed, 316 insertions(+), 37 deletions(-) create mode 100644 Assets/JAY/Scripts/PlayerControllerEditor.cs create mode 100644 Assets/JAY/Scripts/PlayerControllerEditor.cs.meta create mode 100644 Assets/JAY/Scripts/PlayerState.meta create mode 100644 Assets/JAY/Scripts/PlayerState/IPlayerState.cs create mode 100644 Assets/JAY/Scripts/PlayerState/IPlayerState.cs.meta create mode 100644 Assets/JAY/Scripts/PlayerState/PlayerStateIdle.cs create mode 100644 Assets/JAY/Scripts/PlayerState/PlayerStateIdle.cs.meta create mode 100644 Assets/JAY/Scripts/PlayerState/PlayerStateMove.cs create mode 100644 Assets/JAY/Scripts/PlayerState/PlayerStateMove.cs.meta create mode 100644 Assets/Prefabs/Player.prefab create mode 100644 Assets/Prefabs/Player.prefab.meta create mode 100644 Assets/Resources.meta create mode 100644 Assets/Resources/Player.meta create mode 100644 Assets/Resources/Player/Weapon.meta create mode 100644 Assets/Resources/Player/Weapon/Chopstick.prefab create mode 100644 Assets/Resources/Player/Weapon/Chopstick.prefab.meta diff --git a/Assets/JAY/Animator/PlayerController.controller b/Assets/JAY/Animator/PlayerController.controller index e4cc432c..d46c2f2f 100644 --- a/Assets/JAY/Animator/PlayerController.controller +++ b/Assets/JAY/Animator/PlayerController.controller @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8f4cdb374bd0572e763220b0e51ca6989957a7c65c0be176f5ee5e00068419e3 -size 4269 +oid sha256:08d59f4f15437f527ada2d57db2db6ad8fa7d0dc8446934f0d18a2a590021068 +size 4267 diff --git a/Assets/JAY/Character Test Scene.unity b/Assets/JAY/Character Test Scene.unity index 22b191e1..40b4460f 100644 --- a/Assets/JAY/Character Test Scene.unity +++ b/Assets/JAY/Character Test Scene.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:008a0c4e6bead6c72e08ea51da874d3e1f15c39f02973035344d5fdf02fa4866 -size 116816 +oid sha256:c66ec53ae91ce31decef84939d3722fa53df7028bd5b03356f02ada610525340 +size 27705 diff --git a/Assets/JAY/Scripts/PlayerController.cs b/Assets/JAY/Scripts/PlayerController.cs index ae6a7d52..6b761e88 100644 --- a/Assets/JAY/Scripts/PlayerController.cs +++ b/Assets/JAY/Scripts/PlayerController.cs @@ -2,60 +2,104 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; +public enum PlayerState { None, Idle, Move, Attack, Hit, Dead } + public class PlayerController : CharacterBase { // 외부 접근 가능 변수 - [Header("플레이어 관련")] - public VariableJoystick joystick; - public Animator PlayerAnimator { get; private set; } - + [Header("Movement")] [SerializeField] private float rotationSpeed = 10f; + [Header("Attach Points")] + [SerializeField] private Transform rightHandTransform; + [SerializeField] private Transform headTransform; + + // 내부에서만 사용하는 변수 private CharacterController _characterController; - private Vector3 gravityVelocity; + private bool _isBattle; + private GameObject weapon; + + // 상태 관련 + private PlayerStateIdle _playerStateIdle; + private PlayerStateMove _playerStateMove; + + // 외부에서도 사용하는 변수 + public VariableJoystick joystick { get; private set; } + public PlayerState CurrentState { get; private set; } + private Dictionary _playerStates; + public Animator PlayerAnimator { get; private set; } + public CharacterController CharacterController => _characterController; private void Awake() { PlayerAnimator = GetComponent(); _characterController = GetComponent(); + if (joystick == null) + { + joystick = FindObjectOfType(); + } + } + + private void Start() + { + // 상태 초기화 + _playerStateIdle = new PlayerStateIdle(); + _playerStateMove = new PlayerStateMove(); + + _playerStates = new Dictionary + { + { PlayerState.Idle, _playerStateIdle }, + { PlayerState.Move, _playerStateMove }, + }; + + PlayerInit(); } private void Update() { - HandleMovement(); // 이동 처리 + if (CurrentState != PlayerState.None) + { + _playerStates[CurrentState].Update(); + } } - #region 동작 관련 - - private void HandleMovement() + #region 초기화 관련 + + private void PlayerInit() { - float x = joystick.Horizontal; - float z = joystick.Vertical; + SetState(PlayerState.Idle); - Vector3 moveDir = new Vector3(x, 0, z); - Vector3 move = moveDir.normalized * moveSpeed; - - // 회전 - if (moveDir.magnitude > 0.1f) - { - Quaternion toRotation = Quaternion.LookRotation(moveDir, Vector3.up); - transform.rotation = Quaternion.Slerp(transform.rotation, toRotation, Time.deltaTime * 10f); - } - - // 중력 처리 - if (_characterController.isGrounded && gravityVelocity.y < 0) - { - gravityVelocity.y = -0.1f; - } - - gravityVelocity.y += gravity * Time.deltaTime; - - Vector3 finalMove = (move + gravityVelocity) * Time.deltaTime; - _characterController.Move(finalMove); - - PlayerAnimator.SetFloat("Move", _characterController.velocity.magnitude); + InstantiateWeapon(); + weapon.SetActive(_isBattle); } + private void InstantiateWeapon() + { + if (weapon == null) + { + GameObject weaponObject = Resources.Load("Player/Weapon/Chopstick"); + weapon = Instantiate(weaponObject, rightHandTransform); + // .GetComponent(); + } + } + + #endregion + + public void SetState(PlayerState state) + { + if (CurrentState != PlayerState.None) + { + _playerStates[CurrentState].Exit(); + } + CurrentState = state; + _playerStates[CurrentState].Enter(this); + } + + public void SwitchBattleMode() + { + _isBattle = !_isBattle; + weapon.SetActive(_isBattle); + } } diff --git a/Assets/JAY/Scripts/PlayerControllerEditor.cs b/Assets/JAY/Scripts/PlayerControllerEditor.cs new file mode 100644 index 00000000..2ac95598 --- /dev/null +++ b/Assets/JAY/Scripts/PlayerControllerEditor.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; + +[CustomEditor(typeof(PlayerController))] +public class PlayerControllerEditor : Editor +{ + public override void OnInspectorGUI() + { + // 기본 인스펙터를 그리기 + base.OnInspectorGUI(); + + // 타겟 컴포넌트 참조 가져오기 + PlayerController playerController = (PlayerController)target; + + // 여백 추가 + EditorGUILayout.Space(); + EditorGUILayout.LabelField("상태 디버그 정보", EditorStyles.boldLabel); + + + EditorGUILayout.BeginVertical(EditorStyles.helpBox); + EditorGUILayout.LabelField("현재 상태", playerController.CurrentState.ToString(), + EditorStyles.boldLabel); + EditorGUILayout.EndVertical(); + + + // 지면 접촉 상태 + GUI.backgroundColor = Color.white; + EditorGUILayout.Space(); + EditorGUILayout.LabelField("캐릭터 위치 디버그 정보", EditorStyles.boldLabel); + // GUI.enabled = false; + // EditorGUILayout.Toggle("지면 접촉", playerController.IsGrounded); + // GUI.enabled = true; + + // 강제로 상태 변경 버튼 + EditorGUILayout.BeginHorizontal(); + + if (GUILayout.Button("Idle")) + playerController.SetState(PlayerState.Idle); + if (GUILayout.Button("Move")) + playerController.SetState(PlayerState.Move); + if (GUILayout.Button("BattleMode")) + playerController.SwitchBattleMode(); + // if (GUILayout.Button("Attack")) + // playerController.SetState(PlayerState.Attack); + // if (GUILayout.Button("Hit")) + // playerController.SetState(PlayerState.Hit); + // if (GUILayout.Button("Dead")) + // playerController.SetState(PlayerState.Dead); + + EditorGUILayout.EndHorizontal(); + } + + private void OnEnable() + { + EditorApplication.update += OnEditorUpdate; + } + + private void OnDisable() + { + EditorApplication.update -= OnEditorUpdate; + } + + private void OnEditorUpdate() + { + if (target != null) + Repaint(); + } +} diff --git a/Assets/JAY/Scripts/PlayerControllerEditor.cs.meta b/Assets/JAY/Scripts/PlayerControllerEditor.cs.meta new file mode 100644 index 00000000..d5abe5d8 --- /dev/null +++ b/Assets/JAY/Scripts/PlayerControllerEditor.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b0b2ffd1e9824f71ac899076fa692425 +timeCreated: 1744940250 \ No newline at end of file diff --git a/Assets/JAY/Scripts/PlayerState.meta b/Assets/JAY/Scripts/PlayerState.meta new file mode 100644 index 00000000..c9bddca3 --- /dev/null +++ b/Assets/JAY/Scripts/PlayerState.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a4bf902c969a48439357a75159718385 +timeCreated: 1744942105 \ No newline at end of file diff --git a/Assets/JAY/Scripts/PlayerState/IPlayerState.cs b/Assets/JAY/Scripts/PlayerState/IPlayerState.cs new file mode 100644 index 00000000..c45cd422 --- /dev/null +++ b/Assets/JAY/Scripts/PlayerState/IPlayerState.cs @@ -0,0 +1,9 @@ +public interface IPlayerState +{ + // 해당 상태로 진입했을 때 호출되는 메서드 + void Enter(PlayerController playerController); + // 해당 상태에 머물러 있을 때 Update 주기로 호출되는 메서드 + void Update(); + // 해당 상태에서 빠져 나갈 때 호출되는 메서드 + void Exit(); +} \ No newline at end of file diff --git a/Assets/JAY/Scripts/PlayerState/IPlayerState.cs.meta b/Assets/JAY/Scripts/PlayerState/IPlayerState.cs.meta new file mode 100644 index 00000000..1b4e9788 --- /dev/null +++ b/Assets/JAY/Scripts/PlayerState/IPlayerState.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 80d0d284b37a49eeb7376c3b07207f0c +timeCreated: 1744941077 \ No newline at end of file diff --git a/Assets/JAY/Scripts/PlayerState/PlayerStateIdle.cs b/Assets/JAY/Scripts/PlayerState/PlayerStateIdle.cs new file mode 100644 index 00000000..2ba5e943 --- /dev/null +++ b/Assets/JAY/Scripts/PlayerState/PlayerStateIdle.cs @@ -0,0 +1,30 @@ +using UnityEngine; + +public class PlayerStateIdle : MonoBehaviour, IPlayerState +{ + private PlayerController _playerController; + + public void Enter(PlayerController playerController) + { + _playerController = playerController; + // _playerController.Animator.SetBool("Idle", true); + } + + public void Update() + { + float inputHorizontal = _playerController.joystick.Horizontal; + float inputVertical = _playerController.joystick.Vertical; + + // 이동 + if (inputHorizontal != 0 || inputVertical != 0) + { + _playerController.SetState(PlayerState.Move); + return; + } + } + + public void Exit() + { + _playerController = null; + } +} diff --git a/Assets/JAY/Scripts/PlayerState/PlayerStateIdle.cs.meta b/Assets/JAY/Scripts/PlayerState/PlayerStateIdle.cs.meta new file mode 100644 index 00000000..a8424bf3 --- /dev/null +++ b/Assets/JAY/Scripts/PlayerState/PlayerStateIdle.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9da273f1a9ed4537b36c546a1c9cc390 +timeCreated: 1744942131 \ No newline at end of file diff --git a/Assets/JAY/Scripts/PlayerState/PlayerStateMove.cs b/Assets/JAY/Scripts/PlayerState/PlayerStateMove.cs new file mode 100644 index 00000000..5ac09e92 --- /dev/null +++ b/Assets/JAY/Scripts/PlayerState/PlayerStateMove.cs @@ -0,0 +1,66 @@ +using UnityEngine; + +public class PlayerStateMove : MonoBehaviour, IPlayerState +{ + private static readonly int Move = Animator.StringToHash("Move"); + private PlayerController _playerController; + private Vector3 _gravityVelocity; + + public void Enter(PlayerController playerController) + { + _playerController = playerController; + _playerController.PlayerAnimator.SetBool(Move, true); + } + + public void Update() + { + float inputHorizontal = _playerController.joystick.Horizontal; + float inputVertical = _playerController.joystick.Vertical; + + // 이동 + if (inputHorizontal != 0 || inputVertical != 0) + { + HandleMovement(); + return; + } + else + { + _playerController.SetState(PlayerState.Idle); + } + } + + public void Exit() + { + _playerController.PlayerAnimator.SetBool(Move, false); + _playerController = null; + } + + private void HandleMovement() + { + float inputHorizontal = _playerController.joystick.Horizontal; + float inputVertical = _playerController.joystick.Vertical; + + Vector3 moveDir = new Vector3(inputHorizontal, 0, inputVertical); + Vector3 move = moveDir.normalized * _playerController.moveSpeed; + + // 회전 + if (moveDir.magnitude > 0.1f) + { + Quaternion toRotation = Quaternion.LookRotation(moveDir, Vector3.up); + _playerController.transform.rotation = Quaternion.Slerp(_playerController.transform.rotation, toRotation, Time.deltaTime * 10f); + } + + // 중력 처리 + if (_playerController.CharacterController.isGrounded && _gravityVelocity.y < 0) + { + _gravityVelocity.y = -0.1f; + } + + _gravityVelocity.y += _playerController.gravity * Time.deltaTime; + + Vector3 finalMove = (move + _gravityVelocity) * Time.deltaTime; + _playerController.CharacterController.Move(finalMove); + + // _playerController.PlayerAnimator.SetFloat("Move", _playerController.CharacterController.velocity.magnitude); + } +} diff --git a/Assets/JAY/Scripts/PlayerState/PlayerStateMove.cs.meta b/Assets/JAY/Scripts/PlayerState/PlayerStateMove.cs.meta new file mode 100644 index 00000000..526863f0 --- /dev/null +++ b/Assets/JAY/Scripts/PlayerState/PlayerStateMove.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1399a67446d14e10bbee938def76d41a +timeCreated: 1744942268 \ No newline at end of file diff --git a/Assets/Prefabs/Player.prefab b/Assets/Prefabs/Player.prefab new file mode 100644 index 00000000..8c88cda6 --- /dev/null +++ b/Assets/Prefabs/Player.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c84b42a2592f87b28c9896250c88e1c18f0181a1301f87946184d4e8c838c5c +size 78185 diff --git a/Assets/Prefabs/Player.prefab.meta b/Assets/Prefabs/Player.prefab.meta new file mode 100644 index 00000000..d213f1fd --- /dev/null +++ b/Assets/Prefabs/Player.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b2775e44f9b29414faf17cc5025f9478 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources.meta b/Assets/Resources.meta new file mode 100644 index 00000000..805b8e31 --- /dev/null +++ b/Assets/Resources.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: efccde2839c637a42809d0fd5f3c1076 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Player.meta b/Assets/Resources/Player.meta new file mode 100644 index 00000000..5bc6ed32 --- /dev/null +++ b/Assets/Resources/Player.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 82aa723a5da5571418a09a8f1878011d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Player/Weapon.meta b/Assets/Resources/Player/Weapon.meta new file mode 100644 index 00000000..aa3de7ba --- /dev/null +++ b/Assets/Resources/Player/Weapon.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6f2f1e17292ba234781708b9b427c3dc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Player/Weapon/Chopstick.prefab b/Assets/Resources/Player/Weapon/Chopstick.prefab new file mode 100644 index 00000000..8970c492 --- /dev/null +++ b/Assets/Resources/Player/Weapon/Chopstick.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b26784c1a742fe9cf59e6ecac6ac918b457769ccbe4619379a957a387351714 +size 6476 diff --git a/Assets/Resources/Player/Weapon/Chopstick.prefab.meta b/Assets/Resources/Player/Weapon/Chopstick.prefab.meta new file mode 100644 index 00000000..3fe04759 --- /dev/null +++ b/Assets/Resources/Player/Weapon/Chopstick.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5a4adbb52d0166745b4b6344ac5191e7 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: