 |
04.11.2011, 23:40
|
#1
|
ПроЭктировщик
Регистрация: 04.11.2011
Сообщений: 176
Написано 19 полезных сообщений (для 64 пользователей)
|
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 не поворачивался к игроку, как бы, "вверх-вниз"
|
(Offline)
|
|
04.11.2011, 23:43
|
#2
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: AI в Unity3D
Наверное вот так (не тестировал):
// Вычисляем прямой поворот на игрока var playerDir = _playerTransform.position - _thisTransform.position; playerDir.y=0; var rot : Quaternion = Quaternion.LookRotation(playerDir);
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
04.11.2011, 23:52
|
#3
|
ПроЭктировщик
Регистрация: 04.11.2011
Сообщений: 176
Написано 19 полезных сообщений (для 64 пользователей)
|
Ответ: AI в Unity3D
Спасибо. Помогло.
А как туда встроить проверку на видимость? Допустим у меня стена, пусть будет с тегом "wall". Нужно проводить луч от enemy к player и проверять не пересекает ли он wall?
|
(Offline)
|
|
05.11.2011, 00:09
|
#4
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: AI в Unity3D
На видимость можно проверять лучами да...
Вот тут пример проверки видимости с лучами был видит ли игрок объект, над которым надо текст написать:
http://forum.boolean.name/showthread.php?t=13332
|
(Offline)
|
|
05.11.2011, 13:22
|
#5
|
ПроЭктировщик
Регистрация: 04.11.2011
Сообщений: 176
Написано 19 полезных сообщений (для 64 пользователей)
|
Ответ: AI в Unity3D
С лучем никак не могу разобраться  . Хотя движение к игроку уже сделано благодаря вам. Помогите кто нить с лучем в скрипте описанном выше. 
|
(Offline)
|
|
05.11.2011, 13:55
|
#6
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: AI в Unity3D
Самое первое приближение:

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.position, playerDirection);
// тест попадания луча if (Physics.Raycast(ray, out hit)) { // рисуем луч для дебага Debug.DrawLine(ray.origin, hit.point, Color.yellow);
// если попали в игрока, то начинаем преследование if (hit.collider.GetComponent<Player>()!= null) { _isPursuit = true; } }
return; }
// угол поворота на игрока float angle = Vector3.Angle(_thisTransform.forward, playerDirection);
// максимальный угол поворота на текущем кадре float maxAngle = turnSpeed * Time.deltaTime;
// Вычисляем прямой поворот на игрока var playerDir = _playerTransform.position - _thisTransform.position; playerDir.y = 0; var rot = Quaternion.LookRotation(playerDir);
// поворачиваем врага на игрока с учетом скорости поворота 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); } }
|
(Offline)
|
|
05.11.2011, 14:15
|
#7
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: AI в Unity3D
Веб демка этого примера (управление - стрелки или WSAD)
http://shgames.ru/unity/AI2/
|
(Offline)
|
|
05.11.2011, 15:19
|
#8
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: AI в Unity3D
Немного сложнее

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.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; }
// угол поворота на игрока float angle = Vector3.Angle(_thisTransform.forward, playerDirection);
// максимальный угол поворота на текущем кадре float maxAngle = turnSpeed * Time.deltaTime;
// Вычисляем прямой поворот на игрока var playerDir = _playerTransform.position - _thisTransform.position; playerDir.y = 0; var rot = Quaternion.LookRotation(playerDir);
// поворачиваем врага на игрока с учетом скорости поворота 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); }
// рисуем область видимости public void OnDrawGizmos() { var halfAngle = visibleAreaAngle / 2; var startDir = Quaternion.AngleAxis(-halfAngle, Vector3.up) * transform.forward;
var count = Mathf.Max(1, (int)visibleAreaAngle / 5);
var stepRotation = Quaternion.AngleAxis(visibleAreaAngle / count, Vector3.up);
Gizmos.color = new Color(0.5f, 0.5f, 0, 0.5f);
Gizmos.DrawLine(transform.position, transform.position + startDir * visibleAreaDistance);
var currentVector = startDir;
for (int i = 1; i <= count; i++) { var prevPos = transform.position + currentVector * visibleAreaDistance; currentVector = stepRotation * currentVector; var curPos = transform.position + currentVector * visibleAreaDistance; Gizmos.DrawLine(transform.position, curPos); Gizmos.DrawLine(prevPos, curPos); } } }
Чтобы снизить немного нагрузку - надо тестировать видимость не каждый апдейт физики.
|
(Offline)
|
|
05.11.2011, 16:14
|
#9
|
ПроЭктировщик
Регистрация: 04.11.2011
Сообщений: 176
Написано 19 полезных сообщений (для 64 пользователей)
|
Ответ: 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)
|
(Offline)
|
|
05.11.2011, 16:18
|
#10
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: AI в Unity3D
Два варианта решения:
1. Забить на js (рекомендую)
2. Удалить out из первой строки
|
(Offline)
|
|
05.11.2011, 17:40
|
#11
|
ПроЭктировщик
Регистрация: 04.11.2011
Сообщений: 176
Написано 19 полезных сообщений (для 64 пользователей)
|
Ответ: AI в Unity3D
Ну ладно. На C# так на нем. Вот тут опечатка или нет?
Player player = (Player)FindObjectOfType(typeof(Player));
Потому что на эту строчку ругается.
|
(Offline)
|
|
05.11.2011, 17:41
|
#12
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: AI в Unity3D
Что пишет?
|
(Offline)
|
|
05.11.2011, 18:11
|
#13
|
ПроЭктировщик
Регистрация: 04.11.2011
Сообщений: 176
Написано 19 полезных сообщений (для 64 пользователей)
|
Ответ: AI в Unity3D
Вот.
|
(Offline)
|
|
05.11.2011, 18:13
|
#14
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: AI в Unity3D
Создай класс Player на C#
Если решил переходить на C#, то придется все скрипты переводить на C# 
|
(Offline)
|
|
10.12.2013, 17:55
|
#15
|
AnyKey`щик
Регистрация: 04.12.2013
Сообщений: 8
Написано 2 полезных сообщений (для 2 пользователей)
|
Ответ: AI в Unity3D
Я очень извиняюсь что поднимаю столь старую тему,
Но вот сейчас разбираюсь кодом в сообщении 8, и ни как не могу понять почему у меня враг не движется...
Ошибок не выдает, стоит на месте и крутится 
Может подскажите в чем дело?
P.S. Сорь я все понял  ))
|
(Offline)
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 05:22.
|