Автор Тема: Unity3D Rus Tutorials - Simple AI \ Простой ИИ  (Прочитано 28609 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Июнь 21, 2012, 20:36:24 pm
Прочитано 28609 раз

Alcatraz

  • Администратор
  • Старожил форума

  • Оффлайн
  • *****

  • 1851
  • Репутация:
    123
    • Просмотр профиля
    • Flight Dream Studio
Unity3D Rus Tutorials - Simple AI \ Простой ИИ

Создание простого ИИ на Unity3D + NavMesh.

Автор : Алексей Дудкин a.k.a. Alcatraz | Flight Dream Studio

<a href="http://www.youtube.com/watch?v=aMV2okCphMU" target="_blank">http://www.youtube.com/watch?v=aMV2okCphMU</a>

Код:

var idleAnimation : AnimationClip;
var walkAnimation : AnimationClip;
var attackAnimation : AnimationClip;
var hp : float = 100.0f;
var dead : GameObject;
var damage : float = 3.5f;
var delay : float = 1.0f;
private var time : float;

function Start () {
animation.AddClip(idleAnimation, "idle");
animation.AddClip(walkAnimation, "walk");
animation.AddClip(attackAnimation, "attack");
target = GameObject.FindWithTag("Player").transform;
nav = GetComponent(NavMeshAgent);
}

function ApplyDamage(d : float) {
hp -=d;
if(hp<=0) {
Instantiate(dead, transform.position, transform.rotation);
Destroy(gameObject);
}
}

function Update () {

if(Vector3.Distance(transform.position, target.transform.position) < seeDistance) {
if(Vector3.Distance(transform.position, target.transform.position) > attackDistance) {
animation.CrossFade("walk");
nav.enabled = true;
nav.SetDestination(target.position);
}else{
if(Time.time > time) {
animation.CrossFade("attack");
nav.enabled = false;
target.SendMessage("ApplyDamage", damage, SendMessageOptions.DontRequireReceiver);
time = Time.time + delay;
}

}
}else{
animation.CrossFade("idle");
nav.enabled = false;
}

}
« Последнее редактирование: Июль 31, 2013, 22:59:27 pm от Alcatraz »

Август 04, 2012, 17:52:33 pm
Ответ #1

Laxdinboy

  • Новичок

  • Оффлайн
  • *

  • 6
  • Репутация:
    0
    • Просмотр профиля
1) А ты не мог бы выложить своего перса? А то сделал все как в ролике, но скачал персов с инета, и не один не пашет, хз почему... Может быть твой персонаж сделан по другому... Или из-за того что у меня Terrain стоит, хотя вряд ли, т.к. я его в Navigation нажал на Bake...
2) И еще такой вопрос, скачиваю я допустим какого нить перса в 3ds максе сделанного, он там весь цветной, материал есть, а когда закидываю его в Assets и unity его грузит, а потом выкидываю его на Terrain, то он вообще голая моделька с раздвинутыми руками... Как сделать так, чтобы все загружалось нормально?
3) И еще одна ошибка выскакивает, я подозреваю, что она связана с анимацией, в общем смотри что пишет:
 NullReferenceException. В чем проблема не понимаю, но указывает на вот эту строку в ява скрипте:
if(Vector3.Distance(transform.position, target.transform.position) < seeDistance) {

я подозреваю, что что-то с анимацией, т.к. до этого я с анимацией не работал и брал все стандартное... Поясни, если знаешь?
« Последнее редактирование: Август 04, 2012, 17:55:55 pm от Laxdinboy »

Август 04, 2012, 18:22:58 pm
Ответ #2

Mimi Neko

  • Администратор
  • Старожил форума

  • Оффлайн
  • *****

  • 2456
  • Репутация:
    153
    • Просмотр профиля
1) А ты не мог бы выложить своего перса? А то сделал все как в ролике, но скачал персов с инета, и не один не пашет, хз почему... Может быть твой персонаж сделан по другому... Или из-за того что у меня Terrain стоит, хотя вряд ли, т.к. я его в Navigation нажал на Bake...
2) И еще такой вопрос, скачиваю я допустим какого нить перса в 3ds максе сделанного, он там весь цветной, материал есть, а когда закидываю его в Assets и unity его грузит, а потом выкидываю его на Terrain, то он вообще голая моделька с раздвинутыми руками... Как сделать так, чтобы все загружалось нормально?
3) И еще одна ошибка выскакивает, я подозреваю, что она связана с анимацией, в общем смотри что пишет:
 NullReferenceException. В чем проблема не понимаю, но указывает на вот эту строку в ява скрипте:
if(Vector3.Distance(transform.position, target.transform.position) < seeDistance) {

я подозреваю, что что-то с анимацией, т.к. до этого я с анимацией не работал и брал все стандартное... Поясни, если знаешь?

Персы с инета часто требуют немало работы ещё над ними... бывают или сырые или некоректно экспортированы, или криво импортируются. Координаты расположения особо часто как зря.

А когда я из макса в юнити модель кидаю, я ещё и кидаю папочку textures с текстурами к этой модельке.
если в максе5 нормально был сохранён материал, то в юнити он будет, и в него останется мышкой перетащить текстурки из той папки (либо сами подгрузятся).

А твоя ошибка может возникать и не в этой строке.  лучше  больше кода выложи.




Август 04, 2012, 18:56:41 pm
Ответ #3

Laxdinboy

  • Новичок

  • Оффлайн
  • *

  • 6
  • Репутация:
    0
    • Просмотр профиля
NewBee
Я еще не доделал скрипт до конца, т.к. остановился на этой ошибке. По этому вот что есть пока что на данном этапе:
#pragma strict

var seeDistance : float = 30.5f;
var attackDistance : float = 5.0f;
private var nav: NavMeshAgent;
private var target: Transform;
var idleAnimation : AnimationClip;
var walkAnimation : AnimationClip;
var attackAnimation: AnimationClip;

function Start () {
animation.AddClip(idleAnimation, "idle");
animation.AddClip(walkAnimation, "walk");
animation.AddClip(attackAnimation, "attack");
target = GameObject.FindWithTag("Player").transform;
nav = GetComponent(NavMeshAgent);
}

function Update () {
if(Vector3.Distance(transform.position, target.transform.position) < seeDistance) {
if(Vector3.Distance(transform.position, target.transform.position) > attackDistance){
animation.CrossFade("walk");
nav.enabled=true;
nav.SetDestination(target.position);
}else {
animation.CrossFade("attack");
nav.enabled=false;
}
} else {
animation.CrossFade("idle");
nav.enabled=false;
}
}
Если не трудно, выложи куда-нибудь готовый проект с AI, я разберусь в нем.

А на счет 3дмакса, то да, была такая мысля что придется дорабатывать, но в максе я новичок, по этому качал с инета, и, как подозревал, получил корявый юнит. Придется пилить макса, наверное, чтобы позже игры клепать, но сейчас не об этом, сейчас хотелось бы уроки все пройти и не заострять внимание на других программах.

Август 04, 2012, 19:48:35 pm
Ответ #4

Alcatraz

  • Администратор
  • Старожил форума

  • Оффлайн
  • *****

  • 1851
  • Репутация:
    123
    • Просмотр профиля
    • Flight Dream Studio
NewBee
Я еще не доделал скрипт до конца, т.к. остановился на этой ошибке. По этому вот что есть пока что на данном этапе:
#pragma strict

var seeDistance : float = 30.5f;
var attackDistance : float = 5.0f;
private var nav: NavMeshAgent;
private var target: Transform;
var idleAnimation : AnimationClip;
var walkAnimation : AnimationClip;
var attackAnimation: AnimationClip;

function Start () {
animation.AddClip(idleAnimation, "idle");
animation.AddClip(walkAnimation, "walk");
animation.AddClip(attackAnimation, "attack");
target = GameObject.FindWithTag("Player").transform;
nav = GetComponent(NavMeshAgent);
}

function Update () {
if(Vector3.Distance(transform.position, target.transform.position) < seeDistance) {
if(Vector3.Distance(transform.position, target.transform.position) > attackDistance){
animation.CrossFade("walk");
nav.enabled=true;
nav.SetDestination(target.position);
}else {
animation.CrossFade("attack");
nav.enabled=false;
}
} else {
animation.CrossFade("idle");
nav.enabled=false;
}
}
Если не трудно, выложи куда-нибудь готовый проект с AI, я разберусь в нем.

А на счет 3дмакса, то да, была такая мысля что придется дорабатывать, но в максе я новичок, по этому качал с инета, и, как подозревал, получил корявый юнит. Придется пилить макса, наверное, чтобы позже игры клепать, но сейчас не об этом, сейчас хотелось бы уроки все пройти и не заострять внимание на других программах.
в первом посту код - сравни. модель платная, от дексофта.

Август 04, 2012, 21:10:23 pm
Ответ #5

Laxdinboy

  • Новичок

  • Оффлайн
  • *

  • 6
  • Репутация:
    0
    • Просмотр профиля
Alcatraz
Да, код однозначно другой, но зачем мне брать твой код, если ошибка в другом, мне просто нужно подтвердить или опровергнуть мою теорию о том, что код верный, а юнит мой "недоработанный" слегка. Я шел ровно по твоему видео, не пропуская ни клика.
Можешь хотя-бы какого нить стремного героя кинуть из своих запасов, мне чисто чтобы проверить, заработает или нет...? Животного, робота, кого угодно.
 Если заработает, я дальше сам разберусь... где моя не пропадала:)

Август 05, 2012, 01:06:53 am
Ответ #6

Mimi Neko

  • Администратор
  • Старожил форума

  • Оффлайн
  • *****

  • 2456
  • Репутация:
    153
    • Просмотр профиля
Есть же в стандартном ассете юнити, сантехник, с анимацией! можно его взять и с ним поиграться, он настроеный полность.

Без работы в 3D редакторе, "клепать" что-либо будет весьма маловероятно. Я сам новичёк, недавно за макс и юнити принялся, их вполне можно вместе осваивать, темболее что ни юнити ни макс, невозможно сесть и весь освоить прям.

Я кажется предполагаю, что у  тебя  за  ошибка  NullReferenceException!


Скорее всего дело вот в этой строке:
animation.CrossFade("walk");

Скорее всего, у твоей модели не определено имя фрагмента анимации walk, и ему не соответствует никакой клип анимации.

Вот как это должно быть обычно для модели, смотри скрины. на втором скрине - как и где найти сантехника в стандартном ассете, и какие у него переменные определены.

заметь, в настройках модели, после имени фрагмента (клипа) анимации, задаётся временной интервал, который проигрывается из дорожки анимации.

анимация персонажа обычно состоит из нескольких анимаций, которые в 3d максе прикрепляются к модели, на одну дорожку. получается как бы 1 клип из разных анимаций. Выгружается он из макса в составе файла fbx, вместе с моделькой и её скелетом.
А в юнити, в настройках модели, нужно как бы разбить эту дорожку анимайии на составные фрагменты, и каждой части сопоставить название (имя анимации).

именно имя фрагмента анимации, используется потом в кавычках как тут: animation.CrossFade("walk");


[вложение удалено]
« Последнее редактирование: Август 05, 2012, 02:02:26 am от NewBee »

Август 05, 2012, 01:26:39 am
Ответ #7

Mimi Neko

  • Администратор
  • Старожил форума

  • Оффлайн
  • *****

  • 2456
  • Репутация:
    153
    • Просмотр профиля
в первом посту код - сравни.

Кстати, у тебя тут в листинге кода, 4 строчки в начале пропущены... 
там где объявляется attackDistance, seeDistance, target и nav.
А на видео они есть!  ;)

Август 05, 2012, 11:12:37 am
Ответ #8

Laxdinboy

  • Новичок

  • Оффлайн
  • *

  • 6
  • Репутация:
    0
    • Просмотр профиля
NewBee
Спасибо, сегодня же начну обрабатывать ошибки, а на счет кода - да!:) Я же сказал, что до конца видео не дошел и код не дописал еще, потому-что остановился на середине видео. А смысл идти дальше и делать что-то, если у тебя юнит даже не ходит, не говоря о остальных действиях:)

Август 05, 2012, 11:34:51 am
Ответ #9

Mimi Neko

  • Администратор
  • Старожил форума

  • Оффлайн
  • *****

  • 2456
  • Репутация:
    153
    • Просмотр профиля
А смысл идти дальше и делать что-то, если у тебя юнит даже не ходит, не говоря о остальных действиях:)
Ну да... У меня тоже бывает много ошибок, на каждом шагу по началу были...
Иногда, чтобы понять в чём дело, нужно попытаться локализовать ошибку, максимально упростив програмку.
Например, закомменировав максимально код, или вырезать большую его часть, в блокнот, и оставить минимум.

Август 05, 2012, 11:48:48 am
Ответ #10

Laxdinboy

  • Новичок

  • Оффлайн
  • *

  • 6
  • Репутация:
    0
    • Просмотр профиля
NewBee
Все заработало, поставил этого сантехника, у него атаки нет, но я в замест нее бег поставил.
ОШИБКА была такой глупой..... я забыл TAG своему First Person Controller присвоить Player
Вот сейчас сел разбирать код и бац, смотрю Player то в коде ищет по тэгу а в моем челе то его нету...... Включил я его однако и все заработало:)
Сейчас доделаю проект и пойду дальше :D
Спасибо за помощь:)

Август 05, 2012, 20:57:42 pm
Ответ #11

3Dmaksimka

  • Новичок

  • Оффлайн
  • *

  • 15
  • Репутация:
    0
    • Просмотр профиля
у меня такая проблемка...анимация бега есть..но перс стоит на месте....то бишь бежит на месте..
и плохо что не показано как сделать бар жизни и атака для нпс
« Последнее редактирование: Август 05, 2012, 21:14:17 pm от 3Dmaksimka »

Август 05, 2012, 23:11:38 pm
Ответ #12

Mimi Neko

  • Администратор
  • Старожил форума

  • Оффлайн
  • *****

  • 2456
  • Репутация:
    153
    • Просмотр профиля
у меня такая проблемка...анимация бега есть..но перс стоит на месте....то бишь бежит на месте..

 - Это же наоборот хорошо! это правильная анимация.
а передвижение делай уже программно.
Главное - правильное соотношение скорости анимации и скорости перемещения.

Август 05, 2012, 23:41:17 pm
Ответ #13

3Dmaksimka

  • Новичок

  • Оффлайн
  • *

  • 15
  • Репутация:
    0
    • Просмотр профиля
чет я не в курил:)))а почем в уроке он когда закидывал скрипт в модельку...все бежало и работала?:) или это нужен еще 1 скрипт?:)хотя у меня был другой скрипт от другого автора для движение за игроком..
а и кстати..дистанция работает:) как подхожу ближе он типа меня атакует...а так идет на месте не ко мне а просто идет...типа зацикленная анимация но сам при это не движется..косяк какой то:)

Август 05, 2012, 23:51:53 pm
Ответ #14

Mimi Neko

  • Администратор
  • Старожил форума

  • Оффлайн
  • *****

  • 2456
  • Репутация:
    153
    • Просмотр профиля
Если идёт на месте просто так - надо сперва смотреть, какое ему поведение заложено должно быть вообще.
Если он должен без цели блуждать сам - значит его должен перемещать скрипт.
А если не должен без цели бродить - значит при отсутствии цели, должна изменяться анимация на анимацию покоя и стояния на месте.
Незнаю как в этом именно уроке, пока не смотрел, но обычно всегда анимацией персонажей не принято перемещать.