ИИ c#

Программирование на Юнити.

ИИ c#

Сообщение Gamer_Jack5 09 июн 2017, 16:19

*Только учусь, поэтому ошибка может быть глупой...
У меня есть такой игровой обьект как "Волк", он должен гнаться за игроком если тот входит в его триггер, а также уходить на свою точку дома если игрок вышел из триггера, также в игре имеется ракетница, и волк должен убегать(пока на точку дома), если выстрел произошел в зоне его триггера, но он это упорно не делает....
*Скрипты сырые и недоработанные, представляют из себя примерный план, позже уже доработаю, пока делаю ток основные функции.
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;

public class AI : MonoBehaviour {
        public UnityEngine.AI.NavMeshAgent Agent;
        public Transform Home;
        public Transform Player;
        public int CurrentO;
       
        void Update () {
                if (CurrentO == 0) {
                        GetComponent<Animation> ().Play ("Idle");
                }
                if (CurrentO == 1) {
                        GetComponent<Animation> ().Play ("Walk");
                        Agent.SetDestination (Home.position);
                }
                if (CurrentO == 2) {
                        GetComponent<Animation> ().Play ("Running");
                        Agent.SetDestination (Player.position);
                }
        }
}



 

Синтаксис:
Используется csharp
using System.Collections;
using UnityEngine;



public class Gun : MonoBehaviour {

public Transform Bulletpref;
public Transform Pivot;
public int Ammo;
public AudioClip ShoоtAudio;

public int Hit;

        // Use this for initialization
        void Start () {
                Ammo = 6;

        }
       
        // Update is called once per frame
        void Update () {

                if (Ammo < 0) {
                        Ammo = 0;
                }
                if (Ammo > 6) {
                        Ammo = 6;
                }



if (Input.GetMouseButtonDown(0)){
Ammo = Ammo - 1;
}

         
         
                 
         

                if (Input.GetMouseButtonDown(0) && Ammo >= 0 && Ammo <= 6 ){
                        Instantiate (Bulletpref,Pivot.position,Pivot.rotation);
                        Hit = 1;
                    gameObject.GetComponent<AudioSource>().clip = ShoоtAudio;
                        gameObject.GetComponent<AudioSource>().Play();
                }
                else {
                        Hit = 0;
                }

        }
}

 

Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;

public class Attack : MonoBehaviour {
        public AI _AI;
        public Gun hit;

        void OnTriggerEnter(Collider Player){
                if (Player.gameObject.tag == "Player") {
                        _AI.CurrentO = 2;
         }
        }
        void OnTriggerExit(Collider Player){
                if (Player.gameObject.tag == "Player") {
                        _AI.CurrentO = 1;
                }
        }


        void OnTriggerStay(Collider Player)
        {
                  if(Player.gameObject.tag == "Player" && hit.Hit == 1) {
                  _AI.CurrentO = 1;
                  }
                               
        }
}

 


Что-то писал сам, что-то нашел на просторах интернета
Gamer_Jack5
UNец
 
Сообщения: 39
Зарегистрирован: 04 апр 2017, 20:09

Re: ИИ c#

Сообщение Xtir 10 июн 2017, 21:58

Тяжёлый случай ) Вы вообще не по правильному пути пошли, тут нужно всё переделывать )
Xtir
UNIверсал
 
Сообщения: 498
Зарегистрирован: 21 окт 2016, 00:37

Re: ИИ c#

Сообщение Gamer_Jack5 11 июн 2017, 11:57

Xtir писал(а):Тяжёлый случай ) Вы вообще не по правильному пути пошли, тут нужно всё переделывать )


Подтолкните на верный путь исправления, перепишу все если надо, время и хотение научиться имеются.
Gamer_Jack5
UNец
 
Сообщения: 39
Зарегистрирован: 04 апр 2017, 20:09

Re: ИИ c#

Сообщение samana 11 июн 2017, 13:14

Вы можете создать некие состояния волка, чтобы в зависимости от них - давать нужные команды.
Например, если по-проще, скрипт волка
Синтаксис:
Используется csharp
using UnityEngine;
using UnityEngine.AI;

public class Wolf : MonoBehaviour
{
    public Transform home;
    public Transform player;

    private NavMeshAgent _agent;
    private Animation _animation;

    enum WolfState // виды состояния волка
    {
        None,
        GoToPlayer,
        GoToHome,
        RunToHome,
    }

    private WolfState state = WolfState.None; // текущее состояние волка

    void Start()
    {
        _agent = GetComponent<NavMeshAgent>();
        _animation = GetComponent<Animation>();

        _animation.Play("Idle");
    }

    private void Update()
    {
        if (state == WolfState.GoToPlayer)          //если надо преследовать игрока
        {
            _agent.SetDestination(player.position);
            _animation.Play("Walk");
        }
        else if (state == WolfState.GoToHome)       //если надо идти домой
        {
            _agent.SetDestination(home.position);
            _animation.Play("Walk");
        }
        else if (state == WolfState.RunToHome)      //если надо бежать домой (от бомбы)
        {
            _agent.SetDestination(home.position);
            _animation.Play("Running");
        }
    }

    private void OnTriggerEnter(Collider collider)
    {
        if (collider.CompareTag("Player"))      //если наткнулись на игрока, то идём за ним
        {
            state = WolfState.GoToPlayer;
            return;
        }
        else if (collider.CompareTag("bomb"))   //если наткнулись на бомбу, то убегаем домой
        {
            state = WolfState.RunToHome;
            return;
        }

    }

    private void OnTriggerExit(Collider collider)
    {
        // спорный момент - если волк убегает от бомбы домой и игрок выходит из треггера волка в этот момент,
        // то волк должен продолжать бежать или начать спокойно идти в дом?

        //если игрок вышел из поля зрения волка и волк НЕ убегает от бомбы, то волк идёт домой.
        //иначе волк бежит от бомбы домой игнорируя игрока
        if (collider.CompareTag("Player") && state != WolfState.RunToHome)
        {
            state = WolfState.GoToHome;
        }

        //если игрок вышел из триггера волка, а тот убегал от бомбы домой, то волк просто начинает идти домой, а не бежать
        //if (collider.CompareTag("Player"))
        //{
        //    state = WolfState.GoToHome;
        //}
    }

}
 


А это скрипт выстрела:
Синтаксис:
Используется csharp
using UnityEngine;

public class Gun : MonoBehaviour
{
    public Transform bulletPrefab;
    public Transform bulletPivot;
    public int ammo = 6;

    public AudioClip shoоtAudio;

    private AudioSource _audioSource;

    void Start()
    {
        _audioSource = GetComponent<AudioSource>();
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            if (ammo > 0)
            {
                ammo--;
                Instantiate(bulletPrefab, bulletPivot.position, bulletPivot.rotation);
                _audioSource.PlayOneShot(shoоtAudio);
            }
        }
    }
}
 


Код не совсем проверил на работоспособность, поэтому возможно там ошибки.
Здесь подразумевается, что у бомбы есть тег "bomb".
Аватара пользователя
samana
Адепт
 
Сообщения: 4738
Зарегистрирован: 21 фев 2015, 13:00
Откуда: Днепропетровск

Re: ИИ c#

Сообщение Cr0c 12 июн 2017, 07:45

samana писал(а):возможно там ошибки.

Каждый кадр запускать анимацию не стоит. Лучше сделать метод задания стейта SetState и в нём проверять текущий.
Аватара пользователя
Cr0c
Адепт
 
Сообщения: 3035
Зарегистрирован: 19 июн 2015, 13:50
Skype: cr0c81

Re: ИИ c#

Сообщение Xtir 12 июн 2017, 11:29

А ещё, в классе Gun должна быть объявлена переменная
Синтаксис:
Используется csharp
Wolf wolf;

или массив
Синтаксис:
Используется csharp
List<Wolf> wolfArray = new List<Wolf>()

куда будут записываться волки попавшие в триггер. И уже при выстреле давать команду волкам прятаться, как-то так.
Xtir
UNIверсал
 
Сообщения: 498
Зарегистрирован: 21 окт 2016, 00:37

Re: ИИ c#

Сообщение samana 12 июн 2017, 17:37

Cr0c писал(а):
samana писал(а):возможно там ошибки.

Каждый кадр запускать анимацию не стоит. Лучше сделать метод задания стейта SetState и в нём проверять текущий.

Согласен. Вообще вот в этом примере писал состояния на if-ах и так сложно было, намного легче для моего восприятия сделать всё через паттерн "состояние", хоть и кода больше.
Аватара пользователя
samana
Адепт
 
Сообщения: 4738
Зарегистрирован: 21 фев 2015, 13:00
Откуда: Днепропетровск

Re: ИИ c#

Сообщение samana 12 июн 2017, 17:39

Xtir писал(а):А ещё, в классе Gun должна быть объявлена переменная
Синтаксис:
Используется csharp
Wolf wolf;

или массив
Синтаксис:
Используется csharp
List<Wolf> wolfArray = new List<Wolf>()

куда будут записываться волки попавшие в триггер. И уже при выстреле давать команду волкам прятаться, как-то так.


Да, можно и так. Вообще вариантов масса.
Аватара пользователя
samana
Адепт
 
Сообщения: 4738
Зарегистрирован: 21 фев 2015, 13:00
Откуда: Днепропетровск

Re: ИИ c#

Сообщение Gamer_Jack5 16 авг 2017, 15:06

Вариант с состояниями мне понравился, но опять столкнулся с ошибкой, написал простенький скрипт для рандомного перемещение моба, работает довольно неплохо(для моего проекта достаточно)
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class AI_TEST : MonoBehaviour {

private NavMeshAgent Agent;
public Vector3 TargetPoint;


        void Start()
        {
                Agent = GetComponent<NavMeshAgent>();
                Invoke("ChangePosition", 0.0f);
        }
       
 
     void ChangePosition()
     {
         TargetPoint = new Vector3(Random.Range(-50.0F, 50.0F), 0, Random.Range(-50.5F, 50.5F));
     }
 
     void Update ()
     {
        if(Agent != null)
                {
            Agent.SetDestination(TargetPoint);
                }
                if (Vector3.Distance(gameObject.transform.position, TargetPoint)<=5f)
                {
                       
                        ChangePosition();
                }
         }

}
 


Попытался перенести его в ваш скрипт, немного подредактировав все под себя, но он упорно не хочет двигаться на "TargetPoint", после старта у "Монстра" включается состояние "FindWay" и "TargetPoint" тоже выбирает рандомные координаты, только вот наш монстр идет в определенную точку и больше не двигается(что это за точка понять не могу, она всегда по определенным координатам, но они нигде не прописаны)

Синтаксис:
Используется csharp
using UnityEngine;
using UnityEngine.AI;

public class AI : MonoBehaviour
{
    public Transform Home;
    public Transform Player;
        public Vector3 TargetPoint;

    private NavMeshAgent Agent;
        private Animation Animation;

        public MonsterState State;

    public enum MonsterState
    {
                None,
        Attack,
        RunToHome,
        FindWay
    }
        MonsterState state = MonsterState.None;

 

    void Start()
    {
        Agent = GetComponent<NavMeshAgent>();
        Animation = GetComponent<Animation>();
                State = MonsterState.FindWay;
                ChangePosition();

               

   
    }

     void ChangePosition()
     {
         TargetPoint = new Vector3(Random.Range(-150.0F, 150.0F), 0, Random.Range(-150.5F, 150.5F));
     }
    private void Update()
    {
        if (state == MonsterState.Attack)          
        {
            Agent.SetDestination(Player.position);
            Animation.Play("Run");
        }
        else if (state == MonsterState.RunToHome)      
        {
            Agent.SetDestination(Home.position);
            Animation.Play("Run");
        }  
        if (state == MonsterState.FindWay)      
        {
                if(Agent != null)
                        {
            Agent.SetDestination(TargetPoint);
                        }
                        if (Vector3.Distance(gameObject.transform.position, TargetPoint)<=5f)
                        {
                        ChangePosition();
                        }

        }
    }



}
 


Почитал я немного про enum, но все понять не могу, зачем нужна строчка
Синтаксис:
Используется csharp
        MonsterState state = MonsterState.None;


Спасибо если смогли дочитать это до конца...
Gamer_Jack5
UNец
 
Сообщения: 39
Зарегистрирован: 04 апр 2017, 20:09

Re: ИИ c#

Сообщение samana 16 авг 2017, 21:08

Gamer_Jack5 писал(а):Попытался перенести его в ваш скрипт, немного подредактировав все под себя, но он упорно не хочет двигаться на "TargetPoint", после старта у "Монстра" включается состояние "FindWay" и "TargetPoint" тоже выбирает рандомные координаты, только вот наш монстр идет в определенную точку и больше не двигается

Честно говоря не могу сообразить, почему возникает такая проблема, на вид код вроде должен работать нормально.

Gamer_Jack5 писал(а):Почитал я немного про enum, но все понять не могу, зачем нужна строчка
MonsterState state = MonsterState.None;


Я уже точно и не помню, кажется это надо было для того, когда у волка нет никаких заданий куда либо бежать. Например он возвращался домой, дошел до дома и всё, двигаться больше никуда не нужно.
Аватара пользователя
samana
Адепт
 
Сообщения: 4738
Зарегистрирован: 21 фев 2015, 13:00
Откуда: Днепропетровск

Re: ИИ c#

Сообщение Gamer_Jack5 20 авг 2017, 20:32

Cr0c писал(а):
samana писал(а):возможно там ошибки.

Каждый кадр запускать анимацию не стоит. Лучше сделать метод задания стейта SetState и в нём проверять текущий.


Можно поподробнее, не могу найти ничего на эту тему, а лучше несколько ссылок на информацию об этом)
Gamer_Jack5
UNец
 
Сообщения: 39
Зарегистрирован: 04 апр 2017, 20:09

Re: ИИ c#

Сообщение Cr0c 20 авг 2017, 21:38

Да просто не в каждом кадре запускать агента и анимацию, а только при смене стейта
Аватара пользователя
Cr0c
Адепт
 
Сообщения: 3035
Зарегистрирован: 19 июн 2015, 13:50
Skype: cr0c81

Re: ИИ c#

Сообщение danquimby 04 сен 2017, 14:30

Ну или введи еще состояние к примеру Action
при каждом изменении состояния переводи в состояние Action
ты просто постоянно агенту говоришь на изменить на др координату
так низя с ним поступать
Почитай доки по нему, ссылку где то я уже кидал.
Пока компьютер еще не научился самостоятельно мыслить, доверять ему можно
Аватара пользователя
danquimby
UNIт
 
Сообщения: 54
Зарегистрирован: 29 янв 2015, 21:33
Откуда: Иваново
Skype: danquimby
  • Сайт


Вернуться в Скрипты

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7