Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;
[RequireComponent (typeof(Movement))]
[RequireComponent (typeof(SphereCollider))]
public class AISimple : MonoBehaviour {
public enum State{
Idle,
Init,
Setup,
Search,
Atack,
Retreat, //отступить
Flee //шляться
}
public Transform target;
public float baseMeleerange = 2; //расстояние до цели при котором движение прекращается
public float perseptionRadious = 10; //настройка радиуса видения цели
public Transform _home; //место отступления после потери цели
private State _state;
private Transform _myTransform;
private const float ROTATION_DAMP = 0.1f;
private const float FORWARD_DAMP = 0.9f;
private SphereCollider _sphereCollider;
void Start (){
_state = AISimple.State.Init;
StartCoroutine("AI");
}
private IEnumerator AI(){
while(true){
switch(_state){
case State.Init:
Init();
break;
case State.Setup:
Setup();
break;
case State.Search:
Search();
break;
case State.Atack:
Atack();
break;
case State.Retreat:
Retreat();
break;
case State.Flee:
Flee();
break;
}
yield return null;
}
}
private void Init(){
_myTransform = transform;
//генератор точки возврата
_home = Instantiate(_home,transform.position,transform.rotation) as Transform;
_sphereCollider = GetComponent<SphereCollider>();
if(_sphereCollider == null){
Debug.LogError("No sphere collider");
return;
}
_state = AISimple.State.Setup;
}
private void Setup(){
//устанавливаем колайдер сферы по центру персонажа и устанавливаем радиус в нужное значение
_sphereCollider.center = GetComponent<CharacterController>().center;
_sphereCollider.radius = perseptionRadious;
_sphereCollider.isTrigger = true;
//установка следующего состояния
_state = AISimple.State.Search;
target = null;
}
//это состояние поиска и принятия решения по тому как атаковать цель и когда бежать за ней
private void Search(){
Move();
_state = AISimple.State.Atack;
}
//пока атака заключается в простом приближении к цели
private void Atack(){
Move();
_state = AISimple.State.Retreat;
}
//состояние отхода назад. Возврата. Но в этом блоке пока минимум функционала
private void Retreat(){
Move();
_state = AISimple.State.Search;
}
//пока невыполняемый блок, но планируется имитация жизни
private void Flee(){
Move();
_state = AISimple.State.Search;
}
public void Move(){
if(target){
//вычисляется направление к цели
Vector3 dir = (target.position - _myTransform.position).normalized;
//определение положения цели относительно нас
//если 0 до 1 - перед нами если 0 до -1 - позади нас
float direction = Vector3.Dot (dir,transform.forward);
float dist = Vector3.Distance(target.position,_myTransform.position);
if(direction >FORWARD_DAMP && dist > baseMeleerange){
SendMessage("MoveMeForward",Movement.Forward.forward);
}
else{
SendMessage("MoveMeForward",Movement.Forward.none);
}
//вычисляется направление к цели
dir = (target.position - _myTransform.position).normalized;
//определение положения цели относительно нас
//если 0 до 1 - перед нами если 0 до -1 - позади нас
direction = Vector3.Dot (dir,transform.right);
if(direction > ROTATION_DAMP){
SendMessage("RotateMe",Movement.Turn.right);
}
else if(direction < -ROTATION_DAMP){
SendMessage("RotateMe",Movement.Turn.left);
}
else{
SendMessage("RotateMe",Movement.Turn.none);
}
}
//цель потеряна из зоны действия
else{
SendMessage("MoveMeForward",Movement.Forward.none);
}
}
public void OnTriggerEnter(Collider other){
if(other.CompareTag("Player")){
target = other.transform;
//пока _alive = false мы ничего не делаем и не имеем цели
//_alive = true;
StartCoroutine("AI");
}
}
public void OnTriggerExit(Collider other){
if(other.CompareTag("Player")){
//передается другая цель - возврат к начальной точке старта
target = _home;
}
}
}
using System.Collections;
[RequireComponent (typeof(Movement))]
[RequireComponent (typeof(SphereCollider))]
public class AISimple : MonoBehaviour {
public enum State{
Idle,
Init,
Setup,
Search,
Atack,
Retreat, //отступить
Flee //шляться
}
public Transform target;
public float baseMeleerange = 2; //расстояние до цели при котором движение прекращается
public float perseptionRadious = 10; //настройка радиуса видения цели
public Transform _home; //место отступления после потери цели
private State _state;
private Transform _myTransform;
private const float ROTATION_DAMP = 0.1f;
private const float FORWARD_DAMP = 0.9f;
private SphereCollider _sphereCollider;
void Start (){
_state = AISimple.State.Init;
StartCoroutine("AI");
}
private IEnumerator AI(){
while(true){
switch(_state){
case State.Init:
Init();
break;
case State.Setup:
Setup();
break;
case State.Search:
Search();
break;
case State.Atack:
Atack();
break;
case State.Retreat:
Retreat();
break;
case State.Flee:
Flee();
break;
}
yield return null;
}
}
private void Init(){
_myTransform = transform;
//генератор точки возврата
_home = Instantiate(_home,transform.position,transform.rotation) as Transform;
_sphereCollider = GetComponent<SphereCollider>();
if(_sphereCollider == null){
Debug.LogError("No sphere collider");
return;
}
_state = AISimple.State.Setup;
}
private void Setup(){
//устанавливаем колайдер сферы по центру персонажа и устанавливаем радиус в нужное значение
_sphereCollider.center = GetComponent<CharacterController>().center;
_sphereCollider.radius = perseptionRadious;
_sphereCollider.isTrigger = true;
//установка следующего состояния
_state = AISimple.State.Search;
target = null;
}
//это состояние поиска и принятия решения по тому как атаковать цель и когда бежать за ней
private void Search(){
Move();
_state = AISimple.State.Atack;
}
//пока атака заключается в простом приближении к цели
private void Atack(){
Move();
_state = AISimple.State.Retreat;
}
//состояние отхода назад. Возврата. Но в этом блоке пока минимум функционала
private void Retreat(){
Move();
_state = AISimple.State.Search;
}
//пока невыполняемый блок, но планируется имитация жизни
private void Flee(){
Move();
_state = AISimple.State.Search;
}
public void Move(){
if(target){
//вычисляется направление к цели
Vector3 dir = (target.position - _myTransform.position).normalized;
//определение положения цели относительно нас
//если 0 до 1 - перед нами если 0 до -1 - позади нас
float direction = Vector3.Dot (dir,transform.forward);
float dist = Vector3.Distance(target.position,_myTransform.position);
if(direction >FORWARD_DAMP && dist > baseMeleerange){
SendMessage("MoveMeForward",Movement.Forward.forward);
}
else{
SendMessage("MoveMeForward",Movement.Forward.none);
}
//вычисляется направление к цели
dir = (target.position - _myTransform.position).normalized;
//определение положения цели относительно нас
//если 0 до 1 - перед нами если 0 до -1 - позади нас
direction = Vector3.Dot (dir,transform.right);
if(direction > ROTATION_DAMP){
SendMessage("RotateMe",Movement.Turn.right);
}
else if(direction < -ROTATION_DAMP){
SendMessage("RotateMe",Movement.Turn.left);
}
else{
SendMessage("RotateMe",Movement.Turn.none);
}
}
//цель потеряна из зоны действия
else{
SendMessage("MoveMeForward",Movement.Forward.none);
}
}
public void OnTriggerEnter(Collider other){
if(other.CompareTag("Player")){
target = other.transform;
//пока _alive = false мы ничего не делаем и не имеем цели
//_alive = true;
StartCoroutine("AI");
}
}
public void OnTriggerExit(Collider other){
if(other.CompareTag("Player")){
//передается другая цель - возврат к начальной точке старта
target = _home;
}
}
}