전투플레이어 로직 전체 수정

+ 이벤트 구독 방식에서 인터페이스 형식으로 변경
This commit is contained in:
Nam Tae Gun 2024-06-17 06:29:06 +09:00
parent 8789f7a2de
commit 0cdf1aa3a8
33 changed files with 569 additions and 430 deletions

View File

@ -1875,8 +1875,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 179524db1ad20f44a8374fb83bb46495, type: 3}
m_Name:
m_EditorClassIdentifier:
SwitchMapsOpened: 4
SwitchMapsClosed: 3
SwitchMapsOpened: 5
SwitchMapsClosed: 4
--- !u!1 &473280139
GameObject:
m_ObjectHideFlags: 0
@ -19658,8 +19658,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: a61520d3b25b0244685023b48f19cdee, type: 3}
m_Name:
m_EditorClassIdentifier:
SwitchMapsOpened: 4
SwitchMapsClosed: 3
SwitchMapsOpened: 5
SwitchMapsClosed: 4
SortingDropdown: {fileID: 5518631981308585485}
CurrentWeight: {fileID: 5638844555988528261}
InstantiateLocation: {fileID: 2478437734520413558}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections;
using Sirenix.OdinInspector;
using UnityEngine;
namespace BlueWater
@ -10,6 +11,7 @@ namespace BlueWater
#region Variables
// Components
[SerializeField]
private Animator _animator;
#endregion
@ -27,7 +29,8 @@ namespace BlueWater
// Initialize methods
#region Initialize Methdos
public void InitializeComponents()
[Button("컴포넌트 초기화")]
private void InitializeComponents()
{
_animator = GetComponentInChildren<Animator>();
}

View File

@ -0,0 +1,152 @@
using System.Collections.Generic;
using BlueWater.Interfaces;
using BlueWater.Uis;
using UnityEngine;
namespace BlueWater
{
public class CombatSkillController : MonoBehaviour, ISkillHandler
{
// Variables
#region Variables
// Components
private IDashable _dashable;
private IComboAttackable _comboAttackable;
private IStunnable _stunnable;
// Variables
[field: SerializeField]
public List<BaseSkill> Skills { get; private set; }
public Dictionary<string, BaseSkill> SkillInstances { get; private set; }
public BaseSkill CurrentActivatingSkill { get; private set; }
public bool IsSkillEnabled { get; private set; } = true;
public bool IsActivatingSkill { get; private set; }
#endregion
// Unity events
#region Unity events
private void Awake()
{
InitializeComponents();
}
private void Start()
{
Initialize();
}
private void OnDestroy()
{
if (SkillInstances == null) return;
foreach (var element in SkillInstances.Values)
{
if (!element) continue;
Destroy(element.gameObject);
}
}
#endregion
// Initialize methods
#region Initialize methods
private void InitializeComponents()
{
_dashable = GetComponent<IDashable>();
_comboAttackable = GetComponent<IComboAttackable>();
_stunnable = GetComponent<IStunnable>();
}
private void Initialize()
{
SkillInstances = new Dictionary<string, BaseSkill>(Skills.Count);
foreach (var element in Skills)
{
var newSkill = Instantiate(element);
newSkill.Initialize(gameObject);
SkillInstances.Add(newSkill.SkillName, newSkill);
}
CurrentActivatingSkill = SkillInstances[Skills[0].SkillName];
CombatUiManager.Instance.CombatSkillUi.ResetSkillUi();
}
#endregion
// Methods
#region Methods
public void EnableSkill() => IsSkillEnabled = true;
public void DisableSkill() => IsSkillEnabled = false;
public bool HasSkill(string skillName = null)
{
if (string.IsNullOrEmpty(skillName)) skillName = CurrentActivatingSkill.SkillName;
if (SkillInstances.ContainsKey(skillName)) return true;
Debug.Log($"{skillName}(이)라는 스킬을 찾을 수 없습니다.");
return false;
}
public bool CanSkill(string skillName = null)
{
if (string.IsNullOrEmpty(skillName)) skillName = CurrentActivatingSkill.SkillName;
if (!IsSkillEnabled || IsActivatingSkill) return false;
var isDashing = _dashable?.IsDashing ?? false;
var isAttacking = _comboAttackable?.CurrentComboAttackCount > 0;
var isStunned = _stunnable?.IsStunned ?? false;
if (isDashing || isAttacking || isStunned) return false;
return SkillInstances[skillName].CanSkill();
}
/// <summary>
/// HasSkill()만 확인하고 스킬을 강제로 사용
/// </summary>
public void ActivateSkill(string skillName = null)
{
if (string.IsNullOrEmpty(skillName)) skillName = CurrentActivatingSkill.SkillName;
if (!HasSkill(skillName)) return;
IsSkillEnabled = false;
IsActivatingSkill = true;
CurrentActivatingSkill = SkillInstances[skillName];
CurrentActivatingSkill.ActivateSkill(EndSkill);
}
/// <summary>
/// HasSkill(), CanSkill()를 모두 확인하고 스킬을 사용하기까지 모든 과정
/// </summary>
public void TryActivateSkill(string skillName = null)
{
if (string.IsNullOrEmpty(skillName)) skillName = CurrentActivatingSkill.SkillName;
if (!CanSkill(skillName)) return;
ActivateSkill(skillName);
}
private void EndSkill()
{
IsSkillEnabled = true;
IsActivatingSkill = false;
CombatUiManager.Instance.CombatSkillUi.CoolDown(CurrentActivatingSkill.Cooldown);
}
#endregion
}
}

View File

@ -30,10 +30,10 @@ namespace BlueWater.Enemies.Bosses
[field: SerializeField]
public int CurrentHealthPoint { get; private set; }
[SerializeField]
private float _damageInterval = 0.1f;
public bool IsInvincible { get; private set; }
private bool _enableTakeDamage = true;
[field: SerializeField]
public float InvincibilityDuration { get; private set; } = 0.1f;
// 효과 설정
[Title("효과 설정")]
@ -68,7 +68,7 @@ namespace BlueWater.Enemies.Bosses
{
InitializeComponent();
_flashWhiteWaitTime = new WaitForSeconds(_damageInterval);
_flashWhiteWaitTime = new WaitForSeconds(InvincibilityDuration);
_fieldBossHealthPointUi = CombatUiManager.Instance.FieldBossHealthPointUi;
}
@ -104,25 +104,18 @@ namespace BlueWater.Enemies.Bosses
SetCurrentHealthPoint(MaxHealthPoint);
}
// Events methods
public void HandleEnableTakeDamage() => _enableTakeDamage = true;
public void HandleDisableTakeDamage() => _enableTakeDamage = false;
// Methods
public void SetCurrentHealthPoint(int changedHealthPoint)
{
CurrentHealthPoint = changedHealthPoint;
OnHealthChanged?.Invoke(changedHealthPoint);
}
public bool CanDamage()
{
return _enableTakeDamage;
}
public bool CanDamage() => !IsInvincible;
public void TakeDamage(int damageAmount)
{
HandleDisableTakeDamage();
IsInvincible = true;
var changeHp = Mathf.Max(CurrentHealthPoint - damageAmount, 0);
SetCurrentHealthPoint(changeHp);
@ -150,7 +143,7 @@ namespace BlueWater.Enemies.Bosses
AudioManager.Instance.PlaySfx(_attackedSfxName);
}
Utils.StartUniqueCoroutine(this, ref _damageIntervalCoroutine, Utils.CoolDownCoroutine(_damageInterval, EndDamageIntervalCoroutine));
Utils.StartUniqueCoroutine(this, ref _damageIntervalCoroutine, Utils.CoolDownCoroutine(InvincibilityDuration, EndDamageIntervalCoroutine));
}
public void TryTakeDamage(int damageAmount)
@ -188,8 +181,8 @@ namespace BlueWater.Enemies.Bosses
private void EndDamageIntervalCoroutine()
{
IsInvincible = false;
Utils.EndUniqueCoroutine(this, ref _damageIntervalCoroutine);
HandleEnableTakeDamage();
}
}
}

View File

@ -14,7 +14,8 @@ namespace BlueWater.Enemies.Bosses.SandMole
[Title("기절 효과")]
[SerializeField]
private ParticleSystem _stunParticle;
public bool IsStunEnabled { get; private set; } = true;
public bool IsStunned { get; private set; }
private Coroutine _stunCoolDownCoroutine;
@ -22,8 +23,12 @@ namespace BlueWater.Enemies.Bosses.SandMole
#endregion
// Stun
public bool CanStun() => IsStunEnabled;
public void Stun(float duration)
{
if (!CanStun()) return;
IsStunned = true;
if (_stunParticle)
{

View File

@ -1,31 +1,41 @@
using System;
using System.Collections;
using BlueWater.Audios;
using BlueWater.Interfaces;
using BlueWater.Utility;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.InputSystem;
namespace BlueWater.Players.Combat
{
public class CombatAttacker : MonoBehaviour
public class CombatAttacker : MonoBehaviour, IComboAttackable
{
// Variables
#region Variables
// Components
[SerializeField]
private Rigidbody _rigidbody;
[SerializeField]
private AnimationController _animationController;
// Interfaces
private IPhysicMovable _iPhysicMovable;
private IDashable _dashable;
private ISkillHandler _skillHandler;
private IStunnable _stunnable;
// ComboAttack
[field: SerializeField, Range(1, 21), Tooltip("한 번에 공격 가능한 개체 수")]
public int MaxHitCount { get; set; } = 10;
public int MaxHitCount { get; private set; } = 10;
[field: SerializeField]
public ComboAttack[] ComboAttacks { get; set; } = new ComboAttack[2];
public ComboAttack[] ComboAttacks { get; private set; } = new ComboAttack[2];
public bool IsAttackEnabled { get; private set; } = true;
public bool IsComboAttackPossible { get; private set; }
public bool IsComboAttacking { get; private set; }
private int _currentComboAttackCount;
public int CurrentComboAttackCount
@ -37,18 +47,13 @@ namespace BlueWater.Players.Combat
_animationController.SetAnimationParameter("comboAttackCount", CurrentComboAttackCount);
}
}
public bool IsComboAttackPossible { get; set; }
public bool IsComboAttacking { get; set; }
public Collider[] HitColliders { get; set; }
private bool _enableAttack = true;
public Collider[] HitColliders { get; private set; }
[field: SerializeField]
public LayerMask TargetLayer { get; private set; }
[SerializeField]
private LayerMask _mouseClickLayer;
[field: SerializeField]
public LayerMask MouseClickLayer { get; private set; }
// Particles
[SerializeField]
@ -62,15 +67,16 @@ namespace BlueWater.Players.Combat
private Coroutine _firstComboAttackCoroutine;
private Coroutine _secondComboAttackCoroutine;
// Events
public event Action OnStartAttack;
public event Action OnEndAttack;
#endregion
// Unity events
#region Unity events
private void Awake()
{
InitializeComponents();
}
private void Start()
{
HitColliders = new Collider[MaxHitCount];
@ -81,33 +87,44 @@ namespace BlueWater.Players.Combat
// Initialize
#region Initialize
public void InitializeComponents(Rigidbody rigidbody, AnimationController animationController, IPhysicMovable iPhysicMovable)
[Button("컴포넌트 초기화")]
private void InitializeComponents()
{
_rigidbody = rigidbody;
_animationController = animationController;
_iPhysicMovable = iPhysicMovable;
_rigidbody = GetComponent<Rigidbody>();
_animationController = GetComponent<AnimationController>();
_iPhysicMovable = GetComponent<IPhysicMovable>();
_dashable = GetComponent<IDashable>();
_skillHandler = GetComponent<ISkillHandler>();
_stunnable = GetComponent<IStunnable>();
}
#endregion
// Methods
#region Methods
// Event methods
public void HandleEnableAttack() => _enableAttack = true;
public void HandleDisableAttack() => _enableAttack = false;
public void HandleDashInAttack()
public bool CanAttack()
{
if (CurrentComboAttackCount > 0)
if (!IsAttackEnabled || CurrentComboAttackCount == 2) return false;
var isActivatingSkill = _skillHandler?.IsActivatingSkill ?? false;
var isStunned = _stunnable?.IsStunned ?? false;
if (isActivatingSkill || isStunned) return false;
var isDashing = _dashable?.IsDashing ?? false;
if (isDashing)
{
EndComboAttack();
_dashable.EndDash();
}
}
public void HandleAttack(bool usedMouseAttack)
return true;
}
public void Attack(bool usedMouseAttack)
{
if (!_enableAttack || CurrentComboAttackCount == 2) return;
if (!CanAttack()) return;
if (CurrentComboAttackCount == 1 && IsComboAttackPossible)
{
@ -126,27 +143,25 @@ namespace BlueWater.Players.Combat
Utils.StartUniqueCoroutine(this, ref _firstComboAttackCoroutine, FirstComboAttackCoroutine());
}
// Methods
private void UseMouseAttack()
{
var mousePos = Mouse.current.position.ReadValue();
var ray = CombatCameraManager.Instance.MainCamera.ScreenPointToRay(mousePos);
if (!Physics.Raycast(ray, out var hit, float.MaxValue, _mouseClickLayer))
if (!Physics.Raycast(ray, out var hit, float.MaxValue, MouseClickLayer))
{
EndComboAttack();
EndAttack();
return;
}
var attackDirection = (hit.point - _rigidbody.position).normalized;
attackDirection.y = 0f;
_iPhysicMovable.CurrentDirection = attackDirection;
_iPhysicMovable.SetCurrentDirection(attackDirection);
}
private IEnumerator FirstComboAttackCoroutine()
{
OnStartAttack?.Invoke();
CurrentComboAttackCount = 1;
var animationStarted = false;
@ -155,7 +170,7 @@ namespace BlueWater.Players.Combat
if (!animationStarted)
{
EndComboAttack();
EndAttack();
yield break;
}
@ -184,7 +199,7 @@ namespace BlueWater.Players.Combat
}
else
{
EndComboAttack();
EndAttack();
}
}
@ -200,7 +215,7 @@ namespace BlueWater.Players.Combat
if (!animationStarted)
{
EndComboAttack();
EndAttack();
yield break;
}
@ -222,7 +237,7 @@ namespace BlueWater.Players.Combat
yield return new WaitForFixedUpdate();
}
EndComboAttack();
EndAttack();
}
private void DoDamage(int comboAttackCount, Vector3 attackDirection)
@ -254,7 +269,7 @@ namespace BlueWater.Players.Combat
}
}
public void EndComboAttack()
public void EndAttack()
{
Utils.EndUniqueCoroutine(this, ref _firstComboAttackCoroutine);
Utils.EndUniqueCoroutine(this, ref _secondComboAttackCoroutine);
@ -263,7 +278,6 @@ namespace BlueWater.Players.Combat
IsComboAttacking = false;
IsComboAttackPossible = false;
_animationController.ResetAnimationSpeed();
OnEndAttack?.Invoke();
}
#endregion

View File

@ -1,5 +1,6 @@
using System;
using BlueWater.Uis;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.InputSystem;
@ -11,22 +12,38 @@ namespace BlueWater.Players.Combat
#region variables
// Components
[SerializeField]
private PlayerInput _playerInput;
// Events
public event Action<Vector2> OnMoveInputReceived;
public event Action OnDashInputReceived;
public event Action<bool> OnAttackInputReceived;
public event Action OnActivateMainSkillInputReceived;
public event Action<string> OnActivateMainSkillInputReceived;
#endregion
private void Awake()
{
InitializeComponents();
}
private void Start()
{
Initialize();
}
// Initialize methods
#region Initialize methods
public void InitializeComponents(PlayerInput playerInput)
[Button("컴포넌트 초기화")]
private void InitializeComponents()
{
_playerInput = GetComponent<PlayerInput>();
}
private void Initialize()
{
_playerInput = playerInput;
_playerInput.enabled = true;
PlayerInputKeyManager.Instance.SetCurrentPlayerInput(_playerInput);
PlayerInputKeyManager.Instance.SwitchCurrentActionMap(InputActionMaps.Combat);
@ -78,7 +95,7 @@ namespace BlueWater.Players.Combat
{
if (context.performed)
{
OnActivateMainSkillInputReceived?.Invoke();
OnActivateMainSkillInputReceived?.Invoke(null);
}
}

View File

@ -1,8 +1,8 @@
using System;
using System.Collections;
using BlueWater.Audios;
using BlueWater.Interfaces;
using BlueWater.Utility;
using Sirenix.OdinInspector;
using UnityEngine;
namespace BlueWater.Players.Combat
@ -13,21 +13,32 @@ namespace BlueWater.Players.Combat
#region Variables
// Components
[field: SerializeField]
public Rigidbody Rigidbody { get; private set; }
[SerializeField]
private Transform _visualLook;
[SerializeField]
private AnimationController _animationController;
private IComboAttackable _comboAttackable;
private ISkillHandler _skillHandler;
private IStunnable _stunnable;
// Move
[field: SerializeField, Range(1f, 10f), Tooltip("이동 속도")]
public float MoveSpeed { get; private set; } = 7f;
public bool EnableMove { get; private set; } = true;
public float MoveSpeedCoefficient { get; private set; }= 1f;
public bool IsMoveEnabled { get; private set; } = true;
private bool _isMoving;
public bool IsMoving
{
get => _isMoving;
set
private set
{
_isMoving = value;
_animationController.SetAnimationParameter("isMoving", _isMoving);
@ -40,7 +51,7 @@ namespace BlueWater.Players.Combat
public Vector3 CurrentDirection
{
get => _currentDirection;
set
private set
{
if (value == Vector3.zero) return;
@ -51,7 +62,6 @@ namespace BlueWater.Players.Combat
}
private float _finalSpeed;
private float _moveSpeedCoefficient = 1f;
// Dash
[field: SerializeField, Range(1f, 50f), Tooltip("대쉬 속도")]
@ -63,7 +73,7 @@ namespace BlueWater.Players.Combat
[field: SerializeField, Range(0f, 5f), Tooltip("대쉬 쿨타임")]
public float DashCooldown { get; private set; } = 0.5f;
public bool EnableDash { get; private set; } = true;
public bool IsDashEnabled { get; private set; } = true;
private bool _isDashing;
public bool IsDashing
@ -80,15 +90,16 @@ namespace BlueWater.Players.Combat
private Coroutine _dashCoroutine;
// Events
public event Action OnStartDash;
public event Action OnEndDash;
#endregion
// Unity events
#region Unity events
private void Awake()
{
InitializeComponents();
}
private void Update()
{
FlipVisualLook();
@ -98,7 +109,7 @@ namespace BlueWater.Players.Combat
{
if (!CanMove()) return;
ApplyMovement();
Move();
}
#endregion
@ -106,11 +117,16 @@ namespace BlueWater.Players.Combat
// Initialize Methods
#region Initialize Methods
public void InitializeComponents(Rigidbody rigidbody, Transform visualLook, AnimationController animationController)
[Button("컴포넌트 초기화")]
private void InitializeComponents()
{
Rigidbody = rigidbody;
_visualLook = visualLook;
_animationController = animationController;
Rigidbody = GetComponent<Rigidbody>();
_visualLook = transform.Find("VisualLook");
_animationController = GetComponent<AnimationController>();
_comboAttackable = GetComponent<IComboAttackable>();
_skillHandler = GetComponent<ISkillHandler>();
_stunnable = GetComponent<IStunnable>();
}
#endregion
@ -119,38 +135,14 @@ namespace BlueWater.Players.Combat
#region Methods
// Event methods
public void HandleInputMovement(Vector2 movementInput)
public void InputMovement(Vector2 movementInput)
{
_inputDirection = new Vector3(movementInput.x, 0, movementInput.y).normalized;
}
public void HandleAttackInDash()
{
if (IsDashing)
{
EndDash(DashCooldown);
}
}
public void HandleMoveSpeedCoefficient(float value) => _moveSpeedCoefficient = value;
public void HandleResetMoveSpeedCoefficient() => _moveSpeedCoefficient = 1f;
public void HandleEnableMove() => EnableMove = true;
public void HandleDisableMove() => EnableMove = false;
public void HandleEnableDash() => EnableDash = true;
public void HandleDisableDash() => EnableDash = false;
public void HandleEnableMoveAndDash()
{
EnableMove = true;
EnableDash = true;
}
public void HandleDisableMoveAndDash()
{
EnableMove = false;
EnableDash = false;
}
public void SetMoveSpeedCoefficient(float value) => MoveSpeedCoefficient = value;
public void ResetMoveSpeedCoefficient() => MoveSpeedCoefficient = 1f;
public void SetCurrentDirection(Vector3 normalDirection) => CurrentDirection = normalDirection;
// Methods
private void FlipVisualLook()
@ -168,34 +160,50 @@ namespace BlueWater.Players.Combat
// Move
public bool CanMove()
{
return EnableMove && !IsDashing;
if (!IsMoveEnabled || IsDashing) return false;
var isActivatingSkill = _skillHandler?.IsActivatingSkill ?? false;
var isStunned = _stunnable?.IsStunned ?? false;
var isAttacking = _comboAttackable?.CurrentComboAttackCount > 0;
return !isActivatingSkill && !isStunned && !isAttacking;
}
public void AddForce(Vector3 force, ForceMode forceMode)
{
if (_isDashing) return;
if (IsDashing) return;
Rigidbody.AddForce(force, forceMode);
}
private void ApplyMovement()
public void Move()
{
CurrentDirection = _inputDirection;
IsMoving = _inputDirection != Vector3.zero;
// var finalVelocity = _inputDirection * (MoveSpeed * _moveSpeedCoefficient);
// Rigidbody.linearVelocity = finalVelocity;
var finalVelocity = _inputDirection * (MoveSpeed * _moveSpeedCoefficient * Time.deltaTime);
var finalVelocity = _inputDirection * (MoveSpeed * MoveSpeedCoefficient * Time.deltaTime);
Rigidbody.MovePosition(transform.position + finalVelocity);
}
// Dash
public bool CanDash()
{
return EnableMove && EnableDash && !IsDashing && !IsDashCoolDownActive;
if (!IsDashEnabled || IsDashing || IsDashCoolDownActive) return false;
var isActivatingSkill = _skillHandler?.IsActivatingSkill ?? false;
var isStunned = _stunnable?.IsStunned ?? false;
if (isActivatingSkill || isStunned) return false;
var isAttacking = _comboAttackable?.CurrentComboAttackCount > 0;
if (isAttacking)
{
_comboAttackable.EndAttack();
}
return true;
}
public void HandleDash()
public void Dash()
{
if (!CanDash()) return;
@ -204,7 +212,6 @@ namespace BlueWater.Players.Combat
private IEnumerator DashCoroutine()
{
OnStartDash?.Invoke();
IsDashing = true;
IsDashCoolDownActive = true;
@ -225,25 +232,26 @@ namespace BlueWater.Players.Combat
while (_animationController.IsComparingCurrentAnimation("DashState") &&
_animationController.GetCurrentAnimationNormalizedTime() < 1f)
{
//var finalVelocity = rb.position + dashDirection * (dashSpeed * Time.fixedDeltaTime);
//rb.MovePosition(finalVelocity);
var finalVelocity = transform.position + dashDirection * (DashSpeed * Time.fixedDeltaTime);
Rigidbody.MovePosition(finalVelocity);
var finalVelocity = dashDirection * DashSpeed;
Rigidbody.linearVelocity = finalVelocity;
yield return new WaitForFixedUpdate();
}
EndDash(DashCooldown);
}
public void EndDash(float dashCooldown)
public void EndDash(float dashCooldown = float.PositiveInfinity)
{
Utils.EndUniqueCoroutine(this, ref _dashCoroutine);
Rigidbody.linearVelocity = Vector3.zero;
_animationController.ResetAnimationSpeed();
OnEndDash?.Invoke();
IsDashing = false;
if (float.IsPositiveInfinity(dashCooldown))
{
dashCooldown = DashCooldown;
}
StartCoroutine(Utils.CoolDownCoroutine(dashCooldown, () => IsDashCoolDownActive = false));
}

View File

@ -33,21 +33,21 @@ namespace BlueWater.Players.Combat
[field: SerializeField]
public Animator Animator { get; private set; }
[field: SerializeField]
public PlayerHealthPoint PlayerHealthPoint { get; private set; }
[field: SerializeField]
public AnimationController AnimationController { get; private set; }
[field: SerializeField]
public CombatInput CombatInput { get; private set; }
[field: SerializeField]
public CombatMovement CombatMovement { get; private set; }
[field: SerializeField]
public AnimationController AnimationController { get; private set; }
[field: SerializeField]
public CombatAttacker CombatAttacker { get; private set; }
[field: SerializeField]
public PlayerHealthPoint PlayerHealthPoint { get; private set; }
[field: SerializeField]
public CombatSkillController CombatSkillController { get; private set; }
@ -62,7 +62,6 @@ namespace BlueWater.Players.Combat
private void Awake()
{
InitializeComponents();
InitializeChileComponents();
}
private void Start()
@ -96,24 +95,15 @@ namespace BlueWater.Players.Combat
Animator = VisualLook.GetComponent<Animator>();
HitBoxCollider = transform.Find("HitBox").GetComponent<BoxCollider>();
PlayerHealthPoint = GetComponent<PlayerHealthPoint>();
AnimationController = GetComponent<AnimationController>();
CombatInput = GetComponent<CombatInput>();
CombatMovement = GetComponent<CombatMovement>();
AnimationController = GetComponent<AnimationController>();
CombatAttacker = GetComponent<CombatAttacker>();
PlayerHealthPoint = GetComponent<PlayerHealthPoint>();
CombatSkillController = GetComponent<CombatSkillController>();
CombatStatus = GetComponent<CombatStatus>();
}
private void InitializeChileComponents()
{
CombatInput.InitializeComponents(PlayerInput);
CombatMovement.InitializeComponents(Rigidbody, VisualLook, AnimationController);
CombatAttacker.InitializeComponents(Rigidbody, AnimationController, CombatMovement);
PlayerHealthPoint.InitializeComponents(SpriteRenderer);
CombatStatus.InitializeComponents(SpriteRenderer);
}
#endregion
// Methods
@ -122,103 +112,25 @@ namespace BlueWater.Players.Combat
private void SubscribeEvents()
{
// Input
CombatInput.OnMoveInputReceived += CombatMovement.HandleInputMovement;
CombatInput.OnDashInputReceived += CombatMovement.HandleDash;
CombatInput.OnAttackInputReceived += CombatAttacker.HandleAttack;
CombatInput.OnActivateMainSkillInputReceived += CombatSkillController.HandleMainSkill;
// Movement
CombatMovement.OnStartDash += CombatAttacker.HandleDashInAttack;
CombatMovement.OnStartDash += CombatSkillController.HandleDisableSkill;
CombatMovement.OnStartDash += PlayerHealthPoint.HandleDisableTakeDamage;
CombatMovement.OnStartDash += CombatStatus.HandleCanNotApplyStatusEffect;
CombatMovement.OnEndDash += CombatSkillController.HandleEnableSkill;
CombatMovement.OnEndDash += PlayerHealthPoint.HandleEnableTakeDamage;
CombatMovement.OnEndDash += CombatStatus.HandleCanApplyStatusEffect;
// Attacker
CombatAttacker.OnStartAttack += CombatMovement.HandleAttackInDash;
CombatAttacker.OnStartAttack += CombatMovement.HandleDisableMove;
CombatAttacker.OnStartAttack += CombatSkillController.HandleDisableSkill;
CombatAttacker.OnEndAttack += CombatMovement.HandleEnableMove;
CombatAttacker.OnEndAttack += CombatSkillController.HandleEnableSkill;
CombatInput.OnMoveInputReceived += CombatMovement.InputMovement;
CombatInput.OnDashInputReceived += CombatMovement.Dash;
CombatInput.OnAttackInputReceived += CombatAttacker.Attack;
CombatInput.OnActivateMainSkillInputReceived += CombatSkillController.TryActivateSkill;
// PlayerHealthPoint
PlayerHealthPoint.OnDead += Die;
// SkillController
CombatSkillController.OnStartSkill += CombatMovement.HandleDisableMoveAndDash;
CombatSkillController.OnStartSkill += CombatAttacker.HandleDisableAttack;
CombatSkillController.OnStartSkill += PlayerHealthPoint.HandleDisableTakeDamage;
CombatSkillController.OnEndSkill += CombatMovement.HandleEnableMoveAndDash;
CombatSkillController.OnEndSkill += CombatAttacker.HandleEnableAttack;
CombatSkillController.OnEndSkill += PlayerHealthPoint.HandleEnableTakeDamage;
// Status
CombatStatus.OnStartStun += CombatMovement.HandleDisableMoveAndDash;
CombatStatus.OnStartStun += CombatAttacker.HandleDisableAttack;
CombatStatus.OnStartStun += CombatSkillController.HandleDisableSkill;
CombatStatus.OnEndStun += CombatMovement.HandleEnableMoveAndDash;
CombatStatus.OnEndStun += CombatAttacker.HandleEnableAttack;
CombatStatus.OnEndStun += CombatSkillController.HandleEnableSkill;
CombatStatus.OnStartSlowMoveSpeed += CombatMovement.HandleMoveSpeedCoefficient;
CombatStatus.OnEndSlowMoveSpeed += CombatMovement.HandleResetMoveSpeedCoefficient;
}
private void UnSubscribeEvents()
{
// Input
CombatInput.OnMoveInputReceived -= CombatMovement.HandleInputMovement;
CombatInput.OnDashInputReceived -= CombatMovement.HandleDash;
CombatInput.OnAttackInputReceived -= CombatAttacker.HandleAttack;
CombatInput.OnActivateMainSkillInputReceived -= CombatSkillController.HandleMainSkill;
// Movement
CombatMovement.OnStartDash -= CombatAttacker.HandleDashInAttack;
CombatMovement.OnStartDash -= CombatSkillController.HandleDisableSkill;
CombatMovement.OnStartDash -= PlayerHealthPoint.HandleDisableTakeDamage;
CombatMovement.OnStartDash -= CombatStatus.HandleCanNotApplyStatusEffect;
CombatMovement.OnEndDash -= CombatSkillController.HandleEnableSkill;
CombatMovement.OnEndDash -= PlayerHealthPoint.HandleEnableTakeDamage;
CombatMovement.OnEndDash -= CombatStatus.HandleCanApplyStatusEffect;
// Attacker
CombatAttacker.OnStartAttack -= CombatMovement.HandleAttackInDash;
CombatAttacker.OnStartAttack -= CombatMovement.HandleDisableMove;
CombatAttacker.OnStartAttack -= CombatSkillController.HandleDisableSkill;
CombatAttacker.OnEndAttack -= CombatMovement.HandleEnableMove;
CombatAttacker.OnEndAttack -= CombatSkillController.HandleEnableSkill;
CombatInput.OnMoveInputReceived -= CombatMovement.InputMovement;
CombatInput.OnDashInputReceived -= CombatMovement.Dash;
CombatInput.OnAttackInputReceived -= CombatAttacker.Attack;
CombatInput.OnActivateMainSkillInputReceived -= CombatSkillController.TryActivateSkill;
// PlayerHealthPoint
PlayerHealthPoint.OnDead -= Die;
// SkillController
CombatSkillController.OnStartSkill -= CombatMovement.HandleDisableMoveAndDash;
CombatSkillController.OnStartSkill -= CombatAttacker.HandleDisableAttack;
CombatSkillController.OnStartSkill -= PlayerHealthPoint.HandleDisableTakeDamage;
CombatSkillController.OnEndSkill -= CombatMovement.HandleEnableMoveAndDash;
CombatSkillController.OnEndSkill -= CombatAttacker.HandleEnableAttack;
CombatSkillController.OnEndSkill -= PlayerHealthPoint.HandleEnableTakeDamage;
// Status
CombatStatus.OnStartStun -= CombatMovement.HandleDisableMoveAndDash;
CombatStatus.OnStartStun -= CombatAttacker.HandleDisableAttack;
CombatStatus.OnStartStun -= CombatSkillController.HandleDisableSkill;
CombatStatus.OnEndStun -= CombatMovement.HandleEnableMoveAndDash;
CombatStatus.OnEndStun -= CombatAttacker.HandleEnableAttack;
CombatStatus.OnEndStun -= CombatSkillController.HandleEnableSkill;
CombatStatus.OnStartSlowMoveSpeed -= CombatMovement.HandleMoveSpeedCoefficient;
CombatStatus.OnEndSlowMoveSpeed -= CombatMovement.HandleResetMoveSpeedCoefficient;
}
private void Die()
@ -259,9 +171,6 @@ namespace BlueWater.Players.Combat
Destroy(gameObject);
CombatUiManager.Instance.GameOverPopupUi.Open(CombatUiManager.Instance.PopupUiList);
}
// Wrapping methods
public LayerMask TargetLayer => CombatAttacker.TargetLayer;
#endregion
}

View File

@ -1,92 +0,0 @@
using System;
using BlueWater.Uis;
using UnityEngine;
namespace BlueWater.Players.Combat
{
public class CombatSkillController : MonoBehaviour
{
// Variables
#region Variables
// Components
[SerializeField]
private BaseSkill _mainSkillPrefab;
private BaseSkill _instantiateMainSkill;
// Variables
private bool _enableSkill = true;
private bool _isActivatingSkill;
// Events
public event Action OnStartSkill;
public event Action OnEndSkill;
#endregion
// Unity events
#region Unity events
private void Start()
{
InitSkill();
}
private void OnDestroy()
{
if (_instantiateMainSkill)
{
Destroy(_instantiateMainSkill.gameObject);
}
}
#endregion
// Initialize methods
#region Initialize methods
private void InitSkill()
{
_instantiateMainSkill = Instantiate(_mainSkillPrefab);
_instantiateMainSkill.Initialize(gameObject);
CombatUiManager.Instance.CombatSkillUi.ResetSkillUi();
}
#endregion
// Methods
#region Methods
// Events methods
public void HandleEnableSkill() => _enableSkill = true;
public void HandleDisableSkill() => _enableSkill = false;
public void HandleMainSkill()
{
if (!CanSkill()) return;
OnStartSkill?.Invoke();
_enableSkill = false;
_isActivatingSkill = true;
_instantiateMainSkill.ActivateSkill(EndSkill);
}
// Methods
private bool CanSkill()
{
if (!_enableSkill || _isActivatingSkill) return false;
return _instantiateMainSkill.CanSkill();
}
private void EndSkill()
{
OnEndSkill?.Invoke();
_isActivatingSkill = false;
_enableSkill = true;
}
#endregion
}
}

View File

@ -1,4 +1,3 @@
using System;
using BlueWater.Interfaces;
using BlueWater.Utility;
using Sirenix.OdinInspector;
@ -12,15 +11,22 @@ namespace BlueWater.Players.Combat
#region Variables
// Components
[SerializeField]
private SpriteRenderer _spriteRenderer;
private IPhysicMovable _physicMovable;
private IDashable _dashable;
private IComboAttackable _comboAttackable;
private ISkillHandler _skillHandler;
// Stun
[Title("기절 효과")]
[SerializeField]
private ParticleSystem _stunParticle;
public bool IsStunEnabled { get; private set; } = true;
public bool IsStunned { get; private set; }
private Coroutine _stunCoolDownCoroutine;
// Slow
@ -29,29 +35,38 @@ namespace BlueWater.Players.Combat
[SerializeField]
private Color _slowEffectColor;
public bool IsSlowMoveEnabled { get; private set; } = true;
public bool IsSlowedMoveSpeed { get; private set; }
private Coroutine _slowMoveSpeedCoolDownCoroutine;
// Variables
private bool _canApplyStatusEffect = true;
// Events
public event Action OnStartStun;
public event Action OnEndStun;
public event Action<float> OnStartSlowMoveSpeed;
public event Action OnEndSlowMoveSpeed;
// Hashes
private static readonly int _colorHash = Shader.PropertyToID("_Color");
#endregion
// Unity events
#region Unity events
private void Awake()
{
InitializeComponents();
}
#endregion
// Initialize methods
#region Initialize methods
public void InitializeComponents(SpriteRenderer spriteRenderer)
[Button("컴포넌트 초기화")]
private void InitializeComponents()
{
_spriteRenderer = spriteRenderer;
_spriteRenderer = GetComponentInChildren<SpriteRenderer>();
_physicMovable = GetComponent<IPhysicMovable>();
_dashable = GetComponent<IDashable>();
_comboAttackable = GetComponent<IComboAttackable>();
_skillHandler = GetComponent<ISkillHandler>();
}
#endregion
@ -59,49 +74,65 @@ namespace BlueWater.Players.Combat
// Methods
#region Methods
// Event methods
public void HandleCanApplyStatusEffect() => _canApplyStatusEffect = true;
public void HandleCanNotApplyStatusEffect() => _canApplyStatusEffect = false;
// Stun
public bool CanStun()
{
if (!IsStunEnabled) return false;
var isDashing = _dashable?.IsDashing ?? false;
var isActivatingSkill = _skillHandler?.IsActivatingSkill ?? false;
return !isDashing && !isActivatingSkill;
}
public void Stun(float duration)
{
if (!_canApplyStatusEffect) return;
if (!IsStunEnabled) return;
_stunParticle.Play();
IsStunned = true;
_stunParticle.Play();
OnStartStun?.Invoke();
Utils.StartUniqueCoroutine(this, ref _stunCoolDownCoroutine, Utils.CoolDownCoroutine(duration, EndStun));
}
public void EndStun()
{
Utils.EndUniqueCoroutine(this, ref _stunCoolDownCoroutine);
IsStunned = false;
_stunParticle.Stop();
_stunParticle.Clear();
OnEndStun?.Invoke();
IsStunned = false;
Utils.EndUniqueCoroutine(this, ref _stunCoolDownCoroutine);
}
// Slow
public bool CanSlowMove()
{
if (!IsSlowMoveEnabled) return false;
var isDashing = _dashable?.IsDashing ?? false;
var isActivatingSkill = _skillHandler?.IsActivatingSkill ?? false;
return !isDashing && !isActivatingSkill;
}
public void SlowMoveSpeed(float duration, float moveSpeedCoefficient)
{
if (!_canApplyStatusEffect) return;
if (!IsSlowMoveEnabled) return;
_spriteRenderer.material.SetColor(_colorHash, _slowEffectColor);
_physicMovable?.SetMoveSpeedCoefficient(moveSpeedCoefficient);
IsSlowedMoveSpeed = true;
_spriteRenderer.material.SetColor(_colorHash, _slowEffectColor);
OnStartSlowMoveSpeed?.Invoke(moveSpeedCoefficient);
Utils.StartUniqueCoroutine(this, ref _slowMoveSpeedCoolDownCoroutine, Utils.CoolDownCoroutine(duration, EndSlowMoveSpeed));
}
public void EndSlowMoveSpeed()
{
Utils.EndUniqueCoroutine(this, ref _slowMoveSpeedCoolDownCoroutine);
_spriteRenderer.material.SetColor(_colorHash, Color.white);
OnEndSlowMoveSpeed?.Invoke();
IsSlowedMoveSpeed = false;
_spriteRenderer.material.SetColor(_colorHash, Color.white);
_physicMovable?.ResetMoveSpeedCoefficient();
Utils.EndUniqueCoroutine(this, ref _slowMoveSpeedCoolDownCoroutine);
}
#endregion

View File

@ -4,6 +4,7 @@ using BlueWater.Audios;
using BlueWater.Interfaces;
using BlueWater.Uis;
using BlueWater.Utility;
using Sirenix.OdinInspector;
using UnityEngine;
namespace BlueWater.Players
@ -11,7 +12,11 @@ namespace BlueWater.Players
public class PlayerHealthPoint : MonoBehaviour, IDamageable
{
// Components
[SerializeField]
private SpriteRenderer _spriteRenderer;
private IDashable _dashable;
private ISkillHandler _skillHandler;
// Variables
[field: SerializeField]
@ -19,11 +24,11 @@ namespace BlueWater.Players
[field: SerializeField]
public int CurrentHealthPoint { get; private set; }
[field: SerializeField]
public float InvincibilityDuration { get; private set; } = 0.5f;
[SerializeField]
private float _damageInterval = 0.5f;
private bool _enableTakeDamage = true;
public bool IsInvincible { get; private set; }
private WaitForSeconds _flashWhiteWaitTime;
private Coroutine _flashWhiteCoroutine;
private Coroutine _damageIntervalCoroutine;
@ -36,11 +41,16 @@ namespace BlueWater.Players
public event Action OnDead;
// Unity events
private void Awake()
{
InitializeComponents();
}
private void Start()
{
OnHealthChanged += CombatUiManager.Instance.PlayerHealthPointUi.SetCurrentHealthPoint;
_flashWhiteWaitTime = new WaitForSeconds(_damageInterval * 0.1f);
_flashWhiteWaitTime = new WaitForSeconds(InvincibilityDuration * 0.1f);
SetCurrentHealthPoint(MaxHealthPoint);
}
@ -53,15 +63,15 @@ namespace BlueWater.Players
}
// Initialize methods
public void InitializeComponents(SpriteRenderer spriteRenderer)
[Button("컴포넌트 초기화")]
private void InitializeComponents()
{
_spriteRenderer = spriteRenderer;
_spriteRenderer = GetComponentInChildren<SpriteRenderer>();
_dashable = GetComponent<IDashable>();
_skillHandler = GetComponent<ISkillHandler>();
}
// Events methods
public void HandleEnableTakeDamage() => _enableTakeDamage = true;
public void HandleDisableTakeDamage() => _enableTakeDamage = false;
// Methods
public void SetCurrentHealthPoint(int changedHealthPoint)
{
@ -80,12 +90,17 @@ namespace BlueWater.Players
public bool CanDamage()
{
return _enableTakeDamage;
if (IsInvincible) return false;
var isDashing = _dashable?.IsDashing ?? false;
var isActivatingSkill = _skillHandler?.IsActivatingSkill ?? false;
return !isDashing && !isActivatingSkill;
}
public void TakeDamage(int damageAmount)
{
HandleDisableTakeDamage();
IsInvincible = true;
var changeHp = Mathf.Max(CurrentHealthPoint - damageAmount, 0);
SetCurrentHealthPoint(changeHp);
AudioManager.Instance.PlaySfx("CombatPlayerAttacked");
@ -101,7 +116,7 @@ namespace BlueWater.Players
{
Utils.StartUniqueCoroutine(this, ref _flashWhiteCoroutine, FlashWhiteCoroutine());
}
Utils.StartUniqueCoroutine(this, ref _damageIntervalCoroutine, Utils.CoolDownCoroutine(_damageInterval, EndDamageIntervalCoroutine));
Utils.StartUniqueCoroutine(this, ref _damageIntervalCoroutine, Utils.CoolDownCoroutine(InvincibilityDuration, EndDamageIntervalCoroutine));
}
public void TryTakeDamage(int damageAmount)
@ -131,8 +146,8 @@ namespace BlueWater.Players
private void EndDamageIntervalCoroutine()
{
IsInvincible = false;
Utils.EndUniqueCoroutine(this, ref _damageIntervalCoroutine);
HandleEnableTakeDamage();
}
}
}

View File

@ -16,8 +16,10 @@ namespace BlueWater.Players.Tycoons
// Move
[field: SerializeField, Range(1f, 10f), Tooltip("이동 속도")]
public float MoveSpeed { get; private set; } = 7f;
public bool EnableMove { get; private set; } = true;
public float MoveSpeedCoefficient { get; private set; } = 1f;
public bool IsMoveEnabled { get; private set; } = true;
private bool _isMoving;
public bool IsMoving
@ -40,7 +42,7 @@ namespace BlueWater.Players.Tycoons
public Vector3 CurrentDirection
{
get => _currentDirection;
set
private set
{
if (value == Vector3.zero) return;
@ -69,7 +71,7 @@ namespace BlueWater.Players.Tycoons
{
if (!CanMove()) return;
ApplyMovement();
Move();
}
#endregion
@ -93,9 +95,12 @@ namespace BlueWater.Players.Tycoons
{
_inputDirection = new Vector3(movementInput.x, 0, movementInput.y).normalized;
}
public void HandleEnableMove() => EnableMove = true;
public void HandleDisableMove() => EnableMove = false;
public void SetMoveSpeedCoefficient(float value) => MoveSpeedCoefficient = value;
public void ResetMoveSpeedCoefficient() => MoveSpeedCoefficient = 1f;
public void EnableMove() => IsMoveEnabled = true;
public void DisableMove() => IsMoveEnabled = false;
public void SetCurrentDirection(Vector3 normalDirection) => CurrentDirection = normalDirection;
// Methods
private void FlipVisualLook()
@ -113,7 +118,7 @@ namespace BlueWater.Players.Tycoons
// Move
public bool CanMove()
{
return EnableMove;
return IsMoveEnabled;
}
public void AddForce(Vector3 force, ForceMode forceMode)
@ -121,7 +126,7 @@ namespace BlueWater.Players.Tycoons
Rigidbody.AddForce(force, forceMode);
}
private void ApplyMovement()
public void Move()
{
CurrentDirection = _inputDirection;
IsMoving = _inputDirection != Vector3.zero;

View File

@ -0,0 +1,22 @@
using BlueWater.Players.Combat;
using UnityEngine;
namespace BlueWater.Interfaces
{
public interface IComboAttackable
{
int MaxHitCount { get; }
ComboAttack[] ComboAttacks { get; }
bool IsAttackEnabled { get; }
bool IsComboAttackPossible { get; }
bool IsComboAttacking { get; }
int CurrentComboAttackCount { get; set; }
Collider[] HitColliders { get; }
LayerMask TargetLayer { get; }
LayerMask MouseClickLayer { get; }
bool CanAttack();
void EndAttack();
void Attack(bool usedMouseAttack);
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2baae403c5973434e9fad1450d077334
timeCreated: 1716899052

View File

@ -4,7 +4,9 @@ namespace BlueWater.Interfaces
{
int MaxHealthPoint { get; }
int CurrentHealthPoint { get; }
bool IsInvincible { get; }
float InvincibilityDuration { get; }
void SetCurrentHealthPoint(int changedHealthPoint);
bool CanDamage();
void TakeDamage(int damageAmount);

View File

@ -2,14 +2,15 @@
{
public interface IDashable
{
bool EnableDash { get; }
bool IsDashEnabled { get; }
bool IsDashing { get; }
bool IsDashCoolDownActive { get; }
float DashSpeed { get; }
float DashTime { get; }
float DashCooldown { get; }
bool CanDash();
void HandleEnableDash();
void HandleDisableDash();
void Dash();
void EndDash(float dashCooldown = float.PositiveInfinity);
}
}

View File

@ -6,10 +6,16 @@ namespace BlueWater.Interfaces
{
Rigidbody Rigidbody { get; }
float MoveSpeed { get; }
bool EnableMove { get; }
float MoveSpeedCoefficient { get; }
bool IsMoveEnabled { get; }
bool IsMoving { get; }
Vector3 CurrentDirection { get; set; }
Vector3 CurrentDirection { get; }
void SetMoveSpeedCoefficient(float value);
void ResetMoveSpeedCoefficient();
void SetCurrentDirection(Vector3 normalDirection);
bool CanMove();
void Move();
void AddForce(Vector3 force, ForceMode forceMode);
}
}

View File

@ -0,0 +1,28 @@
using System.Collections.Generic;
namespace BlueWater.Interfaces
{
public interface ISkillHandler
{
List<BaseSkill> Skills { get; }
Dictionary<string, BaseSkill> SkillInstances { get; }
BaseSkill CurrentActivatingSkill { get; }
bool IsSkillEnabled { get; }
bool IsActivatingSkill { get; }
void EnableSkill();
void DisableSkill();
bool HasSkill(string skillName);
bool CanSkill(string skillName);
/// <summary>
/// HasSkill()만 확인하고 스킬을 강제로 사용
/// </summary>
void ActivateSkill(string skillName);
/// <summary>
/// HasSkill(), CanSkill()를 모두 확인하고 스킬을 사용하기까지 모든 과정
/// </summary>
void TryActivateSkill(string skillName);
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8a67c0e0914676b42b45b9b987cc6ce6
timeCreated: 1716899052

View File

@ -2,7 +2,10 @@
{
public interface ISlowable
{
bool IsSlowMoveEnabled { get; }
bool IsSlowedMoveSpeed { get; }
bool CanSlowMove();
void SlowMoveSpeed(float duration, float moveSpeedCoefficient);
void EndSlowMoveSpeed();
}

View File

@ -2,7 +2,10 @@
{
public interface IStunnable
{
bool IsStunEnabled { get; }
bool IsStunned { get; }
bool CanStun();
void Stun(float duration);
void EndStun();
}

View File

@ -8,6 +8,7 @@ namespace BlueWater
None = 0,
Tycoon,
TycoonUi,
CombatTitle,
Combat,
CombatUi,
}
@ -16,8 +17,6 @@ namespace BlueWater
{
[SerializeField]
private PlayerInput _currentPlayerInput;
private string _previousInputActionMaps;
private InputActionMap _previousInputActionMap;
/// <summary>
/// 현재 실행되고 있는 PlayerInput을 관리할 수 있게
@ -28,7 +27,7 @@ namespace BlueWater
private bool IsNullCurrentPlayerInput()
{
if (_currentPlayerInput) return false;
if (_currentPlayerInput && _currentPlayerInput.enabled) return false;
Debug.Log("CurrentPlayerInput가 할당되지 않았습니다.");
return true;
@ -38,7 +37,6 @@ namespace BlueWater
{
if (IsNullCurrentPlayerInput()) return;
_previousInputActionMaps = _currentPlayerInput.currentActionMap.name;
_currentPlayerInput.SwitchCurrentActionMap(inputActionMaps);
}
@ -46,24 +44,9 @@ namespace BlueWater
{
if (IsNullCurrentPlayerInput()) return;
_previousInputActionMaps = _currentPlayerInput.currentActionMap.name;
_currentPlayerInput.SwitchCurrentActionMap(inputActionMaps.ToString());
}
public void SwitchPreviousActionMap()
{
if (IsNullCurrentPlayerInput()) return;
if (string.IsNullOrEmpty(_previousInputActionMaps))
{
Debug.Log("저장된 _previousInputActionMaps값이 없습니다.");
return;
}
_currentPlayerInput.SwitchCurrentActionMap(_previousInputActionMaps);
_previousInputActionMaps = null;
}
public InputActionMap GetCurrentInputActionMap()
{
if (IsNullCurrentPlayerInput()) return null;
@ -114,7 +97,7 @@ namespace BlueWater
}
}
public void EnableAllActions()
public void EnableAllActionsMaps()
{
if (IsNullCurrentPlayerInput()) return;

View File

@ -15,6 +15,11 @@ namespace BlueWater
[field: SerializeField]
public int CurrentHealthPoint { get; private set; }
public bool IsInvincible { get; private set; }
[field: SerializeField]
public float InvincibilityDuration { get; private set; }
[Title("Die 설정")]
[SerializeField]
private string _dieSfxName;

View File

@ -100,6 +100,7 @@ namespace BlueWater
}
public virtual bool CanSkill() => EnableSkill;
/// <param name="actions">0번째 actions은 스킬이 종료된 후 실행해야하는 것들</param>
public abstract void ActivateSkill(params Action[] actions);
protected void EndCooldown()
@ -109,6 +110,7 @@ namespace BlueWater
}
public string SkillName => SkillData.Name;
public float Cooldown => SkillData.Cooldown;
#endregion
}

View File

@ -222,8 +222,14 @@ namespace BlueWater.Enemies.Bosses.TitanSlime.Skills
Utils.StartUniqueCoroutine(this, ref CooldownCoroutineInstance,Utils.CoolDownCoroutine(cooldown, EndCooldown));
}
private Vector3 CalculateRandomPosition(Vector3 startPosition, float range, int iterationCount = 100)
private Vector3 CalculateRandomPosition(Vector3 startPosition, float range, int iterationCount = 1000)
{
var nearestNodeInfo = AstarPath.active.GetNearest(startPosition);
if (nearestNodeInfo.node is not { Walkable: true })
{
startPosition = nearestNodeInfo.position;
}
for (var i = 0; i < iterationCount; i++)
{
var randomPosition = startPosition + Random.insideUnitSphere * range;
@ -233,8 +239,7 @@ namespace BlueWater.Enemies.Bosses.TitanSlime.Skills
return randomPosition;
}
Debug.Log($"{SkillUser.name}이 랜덤으로 이동할 위치를 찾지 못했습니다.");
return startPosition;
}

View File

@ -3,7 +3,6 @@ using System.Collections;
using System.Linq;
using BlueWater.Audios;
using BlueWater.Interfaces;
using BlueWater.Uis;
using BlueWater.Utility;
using UnityEngine;
using Random = UnityEngine.Random;
@ -194,7 +193,7 @@ namespace BlueWater.Players.Combat.Skills
case Direction.None:
break;
case Direction.Left:
_iPhysicMovable.CurrentDirection = Vector3.right;
_iPhysicMovable.SetCurrentDirection(Vector3.right);
addX = -hitCollider.bounds.extents.x;
_currentDirection = Direction.Back;
break;
@ -204,7 +203,7 @@ namespace BlueWater.Players.Combat.Skills
_previousLeft = !_previousLeft;
break;
case Direction.Right:
_iPhysicMovable.CurrentDirection = Vector3.left;
_iPhysicMovable.SetCurrentDirection(Vector3.left);
addX = hitCollider.bounds.extents.x;
_currentDirection = Direction.Back;
break;
@ -260,7 +259,6 @@ namespace BlueWater.Players.Combat.Skills
}
Utils.StartUniqueCoroutine(this, ref CooldownCoroutineInstance,Utils.CoolDownCoroutine(SkillData.Cooldown, EndCooldown));
CombatUiManager.Instance.CombatSkillUi.CoolDown(SkillData.Cooldown);
}
private void SortCollidersByDistance()

View File

@ -31,18 +31,17 @@ namespace BlueWater.Uis
public void ShowFirstTutorialUi()
{
PlayerInputKeyManager.Instance.DisableCurrentPlayerInput();
PlayerInputKeyManager.Instance.DisableAllActionMaps();
gameObject.SetActive(true);
_firstTutorialUi.SetActive(true);
_secondTutorialUi.SetActive(false);
CurrentTutorialState = TutorialState.First;
StartCoroutine(FirstTutorialCoroutine());
Invoke(nameof(FirstTutorialCoroutine), 0.1f);
}
private IEnumerator FirstTutorialCoroutine()
private void FirstTutorialCoroutine()
{
yield return new WaitForSeconds(0.1f);
PlayerInputKeyManager.Instance.EnableCurrentPlayerInput();
PlayerInputKeyManager.Instance.SwitchCurrentActionMap(InputActionMaps.CombatUi);
PlayerInputKeyManager.Instance.DisableAllActionsExcept("InteractionUi");

View File

@ -67,6 +67,11 @@ namespace BlueWater.Uis
}
private void Start()
{
Invoke(nameof(StartTutorial), 0.1f);
}
private void StartTutorial()
{
CombatTutorialUi.ShowFirstTutorialUi();
}

View File

@ -38,6 +38,7 @@ Material:
disabledShaderPasses:
- MOTIONVECTORS
- DepthOnly
- SHADOWCASTER
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3

View File

@ -366,11 +366,11 @@ MonoBehaviour:
<HitBoxCollider>k__BackingField: {fileID: 6951320512859863136}
<SpriteRenderer>k__BackingField: {fileID: 5558898291459354456}
<Animator>k__BackingField: {fileID: 3031446967001791208}
<PlayerHealthPoint>k__BackingField: {fileID: 326920787583948413}
<AnimationController>k__BackingField: {fileID: 3889238742570113982}
<CombatInput>k__BackingField: {fileID: 522031830802304584}
<CombatMovement>k__BackingField: {fileID: 181082763061672982}
<AnimationController>k__BackingField: {fileID: 3889238742570113982}
<CombatAttacker>k__BackingField: {fileID: 6458719908533317799}
<PlayerHealthPoint>k__BackingField: {fileID: 326920787583948413}
<CombatSkillController>k__BackingField: {fileID: 3677775080446906429}
<CombatStatus>k__BackingField: {fileID: 9129295631914427799}
--- !u!114 &522031830802304584
@ -385,6 +385,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: c1832000a0f2b5d45b277c98a748c359, type: 3}
m_Name:
m_EditorClassIdentifier:
_playerInput: {fileID: 6401154187219196241}
--- !u!114 &181082763061672982
MonoBehaviour:
m_ObjectHideFlags: 0
@ -397,6 +398,9 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 77cb3821bc2d2f74b85d8e49b0395064, type: 3}
m_Name:
m_EditorClassIdentifier:
<Rigidbody>k__BackingField: {fileID: 1951754024224882079}
_visualLook: {fileID: 2668222795840865044}
_animationController: {fileID: 3889238742570113982}
<MoveSpeed>k__BackingField: 7
<DashSpeed>k__BackingField: 20
<DashTime>k__BackingField: 0.2
@ -413,6 +417,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 17488a2bea6f4126a7877ce5d934f865, type: 3}
m_Name:
m_EditorClassIdentifier:
_animator: {fileID: 3031446967001791208}
--- !u!114 &6458719908533317799
MonoBehaviour:
m_ObjectHideFlags: 0
@ -425,6 +430,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d7c20927144715848888b335473c5bf0, type: 3}
m_Name:
m_EditorClassIdentifier:
_rigidbody: {fileID: 1951754024224882079}
_animationController: {fileID: 3889238742570113982}
<MaxHitCount>k__BackingField: 10
<ComboAttacks>k__BackingField:
- <Damage>k__BackingField: 10
@ -440,7 +447,7 @@ MonoBehaviour:
<TargetLayer>k__BackingField:
serializedVersion: 2
m_Bits: 4352
_mouseClickLayer:
<MouseClickLayer>k__BackingField:
serializedVersion: 2
m_Bits: 32832
_swordAttackParticle: {fileID: 8523211495174882546, guid: 04437dbea0cb46d46be53d3485123127, type: 3}
@ -457,9 +464,10 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 6ff2dc3fa7a6be445bf8e71043f86d2e, type: 3}
m_Name:
m_EditorClassIdentifier:
_spriteRenderer: {fileID: 5558898291459354456}
<MaxHealthPoint>k__BackingField: 4
<CurrentHealthPoint>k__BackingField: 0
_damageInterval: 0.5
<InvincibilityDuration>k__BackingField: 0.5
--- !u!114 &3677775080446906429
MonoBehaviour:
m_ObjectHideFlags: 0
@ -472,7 +480,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d15d270547a76a547b91e71c596e4fc7, type: 3}
m_Name:
m_EditorClassIdentifier:
_mainSkillPrefab: {fileID: -3797204096501760660, guid: c2dcf20bc51f1b242961ed33da1867ac, type: 3}
<Skills>k__BackingField:
- {fileID: -3797204096501760660, guid: c2dcf20bc51f1b242961ed33da1867ac, type: 3}
--- !u!114 &9129295631914427799
MonoBehaviour:
m_ObjectHideFlags: 0
@ -485,6 +494,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 0096d36771e12834592c1d58bf8358a3, type: 3}
m_Name:
m_EditorClassIdentifier:
_spriteRenderer: {fileID: 5558898291459354456}
_stunParticle: {fileID: 8979130989535966673}
_slowEffectColor: {r: 0.5921569, g: 0.9843137, b: 0.5882353, a: 0}
--- !u!114 &260539324676461127

View File

@ -140,7 +140,7 @@ PlayerSettings:
loadStoreDebugModeEnabled: 0
visionOSBundleVersion: 1.0
tvOSBundleVersion: 1.0
bundleVersion: 0.2.1
bundleVersion: 0.2.2.0
preloadedAssets:
- {fileID: -944628639613478452, guid: 4ed6540e2f7ce234888adf8deff1f241, type: 3}
metroInputSource: 0