플레이어 입력 및 캐릭터 컨트롤러 추가
This commit is contained in:
parent
47e479c0fa
commit
9a25238497
296
Assets/Scirpts/CharacterController.cs
Normal file
296
Assets/Scirpts/CharacterController.cs
Normal file
@ -0,0 +1,296 @@
|
||||
using System;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace DDD
|
||||
{
|
||||
public class CharacterController : MonoBehaviour
|
||||
{
|
||||
#region Variables
|
||||
// Components
|
||||
public Rigidbody Rigidbody { get; private set; }
|
||||
private Transform _visualLook;
|
||||
|
||||
// Move
|
||||
[field: SerializeField, Range(1f, 20f), Tooltip("이동 속도")]
|
||||
public float MoveSpeed { get; private set; } = 7f;
|
||||
|
||||
[field: SerializeField]
|
||||
public float MoveSpeedMultiplier { get; private set; } = 1f;
|
||||
|
||||
public bool IsMoveEnabled { get; private set; } = true;
|
||||
|
||||
private bool _isMoving;
|
||||
|
||||
public bool IsMoving
|
||||
{
|
||||
get => _isMoving;
|
||||
private set
|
||||
{
|
||||
if (_isMoving == value) return;
|
||||
|
||||
_isMoving = value;
|
||||
|
||||
// if (_isMoving)
|
||||
// {
|
||||
// AudioManager.Instance.PlaySfx(_walkingSfxName, true);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// AudioManager.Instance.StopSfx(_walkingSfxName);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
// Dash
|
||||
[field: Title("대쉬")]
|
||||
[field: SerializeField, Range(1f, 50f), Tooltip("대쉬 속도")]
|
||||
public float DashSpeed { get; private set; } = 20f;
|
||||
|
||||
[field: SerializeField, Range(0.1f, 1f), Tooltip("대쉬 시간")]
|
||||
public float DashTime { get; private set; } = 0.2f;
|
||||
|
||||
[field: SerializeField, Range(0f, 5f), Tooltip("대쉬 쿨타임")]
|
||||
public float DashCooldown { get; private set; } = 0.5f;
|
||||
|
||||
[SerializeField]
|
||||
private ParticleSystem _dashParticle;
|
||||
|
||||
[Title("사운드")]
|
||||
// [SerializeField]
|
||||
// private string _walkingSfxName = "TycoonPlayerWalking";
|
||||
[SerializeField]
|
||||
private string _dashSfxName = "TycoonPlayerDashing";
|
||||
|
||||
public bool IsDashEnabled { get; private set; } = true;
|
||||
public bool IsDashing { get; private set; }
|
||||
|
||||
public bool IsDashCoolDownActive { get; private set; }
|
||||
|
||||
private Vector3 _inputDirection;
|
||||
|
||||
private Vector3 _currentDirection = Vector3.back;
|
||||
|
||||
public Vector3 CurrentDirection
|
||||
{
|
||||
get => _currentDirection;
|
||||
private set
|
||||
{
|
||||
if (value == Vector3.zero) return;
|
||||
|
||||
_currentDirection = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 PushDirection { get; private set; }
|
||||
public float PushPower { get; private set; }
|
||||
public float PushPowerReduction { get; private set; }
|
||||
|
||||
private InputAction _moveAction;
|
||||
private InputAction _dashAction;
|
||||
private Coroutine _dashInstance;
|
||||
private float _finalSpeed;
|
||||
|
||||
public Action OnSucceedDash;
|
||||
|
||||
#endregion
|
||||
|
||||
// Unity events
|
||||
|
||||
#region Unity events
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
InitializeComponents();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_moveAction = PlayerInputKeyManager.Instance.GetAction(InputActionMaps.Tycoon, TycoonActions.Move);
|
||||
// _dashAction = PlayerInputKeyManager.Instance.GetAction(InputActionMaps.Tycoon, TycoonActions.Dash);
|
||||
|
||||
_moveAction.performed += OnMove;
|
||||
_moveAction.canceled += OnMove;
|
||||
// _dashAction.performed += OnDash;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
FlipVisualLook();
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
if (!CanMove()) return;
|
||||
|
||||
Move();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
_moveAction.performed -= OnMove;
|
||||
_moveAction.canceled -= OnMove;
|
||||
// _dashAction.performed -= OnDash;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// Initialize Methods
|
||||
|
||||
#region Initialize Methods
|
||||
|
||||
private void InitializeComponents()
|
||||
{
|
||||
Rigidbody = GetComponent<Rigidbody>();
|
||||
_visualLook = transform.Find("VisualLook");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// Methods
|
||||
|
||||
#region Methods
|
||||
|
||||
// Event methods
|
||||
public void SetMoveSpeedMultiplier(float value) => MoveSpeedMultiplier = value;
|
||||
public void ResetMoveSpeedMultiplier() => MoveSpeedMultiplier = 1f;
|
||||
|
||||
public void EnableMoveAndDash()
|
||||
{
|
||||
IsMoveEnabled = true;
|
||||
IsDashEnabled = true;
|
||||
}
|
||||
|
||||
public void DisableMoveAndDash()
|
||||
{
|
||||
IsMoveEnabled = false;
|
||||
IsDashEnabled = false;
|
||||
}
|
||||
|
||||
public void SetCurrentDirection(Vector3 normalDirection) => CurrentDirection = normalDirection;
|
||||
|
||||
// Methods
|
||||
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;
|
||||
}
|
||||
|
||||
// Move
|
||||
public bool CanMove()
|
||||
{
|
||||
return IsMoveEnabled;
|
||||
}
|
||||
|
||||
public void AddForce(Vector3 force, ForceMode forceMode)
|
||||
{
|
||||
Rigidbody.AddForce(force, forceMode);
|
||||
}
|
||||
|
||||
public void SetPush(Vector3 pushDirection, float pushPower)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void OnMove(InputAction.CallbackContext context)
|
||||
{
|
||||
var movementInput = _moveAction.ReadValue<Vector2>();
|
||||
Debug.Log($"Move{movementInput.x} {movementInput.y}]");
|
||||
_inputDirection = new Vector3(movementInput.x, 0, movementInput.y).normalized;
|
||||
}
|
||||
|
||||
public void Move()
|
||||
{
|
||||
if (IsDashing)
|
||||
{
|
||||
IsMoving = false;
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentDirection = _inputDirection;
|
||||
IsMoving = _inputDirection != Vector3.zero;
|
||||
|
||||
var finalVelocity = _inputDirection * (MoveSpeed * MoveSpeedMultiplier);
|
||||
if (!Rigidbody.isKinematic)
|
||||
{
|
||||
Rigidbody.linearVelocity = finalVelocity;
|
||||
}
|
||||
}
|
||||
|
||||
// // Dash
|
||||
// public bool CanDash()
|
||||
// {
|
||||
// if (!IsDashEnabled || IsDashing || IsDashCoolDownActive) return false;
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// public void OnDash(InputAction.CallbackContext context)
|
||||
// {
|
||||
// if (!CanDash()) return;
|
||||
//
|
||||
// OnSucceedDash?.Invoke();
|
||||
// Dash();
|
||||
// }
|
||||
//
|
||||
// public void Dash()
|
||||
// {
|
||||
// Utils.StartUniqueCoroutine(this, ref _dashInstance, DashCoroutine());
|
||||
// }
|
||||
//
|
||||
// private IEnumerator DashCoroutine()
|
||||
// {
|
||||
// IsDashing = true;
|
||||
// IsDashCoolDownActive = true;
|
||||
// if (_dashParticle)
|
||||
// {
|
||||
// _dashParticle.Play();
|
||||
// }
|
||||
//
|
||||
// AudioManager.Instance.PlaySfx(_dashSfxName);
|
||||
//
|
||||
// var dashDirection = _inputDirection;
|
||||
// if (dashDirection == Vector3.zero)
|
||||
// {
|
||||
// dashDirection = CurrentDirection;
|
||||
// }
|
||||
//
|
||||
// var elapsedTime = 0f;
|
||||
// while (elapsedTime <= DashTime)
|
||||
// {
|
||||
// var finalVelocity = dashDirection * DashSpeed;
|
||||
// Rigidbody.linearVelocity = finalVelocity;
|
||||
//
|
||||
// elapsedTime += Time.fixedDeltaTime;
|
||||
// yield return new WaitForFixedUpdate();
|
||||
// }
|
||||
//
|
||||
// var newDashCooldown = DashCooldown - TycoonManager.Instance.TycoonStatus.PlayerDashCooldownReduction;
|
||||
// EndDash(newDashCooldown);
|
||||
// }
|
||||
//
|
||||
// public void EndDash(float dashCooldown = float.PositiveInfinity)
|
||||
// {
|
||||
// Utils.EndUniqueCoroutine(this, ref _dashInstance);
|
||||
// Rigidbody.linearVelocity = Vector3.zero;
|
||||
// IsDashing = false;
|
||||
//
|
||||
// if (float.IsPositiveInfinity(dashCooldown))
|
||||
// {
|
||||
// dashCooldown = DashCooldown;
|
||||
// }
|
||||
//
|
||||
// EventManager.InvokeDashCooldown(dashCooldown);
|
||||
// StartCoroutine(Utils.CoolDownCoroutine(dashCooldown, () => IsDashCoolDownActive = false));
|
||||
// }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
2
Assets/Scirpts/CharacterController.cs.meta
Normal file
2
Assets/Scirpts/CharacterController.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 620909d88f805ee4898b9af964a7f0e8
|
299
Assets/Scirpts/PlayerInputKeyManager.cs
Normal file
299
Assets/Scirpts/PlayerInputKeyManager.cs
Normal file
@ -0,0 +1,299 @@
|
||||
using System.Threading.Tasks;
|
||||
using DDD;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
public enum InputActionMaps
|
||||
{
|
||||
None = 0,
|
||||
UI = 1,
|
||||
Tycoon = 2,
|
||||
TycoonUi = 3,
|
||||
CombatTitle = 4,
|
||||
Combat = 5,
|
||||
CombatUi = 6
|
||||
}
|
||||
|
||||
public static class UiActions
|
||||
{
|
||||
public const string Navigate = "Navigate";
|
||||
}
|
||||
|
||||
public static class TycoonActions
|
||||
{
|
||||
public const string Move = "Move";
|
||||
public const string Dash = "Dash";
|
||||
public const string Interaction = "Interaction";
|
||||
public const string DevelopKey01 = "DevelopKey01";
|
||||
public const string OpenManualBook = "OpenManualBook";
|
||||
public const string ZoomOut = "ZoomOut";
|
||||
public const string ZoomIn = "ZoomIn";
|
||||
public const string Options = "Options";
|
||||
}
|
||||
|
||||
public static class TycoonUiActions
|
||||
{
|
||||
public const string Move = "Move";
|
||||
public const string Cancel = "Cancel";
|
||||
public const string PressQ = "PressQ";
|
||||
public const string PressR = "PressR";
|
||||
public const string PressA = "PressA";
|
||||
public const string PressD = "PressD";
|
||||
public const string PressAnyKey = "PressAnyKey";
|
||||
public const string InteractionE = "InteractionE";
|
||||
public const string PressF = "PressF";
|
||||
}
|
||||
|
||||
public class PlayerInputKeyManager : Singleton<PlayerInputKeyManager>
|
||||
{
|
||||
[SerializeField]
|
||||
private PlayerInput _currentPlayerInput;
|
||||
|
||||
public bool IsInitialized { get; private set; }
|
||||
|
||||
protected override void OnAwake()
|
||||
{
|
||||
base.OnAwake();
|
||||
|
||||
_currentPlayerInput = GetComponent<PlayerInput>();
|
||||
}
|
||||
|
||||
private async void Start()
|
||||
{
|
||||
await Initialize();
|
||||
|
||||
SceneManager.sceneLoaded += OnSceneLoaded;
|
||||
}
|
||||
|
||||
private async void OnSceneLoaded(Scene scene, LoadSceneMode mode)
|
||||
{
|
||||
await Initialize();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
SceneManager.sceneLoaded -= OnSceneLoaded;
|
||||
}
|
||||
|
||||
private async Task Initialize()
|
||||
{
|
||||
IsInitialized = false;
|
||||
await Task.Delay(1000);
|
||||
|
||||
DisableAllActionMaps();
|
||||
string currentSceneName = SceneManager.GetActiveScene().name;
|
||||
|
||||
// if (currentSceneName == SceneName.TycoonTile)
|
||||
// {
|
||||
// SwitchCurrentActionMap(InputActionMaps.TycoonUi);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
SwitchCurrentActionMap(InputActionMaps.Tycoon);
|
||||
// }
|
||||
|
||||
IsInitialized = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 현재 실행되고 있는 PlayerInput을 관리할 수 있게
|
||||
/// PlayerInput 컴포넌트를 받아와서 사용하는 경우에 필수로 호출
|
||||
/// </summary>
|
||||
/// <param name="playerInput"></param>
|
||||
public void SetCurrentPlayerInput(PlayerInput playerInput) => _currentPlayerInput = playerInput;
|
||||
|
||||
private bool IsNullCurrentPlayerInput()
|
||||
{
|
||||
if (_currentPlayerInput && _currentPlayerInput.enabled) return false;
|
||||
|
||||
Debug.Log("CurrentPlayerInput가 할당되지 않았습니다.");
|
||||
return true;
|
||||
}
|
||||
|
||||
public InputAction GetAction(InputActionMaps actionMapName, string actionName)
|
||||
{
|
||||
if (IsNullCurrentPlayerInput()) return null;
|
||||
|
||||
var actionMap = _currentPlayerInput.actions.FindActionMap(actionMapName.ToString(), true);
|
||||
if (actionMap == null)
|
||||
{
|
||||
Debug.LogError($"Action Map '{actionMapName}' not found!");
|
||||
return null;
|
||||
}
|
||||
|
||||
var action = actionMap.FindAction(actionName, true);
|
||||
if (action == null)
|
||||
{
|
||||
Debug.LogError($"Action '{actionName}' not found in Action Map '{actionMapName}'!");
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
public string GetBoundKey(InputActionMaps actionMapName, string actionName)
|
||||
{
|
||||
if (IsNullCurrentPlayerInput()) return null;
|
||||
|
||||
var actionMap = _currentPlayerInput.actions.FindActionMap(actionMapName.ToString(), true);
|
||||
if (actionMap == null)
|
||||
{
|
||||
Debug.LogError($"Action Map '{actionMapName}' not found!");
|
||||
return null;
|
||||
}
|
||||
|
||||
var action = actionMap.FindAction(actionName, true);
|
||||
if (action == null)
|
||||
{
|
||||
Debug.LogError($"Action '{actionName}' not found in Action Map '{actionMapName}'!");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 첫 번째 바인딩에서 키 이름 가져오기
|
||||
foreach (var binding in action.bindings)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(binding.path))
|
||||
{
|
||||
// 키 이름만 추출
|
||||
var key = InputControlPath.ToHumanReadableString(binding.path, InputControlPath.HumanReadableStringOptions.OmitDevice);
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
Debug.LogWarning($"No bindings found for action '{actionName}' in Action Map '{actionMapName}'.");
|
||||
return null;
|
||||
}
|
||||
|
||||
public string GetBoundKey(InputAction inputAction)
|
||||
{
|
||||
if (IsNullCurrentPlayerInput()) return null;
|
||||
|
||||
if (inputAction == null)
|
||||
{
|
||||
Debug.LogError($"Action not found'!");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 첫 번째 바인딩에서 키 이름 가져오기
|
||||
foreach (var binding in inputAction.bindings)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(binding.path))
|
||||
{
|
||||
// 키 이름만 추출
|
||||
var key = InputControlPath.ToHumanReadableString(binding.path, InputControlPath.HumanReadableStringOptions.OmitDevice);
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
Debug.LogWarning($"No bindings found for action '{inputAction}'");
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool IsCurrentActionMap(InputActionMaps inputActionMaps)
|
||||
{
|
||||
if (IsNullCurrentPlayerInput()) return false;
|
||||
|
||||
return _currentPlayerInput.currentActionMap.ToString() == inputActionMaps.ToString();
|
||||
}
|
||||
|
||||
public void SwitchCurrentActionMap(string inputActionMaps)
|
||||
{
|
||||
if (IsNullCurrentPlayerInput()) return;
|
||||
|
||||
_currentPlayerInput.SwitchCurrentActionMap(inputActionMaps);
|
||||
}
|
||||
|
||||
public void SwitchCurrentActionMap(InputActionMaps inputActionMaps)
|
||||
{
|
||||
if (IsNullCurrentPlayerInput()) return;
|
||||
|
||||
_currentPlayerInput.SwitchCurrentActionMap(inputActionMaps.ToString());
|
||||
}
|
||||
|
||||
public InputActionMap GetCurrentInputActionMap()
|
||||
{
|
||||
if (IsNullCurrentPlayerInput()) return null;
|
||||
|
||||
return _currentPlayerInput.currentActionMap;
|
||||
}
|
||||
|
||||
public void EnableCurrentPlayerInput()
|
||||
{
|
||||
if (!_currentPlayerInput) return;
|
||||
|
||||
_currentPlayerInput.enabled = true;
|
||||
}
|
||||
|
||||
public void DisableCurrentPlayerInput()
|
||||
{
|
||||
if (IsNullCurrentPlayerInput()) return;
|
||||
|
||||
_currentPlayerInput.enabled = false;
|
||||
}
|
||||
|
||||
public void DisableAllActionMaps()
|
||||
{
|
||||
if (IsNullCurrentPlayerInput()) return;
|
||||
|
||||
foreach (var element in _currentPlayerInput.actions.actionMaps)
|
||||
{
|
||||
element.Disable();
|
||||
}
|
||||
}
|
||||
|
||||
public void DisableAllActionsExcept(string exceptActionName)
|
||||
{
|
||||
if (IsNullCurrentPlayerInput()) return;
|
||||
|
||||
var exceptAction = _currentPlayerInput.currentActionMap.FindAction(exceptActionName);
|
||||
|
||||
foreach (var action in _currentPlayerInput.currentActionMap.actions)
|
||||
{
|
||||
if (action != exceptAction)
|
||||
{
|
||||
action.Disable();
|
||||
}
|
||||
else
|
||||
{
|
||||
action.Enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void EnableAllActionsMaps()
|
||||
{
|
||||
if (IsNullCurrentPlayerInput()) return;
|
||||
|
||||
foreach (var action in _currentPlayerInput.actions)
|
||||
{
|
||||
action.Enable();
|
||||
}
|
||||
}
|
||||
|
||||
public void EnableAction(string actionName)
|
||||
{
|
||||
if (IsNullCurrentPlayerInput()) return;
|
||||
|
||||
var action = _currentPlayerInput.currentActionMap.FindAction(actionName);
|
||||
if (action == null)
|
||||
{
|
||||
Debug.Log($"현재 Action Map인 {_currentPlayerInput.currentActionMap}에는 {actionName} Action이 존재하지 않습니다");
|
||||
return;
|
||||
}
|
||||
|
||||
action.Enable();
|
||||
}
|
||||
|
||||
public void DisableAction(string actionName)
|
||||
{
|
||||
if (IsNullCurrentPlayerInput()) return;
|
||||
|
||||
var action = _currentPlayerInput.currentActionMap.FindAction(actionName);
|
||||
if (action == null)
|
||||
{
|
||||
Debug.Log($"현재 Action Map인 {_currentPlayerInput.currentActionMap}에는 {actionName} Action이 존재하지 않습니다");
|
||||
return;
|
||||
}
|
||||
|
||||
action.Disable();
|
||||
}
|
||||
}
|
2
Assets/Scirpts/PlayerInputKeyManager.cs.meta
Normal file
2
Assets/Scirpts/PlayerInputKeyManager.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3a9c6e7027b3d944ae69e5e7ccc7627
|
Loading…
Reference in New Issue
Block a user