DEG-16 [UPDATE] PlayerState 구현
This commit is contained in:
parent
1a7b282bd8
commit
7c526a1f70
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8f4cdb374bd0572e763220b0e51ca6989957a7c65c0be176f5ee5e00068419e3
|
||||
size 4269
|
||||
oid sha256:08d59f4f15437f527ada2d57db2db6ad8fa7d0dc8446934f0d18a2a590021068
|
||||
size 4267
|
||||
|
BIN
Assets/JAY/Character Test Scene.unity
(Stored with Git LFS)
BIN
Assets/JAY/Character Test Scene.unity
(Stored with Git LFS)
Binary file not shown.
@ -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<PlayerState, IPlayerState> _playerStates;
|
||||
public Animator PlayerAnimator { get; private set; }
|
||||
public CharacterController CharacterController => _characterController;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
PlayerAnimator = GetComponent<Animator>();
|
||||
_characterController = GetComponent<CharacterController>();
|
||||
if (joystick == null)
|
||||
{
|
||||
joystick = FindObjectOfType<VariableJoystick>();
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// 상태 초기화
|
||||
_playerStateIdle = new PlayerStateIdle();
|
||||
_playerStateMove = new PlayerStateMove();
|
||||
|
||||
_playerStates = new Dictionary<PlayerState, IPlayerState>
|
||||
{
|
||||
{ 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<GameObject>("Player/Weapon/Chopstick");
|
||||
weapon = Instantiate(weaponObject, rightHandTransform);
|
||||
// .GetComponent<WeaponController>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
||||
|
71
Assets/JAY/Scripts/PlayerControllerEditor.cs
Normal file
71
Assets/JAY/Scripts/PlayerControllerEditor.cs
Normal file
@ -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();
|
||||
}
|
||||
}
|
3
Assets/JAY/Scripts/PlayerControllerEditor.cs.meta
Normal file
3
Assets/JAY/Scripts/PlayerControllerEditor.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b0b2ffd1e9824f71ac899076fa692425
|
||||
timeCreated: 1744940250
|
3
Assets/JAY/Scripts/PlayerState.meta
Normal file
3
Assets/JAY/Scripts/PlayerState.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a4bf902c969a48439357a75159718385
|
||||
timeCreated: 1744942105
|
9
Assets/JAY/Scripts/PlayerState/IPlayerState.cs
Normal file
9
Assets/JAY/Scripts/PlayerState/IPlayerState.cs
Normal file
@ -0,0 +1,9 @@
|
||||
public interface IPlayerState
|
||||
{
|
||||
// 해당 상태로 진입했을 때 호출되는 메서드
|
||||
void Enter(PlayerController playerController);
|
||||
// 해당 상태에 머물러 있을 때 Update 주기로 호출되는 메서드
|
||||
void Update();
|
||||
// 해당 상태에서 빠져 나갈 때 호출되는 메서드
|
||||
void Exit();
|
||||
}
|
3
Assets/JAY/Scripts/PlayerState/IPlayerState.cs.meta
Normal file
3
Assets/JAY/Scripts/PlayerState/IPlayerState.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 80d0d284b37a49eeb7376c3b07207f0c
|
||||
timeCreated: 1744941077
|
30
Assets/JAY/Scripts/PlayerState/PlayerStateIdle.cs
Normal file
30
Assets/JAY/Scripts/PlayerState/PlayerStateIdle.cs
Normal file
@ -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;
|
||||
}
|
||||
}
|
3
Assets/JAY/Scripts/PlayerState/PlayerStateIdle.cs.meta
Normal file
3
Assets/JAY/Scripts/PlayerState/PlayerStateIdle.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9da273f1a9ed4537b36c546a1c9cc390
|
||||
timeCreated: 1744942131
|
66
Assets/JAY/Scripts/PlayerState/PlayerStateMove.cs
Normal file
66
Assets/JAY/Scripts/PlayerState/PlayerStateMove.cs
Normal file
@ -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);
|
||||
}
|
||||
}
|
3
Assets/JAY/Scripts/PlayerState/PlayerStateMove.cs.meta
Normal file
3
Assets/JAY/Scripts/PlayerState/PlayerStateMove.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1399a67446d14e10bbee938def76d41a
|
||||
timeCreated: 1744942268
|
BIN
Assets/Prefabs/Player.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/Prefabs/Player.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
7
Assets/Prefabs/Player.prefab.meta
Normal file
7
Assets/Prefabs/Player.prefab.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b2775e44f9b29414faf17cc5025f9478
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Resources.meta
Normal file
8
Assets/Resources.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: efccde2839c637a42809d0fd5f3c1076
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Resources/Player.meta
Normal file
8
Assets/Resources/Player.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82aa723a5da5571418a09a8f1878011d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Resources/Player/Weapon.meta
Normal file
8
Assets/Resources/Player/Weapon.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6f2f1e17292ba234781708b9b427c3dc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
BIN
Assets/Resources/Player/Weapon/Chopstick.prefab
(Stored with Git LFS)
Normal file
BIN
Assets/Resources/Player/Weapon/Chopstick.prefab
(Stored with Git LFS)
Normal file
Binary file not shown.
7
Assets/Resources/Player/Weapon/Chopstick.prefab.meta
Normal file
7
Assets/Resources/Player/Weapon/Chopstick.prefab.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a4adbb52d0166745b4b6344ac5191e7
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
x
Reference in New Issue
Block a user