구현 상황:
1. Boss의 탐지 범위 내에 Hero가 들어오면 Boss가 Hero를 따라감
2. Boss가 공격 범위 내에 Hero가 들어오면 Boss가 그자리에 멈춰서 Hero를 공격
3. Hero가 Boss의 탐지 범위 밖으로 벗어나면 초기 자리로 돌아가 초기 회전값 유지 (돌아갈 때는 탐지X)
using System.Collections;
using UnityEngine;
public class BossController : MonoBehaviour
{
public float detectionRange = 3f;
public float attackRange = 2f;
public float moveSpeed = 1f;
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;
}
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()
{
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()
{
float distanceToStart = Vector3.Distance(transform.position, initialPosition);
transform.LookAt(initialPosition);
if (distanceToStart < 0.1f)
{
state = 0;
this.transform.rotation = initialRotation;
return;
}
Vector3 moveDirection = (initialPosition - transform.position).normalized;
transform.position += moveDirection * moveSpeed * Time.deltaTime;
}
}
반응형
'KDT > 유니티 기초' 카테고리의 다른 글
동기와 비동기란 무엇일까? (0) | 2023.08.15 |
---|---|
[SimpleRPG] 보스전 구현(2) 탐지 범위 수정 (0) | 2023.08.14 |
[SimpleRPG] 보스 씬 전환 + 보스 탐지 범위와 공격 범위 구현 (0) | 2023.08.14 |
[SimpleRPG] 몬스터 클릭시 사망, 사망+이동 애니메이션, 아이템 드롭과 장착 (0) | 2023.08.10 |
[SimpleRPG] 몬스터 피격시 피격 이펙트 입히기 (0) | 2023.08.10 |