forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Искусственный интеллект (http://forum.boolean.name/forumdisplay.php?f=171)
-   -   AI в Unity3D (http://forum.boolean.name/showthread.php?t=15775)

pie 04.11.2011 23:40

AI в Unity3D
 
Итак. Использовал Ваш урок на сайт как основу. Перевел код на JavaScripts. Вот что получилось.

Код:

// Make sure there is always a character controller
@script RequireComponent (CharacterController);

// скорость ходьбы и скорость поворота в секунду
var moveSpeed : float = 2;
var turnSpeed : float = 90;

private var _controller : CharacterController;
private var _thisTransform : Transform;
private var _playerTransform : Transform;

function Start()
    {
        // Получаем контроллер
        _controller = GetComponent(CharacterController);

        // Получаем компонент трансформации объекта, к которому привязан данный компонент
        _thisTransform = transform;

        // Получаем компонент трансформации игрока
        if (_playerTransform == null && GameObject.FindWithTag("Player"))
                        _playerTransform = GameObject.FindWithTag("Player").transform;
    }

// Все что связано с физикой выполняем в FixedUpdate
function Update()
    {
        // направление на игрока
        var playerDirection : Vector3 = (_playerTransform.position - _thisTransform.position).normalized;

        // угол поворота на игрока
        var angle : float = Vector3.Angle(_thisTransform.forward, playerDirection);

        // максимальный угол поворота на текущем кадре
        var maxAngle : float = turnSpeed * Time.deltaTime;

        // Вычисляем прямой поворот на игрока
        var rot : Quaternion = Quaternion.LookRotation(_playerTransform.position - _thisTransform.position);

        // поворачиваем врага на игрока с учетом скорости поворота
        if (maxAngle < angle)
        {
            _thisTransform.rotation = Quaternion.Slerp(_thisTransform.rotation, rot, maxAngle / angle);
        }
        else
        {
            _thisTransform.rotation = rot;
        }

        // если дистанция до игрока больше трех метров
        if (Vector3.Distance(_playerTransform.position, _thisTransform.position) > 3.0f)
        {
            // двигаемся к игроку
            _controller.Move(_thisTransform.forward * moveSpeed * Time.deltaTime);
        }
        else // если меньше или равна трем метрам
        {
            // здесь например стреляем в игрока
        }

        // гравитация
        _controller.Move(Vector3.down * 10.0f * Time.deltaTime);
    }

Вопрос в следующем. Как можно убрать что бы enemy не поворачивался к игроку, как бы, "вверх-вниз"

pax 04.11.2011 23:43

Ответ: AI в Unity3D
 
Наверное вот так (не тестировал):
PHP код:

// Вычисляем прямой поворот на игрока
        
var playerDir _playerTransform.position _thisTransform.position;
        
playerDir.y=0;
        var 
rot Quaternion Quaternion.LookRotation(playerDir); 


pie 04.11.2011 23:52

Ответ: AI в Unity3D
 
Спасибо. Помогло.
А как туда встроить проверку на видимость? Допустим у меня стена, пусть будет с тегом "wall". Нужно проводить луч от enemy к player и проверять не пересекает ли он wall?

pax 05.11.2011 00:09

Ответ: AI в Unity3D
 
На видимость можно проверять лучами да...
Вот тут пример проверки видимости с лучами был видит ли игрок объект, над которым надо текст написать:
http://forum.boolean.name/showthread.php?t=13332

pie 05.11.2011 13:22

Ответ: AI в Unity3D
 
Вложений: 1
С лучем никак не могу разобраться :(. Хотя движение к игроку уже сделано благодаря вам. Помогите кто нить с лучем в скрипте описанном выше.:SOS:

pax 05.11.2011 13:55

Ответ: AI в Unity3D
 
Самое первое приближение:
PHP код:

using UnityEngine;

public class 
Enemy MonoBehaviour
{
    
// скорость ходьбы и скорость поворота в секунду
    
public float moveSpeed 2;
    public 
float turnSpeed 90;

    private 
CharacterController _controller;
    private 
Transform _thisTransform;
    private 
Transform _playerTransform;

    
// преследуем или нет
    
private bool _isPursuit false;

    public 
void Start()
    {
        
// Получаем контроллер
        
_controller GetComponent<CharacterController>();

        
// Получаем компонент трансформации объекта, к которому привязан данный компонент
        
_thisTransform transform;

        
// Получаем компонент трансформации игрока
        
Player player = (Player)FindObjectOfType(typeof(Player));
        
_playerTransform player.transform;
    }

    
// Все что связано с физикой выполняем в FixedUpdate
    
public void FixedUpdate()
    {
        
// направление на игрока
        
Vector3 playerDirection = (_playerTransform.position _thisTransform.position).normalized;

        
// если не преследуем
        
if (!_isPursuit)
        {
            
// переменная для результата попадания
            
RaycastHit hit;
            
// луч
            
Ray ray = new Ray(transform.positionplayerDirection);

            
// тест попадания луча
            
if (Physics.Raycast(rayout hit))
            {
                
// рисуем луч для дебага
                
Debug.DrawLine(ray.originhit.pointColor.yellow);

                
// если попали в игрока, то начинаем преследование
                
if (hit.collider.GetComponent<Player>()!= null)
                {
                    
_isPursuit true;
                }
            }

            return;
        }



        
// угол поворота на игрока
        
float angle Vector3.Angle(_thisTransform.forwardplayerDirection);

        
// максимальный угол поворота на текущем кадре
        
float maxAngle turnSpeed Time.deltaTime;

        
// Вычисляем прямой поворот на игрока
        
var playerDir _playerTransform.position _thisTransform.position;
        
playerDir.0;
        var 
rot Quaternion.LookRotation(playerDir);

        
// поворачиваем врага на игрока с учетом скорости поворота
        
if (maxAngle angle)
        {
            
_thisTransform.rotation Quaternion.Slerp(_thisTransform.rotationrotmaxAngle angle);
        }
        else
        {
            
_thisTransform.rotation rot;
        }

        
// если дистанция до игрока больше трех метров
        
if (Vector3.Distance(_playerTransform.position_thisTransform.position) > 3.0f)
        {
            
// двигаемся к игроку
            
_controller.Move(_thisTransform.forward moveSpeed Time.deltaTime);
        }
        else 
// если меньше или равна трем метрам
        
{
            
// здесь например стреляем в игрока
        
}

        
// гравитация
        
_controller.Move(Vector3.down 10.0f Time.deltaTime);
    }



pax 05.11.2011 14:15

Ответ: AI в Unity3D
 
Веб демка этого примера (управление - стрелки или WSAD)
http://shgames.ru/unity/AI2/

pax 05.11.2011 15:19

Ответ: AI в Unity3D
 
Вложений: 1
Немного сложнее
PHP код:

using UnityEngine;

public class 
Enemy MonoBehaviour
{
    
// скорость ходьбы и скорость поворота в секунду
    
public float moveSpeed 2;
    public 
float turnSpeed 90;

    
// угол области видимости
    
public float visibleAreaAngle 120;
    
// дистанция видимости
    
public float visibleAreaDistance 15;

    private 
CharacterController _controller;
    private 
Transform _thisTransform;
    private 
Transform _playerTransform;

    private 
bool _isPursuit false;

    public 
void Start()
    {
        
// Получаем контроллер
        
_controller GetComponent<CharacterController>();

        
// Получаем компонент трансформации объекта, к которому привязан данный компонент
        
_thisTransform transform;

        
// Получаем компонент трансформации игрока
        
Player player = (Player)FindObjectOfType(typeof(Player));
        
_playerTransform player.transform;
    }

    
// Все что связано с физикой выполняем в FixedUpdate
    
public void FixedUpdate()
    {
        
// направление на игрока
        
Vector3 playerDirection = (_playerTransform.position _thisTransform.position).normalized;

        
// если не преследуем
        
if (!_isPursuit)
        {
            
// переменная для результата попадания
            
RaycastHit hit;
            
// луч
            
Ray ray = new Ray(transform.positionplayerDirection);

            
// тест попадания луча
            
if (Physics.Raycast(rayout hit))
            {
                
// рисуем луч для дебага
                
Debug.DrawLine(ray.originhit.pointColor.yellow);

                
// если попали в игрока, то начинаем преследование
                
if (hit.collider.GetComponent<Player>() != null)
                {
                    
// половина угла видимости
                    
var halfAngle visibleAreaAngle 2;

                    
// если угол между направлением врага и направлением на игрока входит в область видимости
                    // то начинаем преследование
                    
if (Vector3.Angle(transform.forwardplayerDirection) <= halfAngle)
                    {
                        
_isPursuit true;
                    }

                }
            }

            return;
        }



        
// угол поворота на игрока
        
float angle Vector3.Angle(_thisTransform.forwardplayerDirection);

        
// максимальный угол поворота на текущем кадре
        
float maxAngle turnSpeed Time.deltaTime;

        
// Вычисляем прямой поворот на игрока
        
var playerDir _playerTransform.position _thisTransform.position;
        
playerDir.0;
        var 
rot Quaternion.LookRotation(playerDir);

        
// поворачиваем врага на игрока с учетом скорости поворота
        
if (maxAngle angle)
        {
            
_thisTransform.rotation Quaternion.Slerp(_thisTransform.rotationrotmaxAngle angle);
        }
        else
        {
            
_thisTransform.rotation rot;
        }

        
// если дистанция до игрока больше трех метров
        
if (Vector3.Distance(_playerTransform.position_thisTransform.position) > 3.0f)
        {
            
// двигаемся к игроку
            
_controller.Move(_thisTransform.forward moveSpeed Time.deltaTime);
        }
        else 
// если меньше или равна трем метрам
        
{
            
// здесь например стреляем в игрока
        
}

        
// гравитация
        
_controller.Move(Vector3.down 10.0f Time.deltaTime);
    }


    
// рисуем область видимости
    
public void OnDrawGizmos()
    {
        var 
halfAngle visibleAreaAngle 2;
        var 
startDir Quaternion.AngleAxis(-halfAngleVector3.up) * transform.forward;

        var 
count Mathf.Max(1, (int)visibleAreaAngle 5);

        var 
stepRotation Quaternion.AngleAxis(visibleAreaAngle countVector3.up);

        
Gizmos.color = new Color(0.5f0.5f00.5f);

        
Gizmos.DrawLine(transform.positiontransform.position startDir visibleAreaDistance);

        var 
currentVector startDir;

        for (
int i 1<= counti++)
        {
            var 
prevPos transform.position currentVector visibleAreaDistance;
            
currentVector stepRotation currentVector;
            var 
curPos transform.position currentVector visibleAreaDistance;
            
Gizmos.DrawLine(transform.positioncurPos);
            
Gizmos.DrawLine(prevPoscurPos);
        }
    }


Чтобы снизить немного нагрузку - надо тестировать видимость не каждый апдейт физики.

pie 05.11.2011 16:14

Ответ: AI в Unity3D
 
Спасибо. Но вот я перевожу это дело в JS и у меня ругается на строчки некоторые (выделяю красным).

Код:

if (!_isPursuit)

        {

            // переменная для результата попадания

            var hit : RaycastHit;

           

            // луч

            var ray : Ray = new Ray(transform.position, playerDirection);



            // тест попадания луча

            if (Physics.Raycast(ray, out hit))

            {

                // рисуем луч для дебага

                Debug.DrawLine(ray.origin, hit.point, Color.yellow);



                // если попали в игрока, то начинаем преследование

                if (hit.collider.GetComponent<Player>() != null)

                {

                    // половина угла видимости

                    var halfAngle = visibleAreaAngle / 2;



                    // если угол между направлением врага и направлением на игрока входит в область видимости

                    // то начинаем преследование

                    if (Vector3.Angle(transform.forward, playerDirection) <= halfAngle)

                    {

                        _isPursuit = true;

                    }



                }

            }

            return;

        }

1. expecting ), found 'hit'. (BCE0044)
Unexpected token: ). (BCE0043)
2. expecting :, found ';'. (BCE0044)

pax 05.11.2011 16:18

Ответ: AI в Unity3D
 
Два варианта решения:
1. Забить на js (рекомендую)
2. Удалить out из первой строки

pie 05.11.2011 17:40

Ответ: AI в Unity3D
 
Ну ладно. На C# так на нем. Вот тут опечатка или нет?

Код:

Player player = (Player)FindObjectOfType(typeof(Player));
Потому что на эту строчку ругается.

pax 05.11.2011 17:41

Ответ: AI в Unity3D
 
Что пишет?

pie 05.11.2011 18:11

Ответ: AI в Unity3D
 
Вложений: 1
Вот.

pax 05.11.2011 18:13

Ответ: AI в Unity3D
 
Создай класс Player на C#
Если решил переходить на C#, то придется все скрипты переводить на C# ;)

tonic 10.12.2013 17:55

Ответ: AI в Unity3D
 
Я очень извиняюсь что поднимаю столь старую тему,
Но вот сейчас разбираюсь кодом в сообщении 8, и ни как не могу понять почему у меня враг не движется...
Ошибок не выдает, стоит на месте и крутится:(
Может подскажите в чем дело?
P.S. Сорь я все понял:)))


Часовой пояс GMT +4, время: 11:50.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot