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(); _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(); 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 } }