unity-29: AI만들기3
공격받으면 Player를 쫓아가기
void OnMouseDown()
{
Debug.Log("hit");
GameObject player = GameObject.FindGameObjectWithTag("Player");
_isBattle= true;
ChangedAction(eActionState.RUN);
_navAgent.destination = player.transform.position;
}
_navAgent.stoppingDistance = 0;
_navAgent.stoppingDistance = 4; //run일떄는 4만큼떨어지기
case eActionState.RUN:
if (Vector3.Distance(_navAgent.destination, transform.position) <= 0.1f)
{
_isBattle= false; //Player에게 가서 도착하면 다시 제자리로
_isSelectAi = false;
}
break;
플레이어에게 다가가서 공격하기
case eActionState.RUN:
if (Vector3.Distance(_posTarget, transform.position) <= 3.1f)
{
ChangedAction(eActionState.ATTACK);
}
else
{
ChangedAction(eActionState.RUN);
}
break;
case eActionState.ATTACK:
//_isBattle = false;
//_isSelectAi = false;
break;
void OnMouseDown()
{
Debug.Log("hit");
GameObject player = GameObject.FindGameObjectWithTag("Player");
ChangedAction(eActionState.RUN);
_isBattle= true;
_posTarget= player.transform.position;
_navAgent.destination = _posTarget;
}
최종
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class ZombieController : MonoBehaviour
{
public enum eActionState
{
IDLE =0,
WALK,
RUN,
ATTACK,
HIT,
}
public enum eCharacter
{
Fierce = 0,
lazy
}
[SerializeField] float _limitX = 5;
[SerializeField] float _limitZ = 5;
[SerializeField] float _moveSpeed; //뛰는 스피드
[SerializeField] float _walkSpeed; //걷는 스피드
[SerializeField] BoxCollider _damageZone;
public eCharacter _eCh;
public float _minTime = 2;
public float _maxTime = 7;
eActionState _stateAction;
Animator _ctrlAni;
Vector3 _posTarget;
float _Speed; //최종 스피드
bool _isDeath; //플래그 (키고 끄고 할수있는 작용
bool _isAttack;
NavMeshAgent _navAgent;
Vector3 _startPos; //cube상에서의 중심 위치 = center
float _timeWait;
bool _isSelectAi;
int _characterStd;
bool _isBattle;
private void Awake()
{
_isDeath = false; //초기화
_isAttack = false; //초기화
_ctrlAni = GetComponent<Animator>();
_navAgent = GetComponent<NavMeshAgent>(); // 좀비에 있는 navmeshagent를 가져옴
_startPos = _posTarget = transform.position;
_timeWait = 0;
_isSelectAi = false;
_characterStd= 0;
_isBattle = false;
}
void Start()
{
switch (_eCh)
{
case eCharacter.Fierce:
_characterStd = 25;
break;
case eCharacter.lazy:
_characterStd = 80;
break;
}
}
private void Update()
{
if (_isDeath)
return;
switch (_stateAction)
{
case eActionState.IDLE:
_timeWait -= Time.deltaTime; //시간이 깎여나가야함
if(_timeWait< 0) //기다리는 시간이 다 지나면
{
//다시 선택
_isSelectAi = false;
}
break;
case eActionState.WALK:
if (Vector3.Distance(_posTarget, transform.position) <= 0.1f)
{
//다시선택
_isSelectAi = false;
}
break;
case eActionState.RUN:
if (Vector3.Distance(_posTarget, transform.position) <= 3.1f)
{
ChangedAction(eActionState.ATTACK);
}
else
{
ChangedAction(eActionState.RUN);
}
break;
case eActionState.ATTACK:
//_isBattle = false;
//_isSelectAi = false;
break;
}
ProceesAI();
}
void ProceesAI()
{
if (!_isSelectAi&&!_isBattle)
{
int r = Random.Range(0, 100); //(이상,미만: 0, 1만 나옴)
if (r <_characterStd)
{ //IDLE
ChangedAction(eActionState.IDLE);
_timeWait = Random.Range(_minTime, _maxTime);
}
else if(r>_characterStd)
{ //WALK
ChangedAction(eActionState.WALK);
_posTarget = GetRandomPos(_startPos, _limitX, _limitZ);
_navAgent.destination = _posTarget;
}
_isSelectAi = true;
}
}
Vector3 GetRandomPos(Vector3 center, float limitX, float limitZ) //좀비가 움직일 임의의 위치를 반환
{
float rX = Random.Range(-limitX, limitX); //센터를 중심으로 -5, +5 사이에서 x좌표 랜덤값 (이상,이하)
float rZ = Random.Range(-limitZ, limitZ); //센터를 중심으로 -5, +5 사이에서 z좌표 랜덤값
Vector3 rv = new Vector3(rX,0,rZ);
return center+ rv; //center가 있어야 cube에서의 중심점에서 x,z에 따라 움직임
}
void ChangedAction(eActionState state)
{
switch (state) //애니메이션이 바뀌는 곳에서 속도를 변경 해주는게 직관적임
{
case eActionState.WALK: //walk일때 최종스피드에다가 워크스피드를 넣어줌
if (_stateAction != eActionState.ATTACK)
{
_navAgent.speed = _walkSpeed;
_navAgent.stoppingDistance = 0;
_ctrlAni.SetInteger("AniState", (int)_stateAction);
_stateAction = state;
}
break;
case eActionState.RUN:
_navAgent.speed = _moveSpeed;
_ctrlAni.SetInteger("AniState", (int)_stateAction);
_stateAction = state;
_navAgent.stoppingDistance = 3;
break;
case eActionState.ATTACK: //모든것이 변하는 곳에 공격할때는 isAttack을 킴
if (_stateAction == eActionState.RUN)
{
_isAttack = true;
_ctrlAni.SetInteger("AniState", (int)_stateAction);
_stateAction = state;
}
break;
case eActionState.HIT: //맞으면 isDeath를 킴
_isDeath = true;
_ctrlAni.SetInteger("AniState", (int)_stateAction);
_stateAction = state;
break;
case eActionState.IDLE:
_ctrlAni.SetInteger("AniState", (int)_stateAction);
_stateAction = state;
break;
}
_stateAction = state;
_ctrlAni.SetInteger("AniState", (int)_stateAction);
}
void DamageOn()
{
_damageZone.enabled = true;
}
void DamageOff()
{
_damageZone.enabled = false;
}
void OnMouseDown()
{
Debug.Log("hit");
GameObject player = GameObject.FindGameObjectWithTag("Player");
ChangedAction(eActionState.RUN);
_isBattle= true;
_posTarget= player.transform.position;
_navAgent.destination = _posTarget;
}
}
댓글남기기