웅냥
This commit is contained in:
49
Assets/Scripts/Unicorn/Boss/AttackManager.cs
Normal file
49
Assets/Scripts/Unicorn/Boss/AttackManager.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Unicorn.Hitbox;
|
||||
using Unity.Collections;
|
||||
using Unity.Collections.LowLevel.Unsafe;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unicorn.Boss
|
||||
{
|
||||
public class AttackManager: MonoBehaviour
|
||||
{
|
||||
private Dictionary<EntityId, float> _projMap;
|
||||
private Dictionary<EntityId, UnicornHitbox> _projHitboxMap;
|
||||
private const float Lifetime = 5f;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_projMap = new Dictionary<EntityId, float>();
|
||||
_projHitboxMap = new Dictionary<EntityId, UnicornHitbox>();
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
foreach (Transform o in transform)
|
||||
{
|
||||
var entityId = o.GetEntityId();
|
||||
if (_projMap.TryAdd(entityId, 0f))
|
||||
{
|
||||
if (o.TryGetComponent(out UnicornHitbox hitbox))
|
||||
_projHitboxMap.Add(entityId, hitbox);
|
||||
}
|
||||
|
||||
if (o.gameObject.activeInHierarchy)
|
||||
_projMap[entityId] += Time.fixedDeltaTime;
|
||||
else continue;
|
||||
|
||||
if (_projMap[entityId] > Lifetime)
|
||||
{
|
||||
o.gameObject.SetActive(false);
|
||||
_projMap[entityId] = 0f;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!_projHitboxMap.TryGetValue(entityId, out var unicornHitbox)) continue;
|
||||
o.transform.Translate(o.right * (unicornHitbox.hitboxData.hitboxSpeed * Time.fixedDeltaTime), Space.World);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Unicorn/Boss/AttackManager.cs.meta
Normal file
3
Assets/Scripts/Unicorn/Boss/AttackManager.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 88e10741af6249658ff3e467495bf561
|
||||
timeCreated: 1778331143
|
||||
@@ -1,8 +1,8 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using DG.Tweening;
|
||||
using Unicorn.Hitbox;
|
||||
using UnityEngine;
|
||||
using NotImplementedException = System.NotImplementedException;
|
||||
|
||||
namespace Unicorn.Boss
|
||||
{
|
||||
@@ -15,6 +15,7 @@ namespace Unicorn.Boss
|
||||
|
||||
private UnicornPhase _unicornPhase = UnicornPhase.Start;
|
||||
private Queue<GameObject> _p1Ps = new Queue<GameObject>();
|
||||
private SpriteRenderer _renderer;
|
||||
private const float P1PC = 12;
|
||||
|
||||
public Transform projContainer;
|
||||
@@ -23,14 +24,17 @@ namespace Unicorn.Boss
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_renderer = GetComponent<SpriteRenderer>();
|
||||
StartCoroutine(Started());
|
||||
base.Start();
|
||||
}
|
||||
|
||||
private IEnumerator Started()
|
||||
{
|
||||
while (_p1Ps.Count < 50)
|
||||
const float target = 360*5/P1PC;
|
||||
while (_p1Ps.Count < target)
|
||||
{
|
||||
for (var i = 0; i < 5 && _p1Ps.Count < 50; i++) //프레임당 5개씩 생성
|
||||
for (var i = 0; i < 5 && _p1Ps.Count < target; i++) //프레임당 5개씩 생성
|
||||
{
|
||||
var instantiate = Instantiate(phase1Proj, projContainer);
|
||||
_p1Ps.Enqueue(instantiate);
|
||||
@@ -46,26 +50,52 @@ namespace Unicorn.Boss
|
||||
|
||||
}
|
||||
|
||||
// 수정된 Phase1 로직
|
||||
private IEnumerator Phase1()
|
||||
{
|
||||
_unicornPhase = UnicornPhase.P1;
|
||||
for (int i = 0; i < 360 / P1PC; i++)
|
||||
float angleStep = 360f / P1PC; // 각도 간격 (30도)
|
||||
|
||||
for (int i = 0; i < P1PC; i++)
|
||||
{
|
||||
var dequeue = _p1Ps.Dequeue();
|
||||
dequeue.SetActive(true);
|
||||
dequeue.transform.position = transform.position;
|
||||
var rotationEulerAngles = transform.rotation.eulerAngles;
|
||||
rotationEulerAngles.z += (360 / P1PC) * i;
|
||||
dequeue.transform.rotation = Quaternion.Euler(rotationEulerAngles);
|
||||
float targetAngle = transform.rotation.eulerAngles.z + (angleStep * i);
|
||||
dequeue.transform.rotation = Quaternion.Euler(0, 0, targetAngle);
|
||||
_p1Ps.Enqueue(dequeue);
|
||||
yield return new WaitForSeconds(.2f);
|
||||
}
|
||||
yield return new WaitForSeconds(5);
|
||||
yield return new WaitForSeconds(1);
|
||||
StartCoroutine(Phase1());
|
||||
}
|
||||
|
||||
protected override void OnKnockback(DamageInfo info)
|
||||
{
|
||||
//No KnockBack
|
||||
|
||||
}
|
||||
|
||||
protected override void OnDeath()
|
||||
{
|
||||
transform.DOScale(0f, 3f).SetEase(Ease.Linear).OnComplete(() =>
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
base.OnDeath();
|
||||
});
|
||||
}
|
||||
|
||||
protected override void OnDamaged(DamageInfo info)
|
||||
{
|
||||
StopCoroutine(HitColor());
|
||||
StartCoroutine(HitColor());
|
||||
base.OnDamaged(info);
|
||||
}
|
||||
|
||||
private IEnumerator HitColor()
|
||||
{
|
||||
_renderer.color = new Color(1f, 0.8f, 0.8f);
|
||||
yield return new WaitForSeconds(0.5f);
|
||||
_renderer.color = Color.white;
|
||||
}
|
||||
}
|
||||
}
|
||||
10
Assets/Scripts/Unicorn/GameManager.cs
Normal file
10
Assets/Scripts/Unicorn/GameManager.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unicorn
|
||||
{
|
||||
|
||||
public class GameManager: MonoBehaviour
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Unicorn/GameManager.cs.meta
Normal file
3
Assets/Scripts/Unicorn/GameManager.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cc10e4b8623544638c8e15879ff85de7
|
||||
timeCreated: 1778342698
|
||||
@@ -4,15 +4,15 @@ namespace Unicorn.Hitbox
|
||||
{
|
||||
public class UnicornHitbox : MonoBehaviour
|
||||
{
|
||||
public UnicornAttackDataSObj attackData;
|
||||
public UnicornHitboxDataSObj hitboxData;
|
||||
|
||||
private void OnTriggerEnter2D(Collider2D other)
|
||||
{
|
||||
if (!other.TryGetComponent(out LivingEntity target)) return;
|
||||
var info = new DamageInfo
|
||||
{
|
||||
Damage = attackData.damage,
|
||||
KnockbackForce = attackData.knockbackForce,
|
||||
Damage = hitboxData.damage,
|
||||
KnockbackForce = hitboxData.knockbackForce,
|
||||
HitPoint = transform.position
|
||||
};
|
||||
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
namespace Unicorn.Hitbox
|
||||
{
|
||||
[CreateAssetMenu(fileName = "NewAttackData", menuName = "Unicorn/AttackData")]
|
||||
public class UnicornAttackDataSObj: ScriptableObject
|
||||
public class UnicornHitboxDataSObj: ScriptableObject
|
||||
{
|
||||
public float damage;
|
||||
public float knockbackForce;
|
||||
public float hitboxSpeed;
|
||||
}
|
||||
}
|
||||
31
Assets/Scripts/Unicorn/HpBar.cs
Normal file
31
Assets/Scripts/Unicorn/HpBar.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unicorn
|
||||
{
|
||||
public class HpBar : MonoBehaviour
|
||||
{
|
||||
private LivingEntity _parent;
|
||||
public GameObject fill;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (!transform.parent.TryGetComponent(out _parent))
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
return;
|
||||
}
|
||||
UpdateHealth();
|
||||
}
|
||||
|
||||
public void UpdateHealth()
|
||||
{
|
||||
var scale = Math.Max(_parent.health, 0f) / _parent.maxHealth;
|
||||
fill.transform.localScale = new Vector3(scale, 1, 1);
|
||||
fill.transform.localPosition = new Vector3((scale-1) / 2, 0, 0);
|
||||
|
||||
//1 -> 0
|
||||
//0 -> -0.5
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Unicorn/HpBar.cs.meta
Normal file
2
Assets/Scripts/Unicorn/HpBar.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 177f745ebb3c415e8e5c73b53c18636b
|
||||
@@ -5,21 +5,18 @@ namespace Unicorn
|
||||
{
|
||||
public partial class LivingEntity : MonoBehaviour
|
||||
{
|
||||
public float maxHealth = 20.0f;
|
||||
public float health = 20.0f;
|
||||
public GameObject hpBarPrefab;
|
||||
private Rigidbody2D Rb { get; set; }
|
||||
private bool _invulnerable = false;
|
||||
private HpBar _hpBar;
|
||||
|
||||
private void Start()
|
||||
protected void Start()
|
||||
{
|
||||
Rb = TryGetComponent(out Rigidbody2D rb) ? rb : null;
|
||||
}
|
||||
|
||||
private void OnTriggerEnter2D(Collider2D other)
|
||||
{
|
||||
if (Rb == null) return;
|
||||
var transformPosition = other.transform.position - transform.position;
|
||||
Rb.linearVelocity = Vector2.zero;
|
||||
Rb.AddForce(transformPosition.normalized * health, ForceMode2D.Impulse);
|
||||
var hpBar = Instantiate(hpBarPrefab, transform);
|
||||
hpBar.TryGetComponent(out _hpBar);
|
||||
}
|
||||
|
||||
public void Damage(DamageInfo info)
|
||||
@@ -27,6 +24,7 @@ namespace Unicorn
|
||||
if (_invulnerable) return;
|
||||
health -= info.Damage;
|
||||
OnDamaged(info);
|
||||
OnKnockback(info);
|
||||
if (health <= 0.0f) OnDeath();
|
||||
}
|
||||
|
||||
@@ -34,10 +32,14 @@ namespace Unicorn
|
||||
protected virtual void OnDeath() { }
|
||||
|
||||
|
||||
protected virtual void OnDamaged(DamageInfo info) { }
|
||||
protected virtual void OnDamaged(DamageInfo info)
|
||||
{
|
||||
if (_hpBar) _hpBar.UpdateHealth();
|
||||
}
|
||||
|
||||
protected virtual void OnKnockback(DamageInfo info)
|
||||
{
|
||||
|
||||
var dir = transform.position - info.HitPoint;
|
||||
Rb.AddForce(dir.normalized * info.KnockbackForce, ForceMode2D.Impulse);
|
||||
}
|
||||
|
||||
@@ -8,11 +8,13 @@ namespace Unicorn.Player
|
||||
protected override void OnDamaged(DamageInfo info)
|
||||
{
|
||||
Debug.Log(health);
|
||||
base.OnDamaged(info);
|
||||
}
|
||||
|
||||
protected override void OnDeath()
|
||||
{
|
||||
Debug.Log("주것서영.");
|
||||
base.OnDeath();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ namespace Unicorn.Player
|
||||
{
|
||||
public GameObject attackHitbox;
|
||||
private UnicornInputSystem _unicornInput;
|
||||
private bool _attackAvailable = true;
|
||||
private void Start()
|
||||
{
|
||||
_unicornInput = UnicornInput.Unicorn;
|
||||
@@ -22,14 +23,18 @@ namespace Unicorn.Player
|
||||
|
||||
private void Attack(InputAction.CallbackContext obj)
|
||||
{
|
||||
if (!_attackAvailable) return;
|
||||
StartCoroutine(OnAttack());
|
||||
}
|
||||
|
||||
private IEnumerator OnAttack()
|
||||
{
|
||||
_attackAvailable = false;
|
||||
attackHitbox.SetActive(true);
|
||||
yield return new WaitForSeconds(0.5f);
|
||||
attackHitbox.SetActive(false);
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
_attackAvailable = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user