13일날 작업한거 복구
EnemyAI
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyAI : MonoBehaviour
{
public enum State{
PATROL,
TRACE,
ATTACK,
DIE
}
public State state = State.PATROL;
private Transform playerTr;
private Transform enemyTr;
// Animator 컴포넌트를 저장할 변수
private Animator animator;
public float attackDist = 5.0f;
public float traceDist = 10.0f;
public bool isDie = false;
private WaitForSeconds ws;
// 이동을 제어하는 MoveAgent클래스 저장할 변수
private MoveAgent moveAgent;
private EnemyFire enemyFire;
// 애니메이터 컨트롤러에 정의한 파라미터 해시값 미리 추출
private readonly int hashMove = Animator.StringToHash("IsMove");
private readonly int hashSpeed = Animator.StringToHash("Speed");
private readonly int hashDie = Animator.StringToHash("Die");
private readonly int hashDieIdx = Animator.StringToHash("DieIdx");
private readonly int hashOffset = Animator.StringToHash("Offset");
private readonly int hashWalkSpeed = Animator.StringToHash("WalkSpeed");
private void Awake(){
var player = GameObject.FindGameObjectWithTag("Player");
if (player != null) playerTr = player.GetComponent<Transform>();
enemyTr = GetComponent<Transform>();
moveAgent = GetComponent<MoveAgent>();
animator = GetComponent<Animator>();
enemyFire = GetComponent<EnemyFire>();
ws = new WaitForSeconds(0.3f);
animator.SetFloat(hashOffset, Random.Range(0.0f,1.0f));
animator.SetFloat(hashWalkSpeed, Random.Range(1.0f,1.2f));
}
private void OnEnable(){
StartCoroutine(CheckState());
StartCoroutine(Action());
}
IEnumerator Action(){
while(!isDie){
yield return ws;
// 상태에 따라 분기처리
switch(state){
case State.PATROL:
// 총알발사정지
enemyFire.isFire = false;
moveAgent.patrolling = true;
animator.SetBool(hashMove, true);
break;
case State.TRACE:
enemyFire.isFire = false;
moveAgent.traceTarget = playerTr.position;
animator.SetBool(hashMove, true);
break;
case State.ATTACK:
moveAgent.Stop();
animator.SetBool(hashMove, false);
if(enemyFire.isFire == false) enemyFire.isFire = true;
break;
case State.DIE:
isDie = true;
enemyFire.isFire = false;
moveAgent.Stop();
int ran = Random.Range(0,3);
Debug.Log(ran);
animator.SetInteger(hashDieIdx,ran);
animator.SetTrigger(hashDie);
GetComponent<CapsuleCollider>().enabled = false;
break;
}
}
}
IEnumerator CheckState(){
while(!isDie){
if(state == State.DIE) yield break;
float dist = Vector3.Distance(playerTr.position, enemyTr.position);
if (dist <=attackDist){
state = State.ATTACK;
}
else if(dist <=traceDist){
state = State.TRACE;
}
else{
state = State.PATROL;
}
yield return ws;
}
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
animator.SetFloat(hashSpeed, moveAgent.speed);
}
}
MoveAgent
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class MoveAgent : MonoBehaviour
{
//순찰 지점들을 저장하기 위한 List 타입 변수
public List<Transform> wayPoints;
//다음 순찰 지점의 배열 Index
public int nextIdx = 0;
//NavMeshAgent 컴포넌트를 저장할 변수
private NavMeshAgent agent;
private Transform enemyTr;
private readonly float patrollSpeed = 1.5f;
private readonly float traceSpeed = 4.0f;
private float damping = 1.0f;
// 순찰 여부를 판단하는 변수
private bool _patrolling;
// patrolling 프로퍼티 정의
public bool patrolling{
get{return _patrolling;}
set{
_patrolling = value;
if(_patrolling){
agent.speed = patrollSpeed;
damping = 1.0f;
MoveWayPoint();
}
}
}
// 추적 대상의 위치를 저장하는 변수
private Vector3 _traceTarget;
public Vector3 traceTarget{
get{return _traceTarget;}
set{
_traceTarget = value;
agent.speed = traceSpeed;
damping = 7.0f;
TraceTarget(_traceTarget);
}
}
public float speed{
get{return agent.velocity.magnitude;}
}
void TraceTarget(Vector3 pos){
if(agent.isPathStale) return;
agent.destination = pos;
agent.isStopped = false;
}
// Start is called before the first frame update
void Start()
{
enemyTr = GetComponent<Transform>();
agent = GetComponent<NavMeshAgent>();
agent.autoBraking = false;
agent.speed = patrollSpeed;
// 자동으로 회전하는 기능을 비 활성화
agent.updateRotation = false;
var group = GameObject.Find("WayPointGroup2");
if(group != null)
{
group.GetComponentsInChildren<Transform>(wayPoints);
wayPoints.RemoveAt(0);
nextIdx = Random.Range(0,wayPoints.Count);
}
MoveWayPoint();
}
private void MoveWayPoint()
{
//최단거리 경로 계산이 끝나지 않았으면 다음을 수행하지 않음
if (agent.isPathStale) return;
//다음 목적지를 wayPoints 배열에서 추출한 위치로 지정
agent.destination = wayPoints[nextIdx].position;
agent.isStopped = false;
}
public void Stop(){
agent.isStopped = true;
// 바로 정지하기 위해 속도 0
agent.velocity = Vector3.zero;
_patrolling = false;
}
// Update is called once per frame
void Update()
{
if(agent.isStopped ==false){
// NavMeshAgent가 가야 할 방향 벡터를 쿼터니언 타입의 각도로 변환
Quaternion rot = Quaternion.LookRotation(agent.desiredVelocity);
// 보간 함수를 사용해 점진적으로 회전시킴
enemyTr.rotation = Quaternion.Slerp(enemyTr.rotation, rot,
Time.deltaTime * damping);
}
if(!_patrolling) return;
//NavMeshAgent가 이동하고 있고 목적지에 도착했는지 여부를 계산
if(agent.velocity.sqrMagnitude >= 0.2f * 0.2f && agent.remainingDistance <= 0.5f)
{
//다음 목적지의 배열 첨자를 계산
//nextIdx = ++nextIdx % wayPoints.Count;
nextIdx = Random.Range(0,wayPoints.Count);
//다음 목적지로 이동 명령을 수행
MoveWayPoint();
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class MoveAgent : MonoBehaviour
{
//순찰 지점들을 저장하기 위한 List 타입 변수
public List<Transform> wayPoints;
//다음 순찰 지점의 배열 Index
public int nextIdx = 0;
//NavMeshAgent 컴포넌트를 저장할 변수
private NavMeshAgent agent;
private Transform enemyTr;
private readonly float patrollSpeed = 1.5f;
private readonly float traceSpeed = 4.0f;
private float damping = 1.0f;
// 순찰 여부를 판단하는 변수
private bool _patrolling;
// patrolling 프로퍼티 정의
public bool patrolling{
get{return _patrolling;}
set{
_patrolling = value;
if(_patrolling){
agent.speed = patrollSpeed;
damping = 1.0f;
MoveWayPoint();
}
}
}
// 추적 대상의 위치를 저장하는 변수
private Vector3 _traceTarget;
public Vector3 traceTarget{
get{return _traceTarget;}
set{
_traceTarget = value;
agent.speed = traceSpeed;
damping = 7.0f;
TraceTarget(_traceTarget);
}
}
public float speed{
get{return agent.velocity.magnitude;}
}
void TraceTarget(Vector3 pos){
if(agent.isPathStale) return;
agent.destination = pos;
agent.isStopped = false;
}
// Start is called before the first frame update
void Start()
{
enemyTr = GetComponent<Transform>();
agent = GetComponent<NavMeshAgent>();
agent.autoBraking = false;
agent.speed = patrollSpeed;
// 자동으로 회전하는 기능을 비 활성화
agent.updateRotation = false;
var group = GameObject.Find("WayPointGroup2");
if(group != null)
{
group.GetComponentsInChildren<Transform>(wayPoints);
wayPoints.RemoveAt(0);
nextIdx = Random.Range(0,wayPoints.Count);
}
MoveWayPoint();
}
private void MoveWayPoint()
{
//최단거리 경로 계산이 끝나지 않았으면 다음을 수행하지 않음
if (agent.isPathStale) return;
//다음 목적지를 wayPoints 배열에서 추출한 위치로 지정
agent.destination = wayPoints[nextIdx].position;
agent.isStopped = false;
}
public void Stop(){
agent.isStopped = true;
// 바로 정지하기 위해 속도 0
agent.velocity = Vector3.zero;
_patrolling = false;
}
// Update is called once per frame
void Update()
{
if(agent.isStopped ==false){
// NavMeshAgent가 가야 할 방향 벡터를 쿼터니언 타입의 각도로 변환
Quaternion rot = Quaternion.LookRotation(agent.desiredVelocity);
// 보간 함수를 사용해 점진적으로 회전시킴
enemyTr.rotation = Quaternion.Slerp(enemyTr.rotation, rot,
Time.deltaTime * damping);
}
if(!_patrolling) return;
//NavMeshAgent가 이동하고 있고 목적지에 도착했는지 여부를 계산
if(agent.velocity.sqrMagnitude >= 0.2f * 0.2f && agent.remainingDistance <= 0.5f)
{
//다음 목적지의 배열 첨자를 계산
//nextIdx = ++nextIdx % wayPoints.Count;
nextIdx = Random.Range(0,wayPoints.Count);
//다음 목적지로 이동 명령을 수행
MoveWayPoint();
}
}
}