closed #42 회피 중 공격 수정

+ 필드 보스 작업 중
This commit is contained in:
NTG 2023-10-31 03:50:02 +09:00
parent 2840306ceb
commit 96f1528a96
12 changed files with 4506 additions and 72 deletions

View File

@ -52,6 +52,7 @@ namespace BlueWaterProject
[field: SerializeField] public float Atk { get; private set; } = 10f;
[field: Tooltip("공격 속도(다음 공격 주기)\nAtkCooldown = 2f (2초마다 1번 공격)")]
[field: OnValueChanged("SetAtkWaitCooldown")]
[field: SerializeField] public float AtkCooldown { get; private set; } = 1f;
[field: Tooltip("공격 사거리 설정")]
@ -98,6 +99,8 @@ namespace BlueWaterProject
// 일반 변수
protected bool isAttacking;
protected bool usedNormalAttackCoroutine;
protected WaitForSeconds waitAtkCooldown;
// 컴포넌트
protected Rigidbody rb;
@ -251,6 +254,7 @@ namespace BlueWaterProject
HelpLayer = LayerMask.GetMask("Enemy");
TargetLayer = LayerMask.GetMask("Player") | LayerMask.GetMask("Crewmate");
waitAtkCooldown = new WaitForSeconds(AtkCooldown);
Agent.updateRotation = false;
DefensePos = transform.position;
SetAgentSpeed(MoveSpd);
@ -261,29 +265,12 @@ namespace BlueWaterProject
protected override void Update()
{
switch (useHpSlider)
{
case true when CurrentHp > 0 && CurrentHp < MaxHp:
{
if (!hpSlider.gameObject.activeSelf)
{
hpSlider.gameObject.SetActive(true);
}
var localOffset = unitRoot.TransformPoint(hpSliderOffset);
hpSlider.transform.position = localOffset;
break;
}
case true when CurrentHp <= 0 || CurrentHp >= MaxHp:
{
if (hpSlider.gameObject.activeSelf)
{
hpSlider.gameObject.SetActive(false);
}
HpSliderUpdate();
if (CurrentHp <= 0) return;
break;
}
}
MoveUpdate();
FlipCharacterUpdate();
}
#endregion
@ -445,6 +432,71 @@ namespace BlueWaterProject
#region Custom methods
private void HpSliderUpdate()
{
switch (useHpSlider)
{
case true when CurrentHp > 0 && CurrentHp < MaxHp:
{
if (!hpSlider.gameObject.activeSelf)
{
hpSlider.gameObject.SetActive(true);
}
var localOffset = unitRoot.TransformPoint(hpSliderOffset);
hpSlider.transform.position = localOffset;
break;
}
case true when CurrentHp <= 0 || CurrentHp >= MaxHp:
{
if (hpSlider.gameObject.activeSelf)
{
hpSlider.gameObject.SetActive(false);
}
break;
}
}
}
private void MoveUpdate()
{
float runStateValue;
// 움직이는 경우
if (Agent.velocity.x != 0 || Agent.velocity.z != 0)
{
runStateValue = 0.5f;
}
// 멈춰있는 경우
else
{
runStateValue = 0f;
}
if (!beAttacked)
{
myAnimator.SetFloat(RunStateHash, runStateValue);
}
}
private void FlipCharacterUpdate()
{
var localScale = transform.localScale;
if (Agent.velocity.x != 0)
{
localScale.x = Agent.velocity.x > 0 ? Mathf.Abs(localScale.x) : -Mathf.Abs(localScale.x);
}
else
{
if (Target)
{
var targetToDistanceX = Target.bounds.center.x - MyCollider.bounds.center.x;
localScale.x = targetToDistanceX > 0 ? Mathf.Abs(localScale.x) : -Mathf.Abs(localScale.x);
}
}
transform.localScale = localScale;
}
private IEnumerator BeAttacked()
{
beAttacked = true;
@ -483,6 +535,7 @@ namespace BlueWaterProject
}
private void SetAgentSpeed(float value) => Agent.speed = value;
private void SetAtkWaitCooldown() => waitAtkCooldown = new WaitForSeconds(AtkCooldown);
#endregion
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b4a3c484f38451143a9c99271118609f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,63 @@
using System.Collections;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public abstract class FieldBoss : Enemy, IAnimatorBridge, INormalAttack
{
#region Properties and variables
// Hash
protected static readonly int AttackHash = Animator.StringToHash("Attack");
protected static readonly int AttackStateHash = Animator.StringToHash("AttackState");
protected static readonly int NormalStateHash = Animator.StringToHash("NormalState");
#endregion
#region abstract
protected abstract IEnumerator NormalAttackCoroutine();
#endregion
#region Unity built-in methods
#endregion
#region Interface
// IAnimatorBridge
public virtual void AttackTiming()
{
if (!Target) return;
var myCenterPos = MyCollider.bounds.center;
var targetDir = (Target.bounds.center - myCenterPos).normalized;
if (!Physics.Raycast(MyCollider.bounds.center, targetDir, out var hit, AtkRange, TargetLayer)) return;
var iDamageable = hit.transform.GetComponent<IDamageable>();
iDamageable.TakeDamage(Atk);
}
public void SetIsAttacking(int boolValue) => isAttacking = boolValue == 1;
// INormalAttack
public void NormalAttack()
{
StartCoroutine(nameof(NormalAttackCoroutine));
}
public void StopNormalAttackCoroutine() => StopCoroutine(nameof(NormalAttackCoroutine));
public bool GetUsedNormalAttackCoroutine() => usedNormalAttackCoroutine;
#endregion
#region Custom methods
#endregion
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f9f959e48a1ddbe4b9a7b21c4553d3c3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 875fece963e8a1844a1753fdd24b0407
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,72 @@
using System;
using System.Collections;
using Sirenix.OdinInspector;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[Serializable]
public class FieldBoss01 : FieldMinion
{
#region Properties and variables
#endregion
#region Unity built-in methods
protected override void Awake()
{
base.Awake();
}
protected override void Start()
{
base.Start();
}
#endregion
#region Interface
// IAnimatorBridge
public override void AttackTiming()
{
}
#endregion
#region Custom methods
protected override IEnumerator NormalAttackCoroutine()
{
usedNormalAttackCoroutine = true;
myAnimator.SetFloat(AttackStateHash, 0f);
myAnimator.SetFloat(NormalStateHash, 1f);
// Attack 애니메이션에 시작에 isAttacking = true, 끝날 때 isAttacking = false 이벤트 실행
myAnimator.SetTrigger(AttackHash);
var maxWaitTime = 0.5f;
var timer = 0f;
while (isAttacking && timer < maxWaitTime)
{
timer += Time.deltaTime;
yield return null;
}
yield return waitAtkCooldown;
usedNormalAttackCoroutine = false;
}
#endregion
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 53a5952d905610548b93367641aa8244
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -7,9 +7,6 @@ namespace BlueWaterProject
public abstract class FieldMinion : Enemy, IAnimatorBridge, INormalAttack
{
#region Properties and variables
protected bool usedNormalAttackCoroutine;
protected WaitForSeconds waitAtkCooldown;
// Hash
protected static readonly int AttackHash = Animator.StringToHash("Attack");
@ -25,52 +22,7 @@ namespace BlueWaterProject
#endregion
#region Unity built-in methods
protected override void Start()
{
base.Start();
waitAtkCooldown = new WaitForSeconds(AtkCooldown);
}
protected override void Update()
{
base.Update();
if (CurrentHp <= 0) return;
float runStateValue;
// 움직이는 경우
if (Agent.velocity.x != 0 || Agent.velocity.z != 0)
{
runStateValue = 0.5f;
}
// 멈춰있는 경우
else
{
runStateValue = 0f;
}
if (!beAttacked)
{
myAnimator.SetFloat(RunStateHash, runStateValue);
}
var localScale = transform.localScale;
if (Agent.velocity.x != 0)
{
localScale.x = Agent.velocity.x > 0 ? Mathf.Abs(localScale.x) : -Mathf.Abs(localScale.x);
}
else
{
if (Target)
{
var targetToDistanceX = Target.bounds.center.x - MyCollider.bounds.center.x;
localScale.x = targetToDistanceX > 0 ? Mathf.Abs(localScale.x) : -Mathf.Abs(localScale.x);
}
}
transform.localScale = localScale;
}
#endregion

View File

@ -547,7 +547,12 @@ namespace BlueWaterProject
public void OnAttackEvent(InputAction.CallbackContext context)
{
if (CurrentHp <= 0f || isRolling || usedNormalAttackCoroutine) return;
if (CurrentHp <= 0f || usedNormalAttackCoroutine) return;
if (isRolling)
{
AttackWhileRolling();
}
var control = context.control;
@ -740,6 +745,15 @@ namespace BlueWaterProject
}
}
private void AttackWhileRolling()
{
StopCoroutine(nameof(Roll));
Rb.velocity = Vector3.zero;
afterImageTrail.Clear();
isRolling = false;
}
private void GameOver()
{
var overlayCanvas = GameObject.Find("OverlayCanvas");

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8536c9e93a521004e985f83e0d4d13b0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 211c62e69325b584bb719f236f0e2d5c
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: