1. Boss의 탐지범위 안으로 Hero가 들어오면 탐지범위 2배로 증가
2. Boss의 탐지범위 밖으로 Hero가 나가면 탐지 범위 0으로 변환
3. Boss가 처음 자리로 돌아가면 탐지범위 초기 상태로 변
using System.Collections;
using UnityEngine;
public class BossController : MonoBehaviour
{
public float detectionRange = 6f;
public float attackRange = 2f;
public float moveSpeed = 1f;
private float initDetectRange;
private GameObject Hero;
private int state = 0;
private Animator animator;
private Quaternion initialRotation;
private Vector3 initialPosition;
private void Start()
{
animator = GetComponent<Animator>();
StartCoroutine(LateStart());
initialPosition = transform.position;
initialRotation = transform.rotation;
initDetectRange = detectionRange;
}
IEnumerator LateStart()
{
yield return new WaitForSeconds(0.1f);
Hero = GameObject.FindGameObjectWithTag("Hero");
}
private void Update()
{
if (Hero == null)
{
Hero = GameObject.FindGameObjectWithTag("Hero");
if (Hero == null)
{
Debug.LogError("Hero not found in the scene.");
return;
}
else
{
Debug.Log("Hero found.");
}
}
switch (state)
{
case 0:
Idle();
break;
case 1:
Chase();
break;
case 2:
Attack();
break;
case 3:
ReturnToStartPosition();
break;
}
animator.SetInteger("state", state);
}
void Idle()
{
float distance = Vector3.Distance(transform.position, Hero.transform.position);
if (distance <= detectionRange)
state = 1;
}
void Chase()
{
detectionRange = 12f;
float distance = Vector3.Distance(transform.position, Hero.transform.position);
if (distance > detectionRange)
{
state = 3;
return;
}
if (distance <= attackRange)
{
state = 2;
return;
}
Vector3 moveDirection = (Hero.transform.position - transform.position).normalized;
transform.LookAt(Hero.transform);
// 플레이어와의 거리와 다음 프레임에서의 이동 거리를 비교
float nextStepDistance = moveSpeed * Time.deltaTime;
if (distance > nextStepDistance) // 만약 이동 거리가 플레이어와의 거리보다 짧으면 이동
{
transform.position += moveDirection * nextStepDistance;
}
else // 그렇지 않다면, 플레이어 바로 앞에서 멈춤
{
transform.position = transform.position + moveDirection * distance;
}
}
void Attack()
{
float distance = Vector3.Distance(transform.position, Hero.transform.position);
if (distance > attackRange)
state = 1;
return;
}
public void SetHero(GameObject newHero)
{
Hero = newHero;
}
void ReturnToStartPosition()
{
detectionRange = 0f;
float distanceToStart = Vector3.Distance(transform.position, initialPosition);
transform.LookAt(initialPosition);
if (distanceToStart < 0.1f)
{
state = 0;
this.transform.rotation = initialRotation;
detectionRange = initDetectRange;
return;
}
Vector3 moveDirection = (initialPosition - transform.position).normalized;
transform.position += moveDirection * moveSpeed * Time.deltaTime;
}
private void OnDrawGizmos()
{
Gizmos.color = Color.yellow;
GizmosExtensions.DrawWireArc(this.transform.position, this.transform.forward, 360, this.detectionRange, 20);
Gizmos.color = Color.red;
GizmosExtensions.DrawWireArc(this.transform.position, this.transform.forward, 360, this.attackRange, 20);
}
}
반응형
'KDT > 유니티 기초' 카테고리의 다른 글
프로세스(Process), 스레드 (Thread) 그리고 코루틴 (Coroutine) (0) | 2023.08.15 |
---|---|
동기와 비동기란 무엇일까? (0) | 2023.08.15 |
[SimpleRPG] 보스전 구현 (1) (0) | 2023.08.14 |
[SimpleRPG] 보스 씬 전환 + 보스 탐지 범위와 공격 범위 구현 (0) | 2023.08.14 |
[SimpleRPG] 몬스터 클릭시 사망, 사망+이동 애니메이션, 아이템 드롭과 장착 (0) | 2023.08.10 |