parent
2840306ceb
commit
96f1528a96
@ -52,6 +52,7 @@ namespace BlueWaterProject
|
|||||||
[field: SerializeField] public float Atk { get; private set; } = 10f;
|
[field: SerializeField] public float Atk { get; private set; } = 10f;
|
||||||
|
|
||||||
[field: Tooltip("공격 속도(다음 공격 주기)\nAtkCooldown = 2f (2초마다 1번 공격)")]
|
[field: Tooltip("공격 속도(다음 공격 주기)\nAtkCooldown = 2f (2초마다 1번 공격)")]
|
||||||
|
[field: OnValueChanged("SetAtkWaitCooldown")]
|
||||||
[field: SerializeField] public float AtkCooldown { get; private set; } = 1f;
|
[field: SerializeField] public float AtkCooldown { get; private set; } = 1f;
|
||||||
|
|
||||||
[field: Tooltip("공격 사거리 설정")]
|
[field: Tooltip("공격 사거리 설정")]
|
||||||
@ -98,6 +99,8 @@ namespace BlueWaterProject
|
|||||||
|
|
||||||
// 일반 변수
|
// 일반 변수
|
||||||
protected bool isAttacking;
|
protected bool isAttacking;
|
||||||
|
protected bool usedNormalAttackCoroutine;
|
||||||
|
protected WaitForSeconds waitAtkCooldown;
|
||||||
|
|
||||||
// 컴포넌트
|
// 컴포넌트
|
||||||
protected Rigidbody rb;
|
protected Rigidbody rb;
|
||||||
@ -251,6 +254,7 @@ namespace BlueWaterProject
|
|||||||
HelpLayer = LayerMask.GetMask("Enemy");
|
HelpLayer = LayerMask.GetMask("Enemy");
|
||||||
TargetLayer = LayerMask.GetMask("Player") | LayerMask.GetMask("Crewmate");
|
TargetLayer = LayerMask.GetMask("Player") | LayerMask.GetMask("Crewmate");
|
||||||
|
|
||||||
|
waitAtkCooldown = new WaitForSeconds(AtkCooldown);
|
||||||
Agent.updateRotation = false;
|
Agent.updateRotation = false;
|
||||||
DefensePos = transform.position;
|
DefensePos = transform.position;
|
||||||
SetAgentSpeed(MoveSpd);
|
SetAgentSpeed(MoveSpd);
|
||||||
@ -261,29 +265,12 @@ namespace BlueWaterProject
|
|||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
switch (useHpSlider)
|
HpSliderUpdate();
|
||||||
{
|
|
||||||
case true when CurrentHp > 0 && CurrentHp < MaxHp:
|
if (CurrentHp <= 0) return;
|
||||||
{
|
|
||||||
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;
|
MoveUpdate();
|
||||||
}
|
FlipCharacterUpdate();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -445,6 +432,71 @@ namespace BlueWaterProject
|
|||||||
|
|
||||||
#region Custom methods
|
#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()
|
private IEnumerator BeAttacked()
|
||||||
{
|
{
|
||||||
beAttacked = true;
|
beAttacked = true;
|
||||||
@ -483,6 +535,7 @@ namespace BlueWaterProject
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void SetAgentSpeed(float value) => Agent.speed = value;
|
private void SetAgentSpeed(float value) => Agent.speed = value;
|
||||||
|
private void SetAtkWaitCooldown() => waitAtkCooldown = new WaitForSeconds(AtkCooldown);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b4a3c484f38451143a9c99271118609f
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f9f959e48a1ddbe4b9a7b21c4553d3c3
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 875fece963e8a1844a1753fdd24b0407
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 53a5952d905610548b93367641aa8244
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -7,9 +7,6 @@ namespace BlueWaterProject
|
|||||||
public abstract class FieldMinion : Enemy, IAnimatorBridge, INormalAttack
|
public abstract class FieldMinion : Enemy, IAnimatorBridge, INormalAttack
|
||||||
{
|
{
|
||||||
#region Properties and variables
|
#region Properties and variables
|
||||||
|
|
||||||
protected bool usedNormalAttackCoroutine;
|
|
||||||
protected WaitForSeconds waitAtkCooldown;
|
|
||||||
|
|
||||||
// Hash
|
// Hash
|
||||||
protected static readonly int AttackHash = Animator.StringToHash("Attack");
|
protected static readonly int AttackHash = Animator.StringToHash("Attack");
|
||||||
@ -25,52 +22,7 @@ namespace BlueWaterProject
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Unity built-in methods
|
#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
|
#endregion
|
||||||
|
|
||||||
|
@ -547,7 +547,12 @@ namespace BlueWaterProject
|
|||||||
|
|
||||||
public void OnAttackEvent(InputAction.CallbackContext context)
|
public void OnAttackEvent(InputAction.CallbackContext context)
|
||||||
{
|
{
|
||||||
if (CurrentHp <= 0f || isRolling || usedNormalAttackCoroutine) return;
|
if (CurrentHp <= 0f || usedNormalAttackCoroutine) return;
|
||||||
|
|
||||||
|
if (isRolling)
|
||||||
|
{
|
||||||
|
AttackWhileRolling();
|
||||||
|
}
|
||||||
|
|
||||||
var control = context.control;
|
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()
|
private void GameOver()
|
||||||
{
|
{
|
||||||
var overlayCanvas = GameObject.Find("OverlayCanvas");
|
var overlayCanvas = GameObject.Find("OverlayCanvas");
|
||||||
|
@ -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
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 211c62e69325b584bb719f236f0e2d5c
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Loading…
Reference in New Issue
Block a user