Жертва,убегающая от игрока!

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

Жертва,убегающая от игрока!

Сообщение Nikitos47 14 авг 2014, 13:34

Здравствуйте,мне нужно сделать так,что бы жертва(в моем случае раненный дикарь,белки-шмелки,зайцы,и вся легка добыча тоже)убегала,когда я буду находится в ее радиусе.В этом проблемы нету,тригер прицеплю,но вот как сделать так что бы она убегела+(самое главное)обходила препятствия?Пытался прицепить скрипт какой-то побега жертвы к Nav Mesh,но увы,ничего не вышло.Как бежала прямо и врезалась в стены-так и врезается.Возможно у кого-то есть готовый скрипт,или же логика его создания.Слышал от тригерных поисках путей,но не представляю себе это.
Nikitos47
UNITрон
 
Сообщения: 256
Зарегистрирован: 03 авг 2013, 21:48

Re: Жертва,убегающая от игрока!

Сообщение bwolf88 14 авг 2014, 16:33

У меня в подписи конструктор с иходниками, там есть скрипт ботов преследующих игрока с примитивным обходом небольших препятствий "EnemyAI".
Поскольку движение там реализовано простым Transform.forward и бот просто поворачивается к игроку, то измени угол поворота на произвольный. И он будет убегать.

Чтобы останавливался после убегания - измени dist на 20 или сколько нужно.
Может еще чего нужно будет подкорректить, вообщем скрипт не сложный и писался пару месяцев назад, а переписывать самому лень, так что разребетесь :) .
Сюда периодически чего нибудь выкладываю https://github.com/LuchunPen
Аватара пользователя
bwolf88
Адепт
 
Сообщения: 2184
Зарегистрирован: 30 апр 2014, 06:40
Skype: bwolf331

Re: Жертва,убегающая от игрока!

Сообщение Nikitos47 15 авг 2014, 20:03

bwolf88 писал(а):У меня в подписи конструктор с иходниками, там есть скрипт ботов преследующих игрока с примитивным обходом небольших препятствий "EnemyAI".
Поскольку движение там реализовано простым Transform.forward и бот просто поворачивается к игроку, то измени угол поворота на произвольный. И он будет убегать.

Чтобы останавливался после убегания - измени dist на 20 или сколько нужно.
Может еще чего нужно будет подкорректить, вообщем скрипт не сложный и писался пару месяцев назад, а переписывать самому лень, так что разребетесь :) .

Спасибо большое!Что-то получается,но всё равно не пойму что изменять.Вроде убегает,а потом начинает тупить,ничего не обходит,и от препятствия к препятствию ходит....
Nikitos47
UNITрон
 
Сообщения: 256
Зарегистрирован: 03 авг 2013, 21:48

Re: Жертва,убегающая от игрока!

Сообщение bwolf88 15 авг 2014, 20:11

В таком случае можно в скрипт добавить еще один луч, который будет бить в рандомную сторону, снимайте точку на расстоянии скажем 20 м
Ray.GetPoint(20);
и ставьте ее в качестве таргета, тогда бот будет следовать к ней, обходя препятствия, а по достижении остановится.
Сюда периодически чего нибудь выкладываю https://github.com/LuchunPen
Аватара пользователя
bwolf88
Адепт
 
Сообщения: 2184
Зарегистрирован: 30 апр 2014, 06:40
Skype: bwolf331

Re: Жертва,убегающая от игрока!

Сообщение Nikitos47 15 авг 2014, 20:19

bwolf88 писал(а):В таком случае можно в скрипт добавить еще один луч, который будет бить в рандомную сторону, снимайте точку на расстоянии скажем 20 м
Ray.GetPoint(20);
и ставьте ее в качестве таргета, тогда бот будет следовать к ней, обходя препятствия, а по достижении остановится.

Хорошо,побробую что то сделать,ну а пока что нифига не доходит.Завтра постараюсь разобратся в рандомной точке.Если будет свободное время-пожалуйста,напишите примерные строчки для рандомного луча,и что бы он был таргетом.Спасибо.
Nikitos47
UNITрон
 
Сообщения: 256
Зарегистрирован: 03 авг 2013, 21:48

Re: Жертва,убегающая от игрока!

Сообщение bwolf88 15 авг 2014, 21:03

Примерно так:

Синтаксис:
Используется csharp

int rRot = Random.Range(80,240); //рандомный угол поворота персонажа
Ray runRay;
Vector3 target; //уже есть в скрипте

myTrans.rotation *= Quaternion.Euler(new Vector3(0, rRot, 0)); //приравниваем его к повороту по y
//после поворота выпускаем луч вперед
runRay = new Ray(transform.position, transform.forward);

//дальше ловим точку на 20м, присваиваем ее к цели и запускаем движение
target = runRay.GetPoint(20);

 
Сюда периодически чего нибудь выкладываю https://github.com/LuchunPen
Аватара пользователя
bwolf88
Адепт
 
Сообщения: 2184
Зарегистрирован: 30 апр 2014, 06:40
Skype: bwolf331

Re: Жертва,убегающая от игрока!

Сообщение Nikitos47 16 авг 2014, 12:12

bwolf88 писал(а):Примерно так:

Синтаксис:
Используется csharp

int rRot = Random.Range(80,240); //рандомный угол поворота персонажа
Ray runRay;
Vector3 target; //уже есть в скрипте

myTrans.rotation *= Quaternion.Euler(new Vector3(0, rRot, 0)); //приравниваем его к повороту по y
//после поворота выпускаем луч вперед
runRay = new Ray(transform.position, transform.forward);

//дальше ловим точку на 20м, присваиваем ее к цели и запускаем движение
target = runRay.GetPoint(20);

 

Ужс,если не сам скрипт не пишешь-значит ничего не понять :| Вставил строчки в Апдейт,а в итоге персонажа дергается в разные стороны,сам он на месте,а таргет как был Плээр,так и остался...Ошибок после запуска в логе видно не было...Ну что ж,спасибо но придется искать что-то другое,разбираться самому с этим,или же просто додуматься самому :3
Nikitos47
UNITрон
 
Сообщения: 256
Зарегистрирован: 03 авг 2013, 21:48

Re: Жертва,убегающая от игрока!

Сообщение bwolf88 16 авг 2014, 16:05

Вам просто нужно подучить что к чему, почитать справку. Как я уже писал, скрипт не сложный, я его писал через месяц после начала изучения C# и Unity.
Вообщем сам допилил немножко.



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

public class EnemyAIRun : MonoBehaviour {

        public AnimationClip a_idle;
        public AnimationClip a_walk;
        public AnimationClip a_run;
        public AnimationClip a_jump;

        //public Transform target;
        public Vector3 target;
        public int moveSpeed;
        public float rotationSpeed;
        float corutTimer;
        float dist;
        float rRot;
       
        Ray ray, rayUp, rayDown, rayDownLeft, rayDownRight, rayRight, rayLeft, rayRun;
        RaycastHit hit, hitDown, hitRight, hitLeft;

        Vector3 p, p1;

        bool startCast;
        bool turnedAccess;
        int tempTurn;

        Animation anim;
        private Transform myTrans;

        void Awake()
        {      
                turnedAccess = true;
                myTrans = transform;
                moveSpeed = Mathf.RoundToInt(Random.Range(6,8.5f));
                rotationSpeed = moveSpeed * 0.5f;
                corutTimer = 0.3f/moveSpeed;
                startCast = true;
                anim = this.GetComponent<Animation>();
        }

        void Start () {
                GameObject go = GameObject.FindGameObjectWithTag("Player");
                //target = go.transform;
                StartCoroutine(OrientationEnemy());
        }
       
        // Update is called once per frame
        void Update () {
                        RunFromPlayer ();
        }

        void RunFromPlayer()
        {       if (target != Vector3.zero)
                {
                        if (dist > 2)
                        {      
                                if (Physics.Raycast(rayDown, out hitDown, 2)){
                                        if (turnedAccess)
                                        {
                                                Quaternion rawRotation = Quaternion.Slerp(myTrans.rotation,
                                                                                             Quaternion.LookRotation(target - myTrans.position),
                                                                                         rotationSpeed*Time.deltaTime);
                                                myTrans.rotation = new Quaternion(0, rawRotation.y, 0, rawRotation.w);
                                        }

                                        myTrans.position += myTrans.forward * moveSpeed * Time.deltaTime;
                                }else
                                {
                                        myTrans.rotation *= Quaternion.Euler(new Vector3(0, -45, 0));
                                }

                                       
                        }
                        else
                        {
                                anim.Play (a_idle.name);
                        }
                }else anim.Play (a_idle.name);
        }

        IEnumerator OrientationEnemy()
        {       while (startCast){
                        yield return new WaitForSeconds(corutTimer);
                        //проверяем дистанцию до цели
                        if (target !=null)
                        {
                                dist = Vector3.Distance(myTrans.position, target);
                        }
                        //проверяем наличие поверхности под телом
                        rayDown = new Ray (transform.position, transform.forward + Vector3.down);
                        rayDownLeft = new Ray (transform.position, -transform.right + Vector3.down);
                        rayDownRight = new Ray (transform.position, transform.right + Vector3.down);
                        //если дистанция до цели больше и есть поверхность делаем проверки для определения непроходимых мест
                        if (dist > 2 && Physics.Raycast(rayDown, out hitDown, 2))
                        {       //луч вперед из центра
                                ray =  new Ray(transform.position, transform.forward);
                                //луч около головы
                                rayUp = new Ray (transform.position + Vector3.up*0.5f, transform.forward);

                                //проверяем левую и правую сторону
                                rayRight = new Ray (transform.position + Vector3.down * 0.5f, transform.right + Vector3.up*0.5f);
                                rayLeft = new Ray (transform.position + Vector3.down * 0.5f, -transform.right + Vector3.up*0.5f);

                                if (Physics.Raycast(rayRight, out hitRight, 2) && hitRight.collider.name !="Enemy" || Physics.Raycast(rayLeft, out hitLeft, 2) && hitLeft.collider.name !="Enemy")
                                {
                                        turnedAccess = false;
                                }
                                else
                                {      
                                        if (Physics.Raycast(rayDownLeft, out hitDown, 2) && Physics.Raycast(rayDownRight, out hitDown, 2))
                                                turnedAccess = true;
                                }

                                if ((Physics.Raycast(ray, out hit, 2) && hit.collider.name == "Collider") || (Physics.Raycast(rayUp, out hit, 2) && hit.collider.name !="Enemy"))
                                {              
                                        tempTurn = Mathf.RoundToInt(Random.Range(0,1.9f));
                                        if (tempTurn == 0) myTrans.rotation *= Quaternion.Euler(new Vector3(0, -45, 0));
                                        else myTrans.rotation *= Quaternion.Euler(new Vector3(0, 45, 0));

                                        /*if (hitRight.collider != null && hitLeft.collider == null)
                                        {
                                                myTrans.rotation *= Quaternion.Euler(new Vector3(0, 45, 0));
                                        }
                                        else if (hitLeft.collider != null && hitRight.collider == null)
                                        {
                                                myTrans.rotation *= Quaternion.Euler(new Vector3(0, -45, 0));
                                        }
                                        else {
                                                tempTurn = Mathf.RoundToInt(Random.Range(0,1.9f));
                                                if (tempTurn == 0) myTrans.rotation *= Quaternion.Euler(new Vector3(0, -45, 0));
                                                else myTrans.rotation *= Quaternion.Euler(new Vector3(0, 45, 0));
                                        }*/

                                       
                                }
                                //отрисовка линий для теста
                                Debug.DrawRay(transform.position + Vector3.up*0.5f, transform.forward);
                                Debug.DrawRay(transform.position, transform.forward);
                                Debug.DrawRay(transform.position, transform.forward*2 + Vector3.down*2);
                                Debug.DrawRay(transform.position + Vector3.down * 0.5f, transform.right + Vector3.up*0.5f);
                                Debug.DrawRay(transform.position + Vector3.down * 0.5f, -transform.right + Vector3.up*0.5f);

                                if (target != Vector3.zero)
                                anim.Play(a_run.name);
                        }
                }
        }

        void OnTriggerEnter(Collider other)
        {
                if (other.name == "Player") {
                        rRot = Random.Range (0, 270); //рандомный кгол поворота для убегания
                        myTrans.rotation *= Quaternion.Euler(new Vector3(0, rRot, 0));
                        rayRun = new Ray (myTrans.position, transform.forward*30);
                        target = rayRun.GetPoint(30); //точка в качестве таргета
                }
        }

}

 
Сюда периодически чего нибудь выкладываю https://github.com/LuchunPen
Аватара пользователя
bwolf88
Адепт
 
Сообщения: 2184
Зарегистрирован: 30 апр 2014, 06:40
Skype: bwolf331

Re: Жертва,убегающая от игрока!

Сообщение Nikitos47 16 авг 2014, 23:16

bwolf88 писал(а):Вам просто нужно подучить что к чему, почитать справку. Как я уже писал, скрипт не сложный, я его писал через месяц после начала изучения C# и Unity.
Вообщем сам допилил немножко.



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

public class EnemyAIRun : MonoBehaviour {

        public AnimationClip a_idle;
        public AnimationClip a_walk;
        public AnimationClip a_run;
        public AnimationClip a_jump;

        //public Transform target;
        public Vector3 target;
        public int moveSpeed;
        public float rotationSpeed;
        float corutTimer;
        float dist;
        float rRot;
       
        Ray ray, rayUp, rayDown, rayDownLeft, rayDownRight, rayRight, rayLeft, rayRun;
        RaycastHit hit, hitDown, hitRight, hitLeft;

        Vector3 p, p1;

        bool startCast;
        bool turnedAccess;
        int tempTurn;

        Animation anim;
        private Transform myTrans;

        void Awake()
        {      
                turnedAccess = true;
                myTrans = transform;
                moveSpeed = Mathf.RoundToInt(Random.Range(6,8.5f));
                rotationSpeed = moveSpeed * 0.5f;
                corutTimer = 0.3f/moveSpeed;
                startCast = true;
                anim = this.GetComponent<Animation>();
        }

        void Start () {
                GameObject go = GameObject.FindGameObjectWithTag("Player");
                //target = go.transform;
                StartCoroutine(OrientationEnemy());
        }
       
        // Update is called once per frame
        void Update () {
                        RunFromPlayer ();
        }

        void RunFromPlayer()
        {       if (target != Vector3.zero)
                {
                        if (dist > 2)
                        {      
                                if (Physics.Raycast(rayDown, out hitDown, 2)){
                                        if (turnedAccess)
                                        {
                                                Quaternion rawRotation = Quaternion.Slerp(myTrans.rotation,
                                                                                             Quaternion.LookRotation(target - myTrans.position),
                                                                                         rotationSpeed*Time.deltaTime);
                                                myTrans.rotation = new Quaternion(0, rawRotation.y, 0, rawRotation.w);
                                        }

                                        myTrans.position += myTrans.forward * moveSpeed * Time.deltaTime;
                                }else
                                {
                                        myTrans.rotation *= Quaternion.Euler(new Vector3(0, -45, 0));
                                }

                                       
                        }
                        else
                        {
                                anim.Play (a_idle.name);
                        }
                }else anim.Play (a_idle.name);
        }

        IEnumerator OrientationEnemy()
        {       while (startCast){
                        yield return new WaitForSeconds(corutTimer);
                        //проверяем дистанцию до цели
                        if (target !=null)
                        {
                                dist = Vector3.Distance(myTrans.position, target);
                        }
                        //проверяем наличие поверхности под телом
                        rayDown = new Ray (transform.position, transform.forward + Vector3.down);
                        rayDownLeft = new Ray (transform.position, -transform.right + Vector3.down);
                        rayDownRight = new Ray (transform.position, transform.right + Vector3.down);
                        //если дистанция до цели больше и есть поверхность делаем проверки для определения непроходимых мест
                        if (dist > 2 && Physics.Raycast(rayDown, out hitDown, 2))
                        {       //луч вперед из центра
                                ray =  new Ray(transform.position, transform.forward);
                                //луч около головы
                                rayUp = new Ray (transform.position + Vector3.up*0.5f, transform.forward);

                                //проверяем левую и правую сторону
                                rayRight = new Ray (transform.position + Vector3.down * 0.5f, transform.right + Vector3.up*0.5f);
                                rayLeft = new Ray (transform.position + Vector3.down * 0.5f, -transform.right + Vector3.up*0.5f);

                                if (Physics.Raycast(rayRight, out hitRight, 2) && hitRight.collider.name !="Enemy" || Physics.Raycast(rayLeft, out hitLeft, 2) && hitLeft.collider.name !="Enemy")
                                {
                                        turnedAccess = false;
                                }
                                else
                                {      
                                        if (Physics.Raycast(rayDownLeft, out hitDown, 2) && Physics.Raycast(rayDownRight, out hitDown, 2))
                                                turnedAccess = true;
                                }

                                if ((Physics.Raycast(ray, out hit, 2) && hit.collider.name == "Collider") || (Physics.Raycast(rayUp, out hit, 2) && hit.collider.name !="Enemy"))
                                {              
                                        tempTurn = Mathf.RoundToInt(Random.Range(0,1.9f));
                                        if (tempTurn == 0) myTrans.rotation *= Quaternion.Euler(new Vector3(0, -45, 0));
                                        else myTrans.rotation *= Quaternion.Euler(new Vector3(0, 45, 0));

                                        /*if (hitRight.collider != null && hitLeft.collider == null)
                                        {
                                                myTrans.rotation *= Quaternion.Euler(new Vector3(0, 45, 0));
                                        }
                                        else if (hitLeft.collider != null && hitRight.collider == null)
                                        {
                                                myTrans.rotation *= Quaternion.Euler(new Vector3(0, -45, 0));
                                        }
                                        else {
                                                tempTurn = Mathf.RoundToInt(Random.Range(0,1.9f));
                                                if (tempTurn == 0) myTrans.rotation *= Quaternion.Euler(new Vector3(0, -45, 0));
                                                else myTrans.rotation *= Quaternion.Euler(new Vector3(0, 45, 0));
                                        }*/

                                       
                                }
                                //отрисовка линий для теста
                                Debug.DrawRay(transform.position + Vector3.up*0.5f, transform.forward);
                                Debug.DrawRay(transform.position, transform.forward);
                                Debug.DrawRay(transform.position, transform.forward*2 + Vector3.down*2);
                                Debug.DrawRay(transform.position + Vector3.down * 0.5f, transform.right + Vector3.up*0.5f);
                                Debug.DrawRay(transform.position + Vector3.down * 0.5f, -transform.right + Vector3.up*0.5f);

                                if (target != Vector3.zero)
                                anim.Play(a_run.name);
                        }
                }
        }

        void OnTriggerEnter(Collider other)
        {
                if (other.name == "Player") {
                        rRot = Random.Range (0, 270); //рандомный кгол поворота для убегания
                        myTrans.rotation *= Quaternion.Euler(new Vector3(0, rRot, 0));
                        rayRun = new Ray (myTrans.position, transform.forward*30);
                        target = rayRun.GetPoint(30); //точка в качестве таргета
                }
        }

}

 

Огромное спасибо за уделенное время!Надеюсь это сработает,и будут нормальные животные :3
Nikitos47
UNITрон
 
Сообщения: 256
Зарегистрирован: 03 авг 2013, 21:48


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

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

Сейчас этот форум просматривают: Google [Bot], Yandex [Bot] и гости: 7