유니티/수업 내용
[3D RPG 프로토타입] 몬스터와 전투 이벤트기반, 가장 가까운 적 찾기
hyunjin-dev-log
2021. 12. 23. 16:55
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestAttackMain : MonoBehaviour
{
public UIInGame uiInGame;
public TestHero hero;
public TestMonster monster;
void Start()
{
this.Init();
this.InitUI();
}
private void Init()
{
this.monster.OnHit = (id, hp, maxHp) => {
this.uiInGame.UpdateMonsterHp(hp, maxHp);
};
this.monster.OnDieEvent.AddListener((id) => {
this.monster.Die();
});
this.monster.OnDieComplete = () => {
Destroy(this.monster.gameObject);
this.monster = null;
this.uiInGame.HideUIMonsterHp();
};
this.monster.Init(100, 10);
//게임 초기화
this.hero.OnAttackImpactEvent.AddListener((damage) =>
{
Debug.LogErrorFormat("OnAttackImpactEvent : {0}", damage);
this.monster.Hit(damage);
});
this.hero.OnAttackComplete = (damage) => {
Debug.LogErrorFormat("OnAttackComplete : {0}", damage);
};
//this.hero.OnAttackCompleteEvent.AddListener(() =>
//{
// Debug.LogError("attack complete");
// this.hero.Idle();
//});
//this.hero.OnAttackImpact = () => {
// Debug.LogError("impact!");
//};
//this.hero.OnAttackComplete = () => {
// Debug.LogError("attackComplete");
// this.hero.Idle();
//};
}
private void InitUI()
{
this.uiInGame.btn.onClick.AddListener(() => {
this.hero.Attack(this.monster);
});
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class TestHeroAttackImpactEvent : UnityEvent<float>
{
}
public class TestHero : MonoBehaviour
{
private float damage = 11f;
private TestMonster target;
public Animation anim;
//public System.Action OnAttackImpact;
//public System.Action OnAttackComplete;
//public UnityAction OnAttackImpact;
//public UnityAction OnAttackComplete;
public TestHeroAttackImpactEvent OnAttackImpactEvent = new TestHeroAttackImpactEvent();
//public UnityEvent OnAttackCompleteEvent = new UnityEvent();
public UnityAction<float> OnAttackComplete;
public void SetTarget(TestMonster target)
{
this.target = target;
}
public void Attack(TestMonster target)
{
if (target == null) return;
this.anim.Play("attack_sword_01");
StartCoroutine(this.WaitForAttack());
}
private IEnumerator WaitForAttack()
{
yield return new WaitForSeconds(0.3f);
//이벤트
//this.OnAttackImpact();
OnAttackImpactEvent.Invoke(this.damage);
yield return new WaitForSeconds(0.733f - 0.3f);
this.OnAttackComplete(this.damage);
//this.OnAttackCompleteEvent.Invoke();
}
public void Idle()
{
this.target = null;
this.anim.Play("idle@loop");
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class TestMonster : TestMonsterBase
{
public Animator anim;
public UnityAction<int, float, float> OnHit;
public override void Attack()
{
}
public override void Hit(float damage)
{
base.Hit(damage);
this.OnHit(this.Id, this.hp, this.maxHp);
this.anim.SetTrigger("GetHit");
}
public override void Die()
{
this.anim.SetTrigger("Die");
StartCoroutine(this.WaitForDieAnimation());
}
private IEnumerator WaitForDieAnimation()
{
yield return new WaitForSeconds(1.333f);
this.OnDieComplete();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class TestMonsterBase : MonoBehaviour
{
public int Id {
get;
protected set;
}
protected float hp;
protected float maxHp;
public UnityEvent<int> OnDieEvent = new UnityEvent<int>();
public System.Action OnDieComplete;
public virtual void Init(int id, float maxHp)
{
this.Id = id;
this.maxHp = maxHp;
this.hp = this.maxHp;
}
public virtual void Attack()
{
}
public virtual void Hit(float damage)
{
if (this.IsDie()) return;
this.hp -= damage;
if (this.hp <= 0) {
this.hp = 0;
this.OnDieEvent.Invoke(this.Id);
}
}
public bool IsDie() {
return this.hp <= 0;
}
public virtual void Die() { }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class TestMonsterBase : MonoBehaviour
{
public int Id {
get;
protected set;
}
protected float hp;
protected float maxHp;
public UnityEvent<int> OnDieEvent = new UnityEvent<int>();
public System.Action OnDieComplete;
public virtual void Init(int id, float maxHp)
{
this.Id = id;
this.maxHp = maxHp;
this.hp = this.maxHp;
}
public virtual void Attack()
{
}
public virtual void Hit(float damage)
{
if (this.IsDie()) return;
this.hp -= damage;
if (this.hp <= 0) {
this.hp = 0;
this.OnDieEvent.Invoke(this.Id);
}
}
public bool IsDie() {
return this.hp <= 0;
}
public virtual void Die() { }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestSlime : TestMonsterBase
{
public override void Hit(float damage)
{
base.Hit(damage);
Debug.Log("play hit animation");
this.transform.GetComponentInChildren<Animator>().SetTrigger("GetHit");
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestBeholder : TestMonsterBase
{
public override void Hit(float damage)
{
base.Hit(damage);
Debug.Log("play hit animation");
this.transform.GetComponentInChildren<Animator>().SetTrigger("GetHit");
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class TestHeroAttackImpactEvent : UnityEvent<TestMonsterBase, float>
{
}
public class TestHero : MonoBehaviour
{
private float damage = 11f;
private TestMonsterBase target;
public Animation anim;
//public System.Action OnAttackImpact;
//public System.Action OnAttackComplete;
//public UnityAction OnAttackImpact;
//public UnityAction OnAttackComplete;
public TestHeroAttackImpactEvent OnAttackImpactEvent = new TestHeroAttackImpactEvent();
//public UnityEvent OnAttackCompleteEvent = new UnityEvent();
public UnityAction<float> OnAttackComplete;
public void SetTarget(TestMonsterBase target)
{
this.target = target;
}
public void Attack(TestMonsterBase target)
{
if (target == null) return;
this.target = target;
this.anim.Play("attack_sword_01");
StartCoroutine(this.WaitForAttack());
}
private IEnumerator WaitForAttack()
{
yield return new WaitForSeconds(0.3f);
//이벤트
//this.OnAttackImpact();
OnAttackImpactEvent.Invoke(this.target, this.damage);
yield return new WaitForSeconds(0.733f - 0.3f);
this.OnAttackComplete(this.damage);
//this.OnAttackCompleteEvent.Invoke();
}
public void Idle()
{
this.target = null;
this.anim.Play("idle@loop");
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestAttackMain : MonoBehaviour
{
public UIInGame uiInGame;
public TestHero hero;
public TestSlime slime;
public TestBeholder beholder;
private List<TestMonsterBase> monsters;
void Start()
{
this.Init();
this.InitUI();
}
private void Init()
{
this.monsters = new List<TestMonsterBase>();
this.monsters.Add(this.slime);
this.monsters.Add(this.beholder);
this.hero.OnAttackImpactEvent.AddListener((target, damage) => {
target.Hit(damage);
});
this.hero.OnAttackComplete = (damage) => {
};
}
private void InitUI()
{
this.uiInGame.btn.onClick.AddListener(() => {
Debug.Log("find nearest monster");
var min = float.MaxValue;
TestMonsterBase target = null;
foreach (var monster in this.monsters)
{
var distance = Vector3.Distance(this.hero.transform.position, monster.transform.position);
if (min > distance)
{
min = distance;
target = monster;
}
}
Debug.Log(target);
Debug.DrawLine(this.hero.transform.position, target.transform.position, Color.red, 100);
this.hero.Attack(target);
});
}
}