유니티 기초
보스 추적 및 돌아가기
송현호
2023. 8. 14. 02:45
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MonsterController : MonoBehaviour
{
public float radius = 1f;
public float attackRange = 3f;
public float chaseDistance = 8f;
private Vector3 originalPosition;
private bool isChasing = false;
private bool isAttacking = false;
[SerializeField]
private GameObject target;
private Animator anim;
private float moveSpeed = 1f;
// Start is called before the first frame update
void Start()
{
this.anim = GetComponent<Animator>();
originalPosition = this.transform.position;
}
// Update is called once per frame
void Update()
{
float distance = Vector3.Distance(this.transform.position, target.transform.position);
if (distance < chaseDistance && distance > attackRange)
{
isChasing = true;
isAttacking = false;
this.anim.SetInteger("State", 1);
this.transform.LookAt(target.transform);
transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);
}
else if (distance <= attackRange)
{
isAttacking = true;
isChasing = false;
StartCoroutine(Attack());
}
else if (isChasing && distance >= chaseDistance)
{
this.transform.LookAt(originalPosition);
transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);
if (Vector3.Distance(originalPosition, this.transform.position) < 0.2f)
{
isChasing = false;
this.anim.SetInteger("State", 0);
}
}
}
private IEnumerator Attack()
{
this.anim.SetInteger("State", 2);
Debug.Log(123);
yield return new WaitForSeconds(2.5f);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HeroController : MonoBehaviour
{
private Animator anim;
private MonsterController target;
private Vector3 targetPosition;
private Coroutine moveRoutine;
public float radius = 1f;
public System.Action<MonsterController> onMoveComplete;
// Start is called before the first frame update
void Start()
{
this.anim = this.GetComponent<Animator>();
}
public void Move(MonsterController target)
{
this.target = target;
this.targetPosition = this.target.gameObject.transform.position;
this.anim.SetInteger("State", 1);
if (this.moveRoutine != null)
{
this.StopCoroutine(this.moveRoutine);
}
this.moveRoutine = this.StartCoroutine(this.CoMove());
}
public void Move(Vector3 targetPosition)
{
this.target = null;
this.targetPosition = targetPosition;
this.anim.SetInteger("State", 1);
if (this.moveRoutine != null)
{
this.StopCoroutine(this.moveRoutine);
}
this.moveRoutine = this.StartCoroutine(this.CoMove());
}
public IEnumerator CoMove()
{
while (true)
{
this.transform.LookAt(this.targetPosition);
this.transform.Translate(Vector3.forward * 2f * Time.deltaTime);
float distance = Vector3.Distance(this.transform.position, this.targetPosition);
if (this.target != null)
{
if (distance <= (1f + 1f))
{
break;
}
}
else
{
if (distance <= 0.1f)
{
break;
}
}
yield return null;
}
this.anim.SetInteger("State", 0);
this.onMoveComplete(this.target);
}
public void Attack(MonsterController target)
{
this.anim.SetInteger("State", 2);
this.StartCoroutine(this.CoAttack());
}
private IEnumerator CoAttack()
{
yield return new WaitForSeconds(0.1f);
yield return new WaitForSeconds(0.73f);
this.anim.SetInteger("State", 0);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BossRoomMain : MonoBehaviour
{
[SerializeField]
private HeroController heroController;
void Start()
{
this.heroController.onMoveComplete = (target) =>
{
Debug.LogFormat("<color=cyan>이동을 완료 했습니다. : {0}</color>", target);
//타겟이 있다면 공격 애니메이션 실행
if (target != null)
{
this.heroController.Attack(target);
}
};
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Debug.Log("down");
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
float maxDistance = 100f;
Debug.DrawRay(ray.origin, ray.direction * maxDistance, Color.red, 3f);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, maxDistance))
{
//클릭한 오브젝트가 몬스터라면
if (hit.collider.tag == "Monster")
{
//거리를 구한다
float distance = Vector3.Distance(this.heroController.gameObject.transform.position,
hit.collider.gameObject.transform.position);
MonsterController monsterController = hit.collider.gameObject.GetComponent<MonsterController>();
//각 반지름더한거와 비교
float sumRadius = this.heroController.radius + monsterController.radius;
Debug.LogFormat("{0}, {1}", distance, sumRadius);
//사거리 안에 들어옴
if (distance <= sumRadius)
{
//공격
}
else
{
//이동
this.heroController.Move(monsterController);
//this.heroController.Move(hit.point);
}
}
else if (hit.collider.tag == "Ground")
{
this.heroController.Move(hit.point);
}
}
}
}
}