оптимизация AI скрипта

Форум для всего, что связано с ИИ.

оптимизация AI скрипта

Сообщение 6opoDuJI0 06 янв 2010, 20:09

имеется AI скрипт солдата ^_^ (на самом деле это небольшая переделка AI скрипта,идущего в FPS TUTORIAL)
Код: Выделить всё
var speed = 3.0;
var rotationSpeed = 5.0;
var shootRange = 15.0;
var attackRange = 30.0;
var shootAngle = 40.0;
var dontComeCloserRange = 5.0;
var delayShootTime = 0.35;
var pickNextWaypointDistance = 2.0;
var target : Transform;

private var lastShot = -10.0;

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

function Start () {
   // Auto setup player as target through tags
   if (target == null && GameObject.FindWithTag("Red Team"))
      target = GameObject.FindWithTag("Red Team").transform;

   Patrol();
}

function Patrol () {
   var curWayPoint = AutoWayPoint.FindClosest(transform.position);
   while (true) {
      var waypointPosition = curWayPoint.transform.position;
      // Are we close to a waypoint? -> pick the next one!
      if (Vector3.Distance(waypointPosition, transform.position) < pickNextWaypointDistance)
         curWayPoint = PickNextWaypoint (curWayPoint);

      // Attack the player and wait until
      // - player is killed
      // - player is out of sight      
      if (CanSeeTarget ())
         yield StartCoroutine("AttackPlayer");
      if (!CanSeeTarget())
      target = GameObject.FindWithTag("Red Team").transform;
      // Move towards our target
      MoveTowards(waypointPosition);
      
      yield;
   }
}


function CanSeeTarget () : boolean {
   if (Vector3.Distance(transform.position, target.position) > attackRange)
      return false;
      
   var hit : RaycastHit;
   if (Physics.Linecast (transform.position, target.position, hit))
      return hit.transform == target;      

   return false;
}

function Shoot () {
   // Start shoot animation
   animation.CrossFade("shoot", 0.3);

   // Wait until half the animation has played
   yield WaitForSeconds(delayShootTime);
   
   // Fire gun
   BroadcastMessage("Fire");
   
   // Wait for the rest of the animation to finish
   yield WaitForSeconds(animation["shoot"].length - delayShootTime);
   target = GameObject.FindWithTag("Red Team").transform;
}

function AttackPlayer () {
   var lastVisiblePlayerPosition = target.position;
   while (true) {
      if (CanSeeTarget ()) {
         // Target is dead - stop hunting
         if (target == null){
         return;
            }

         // Target is too far away - give up   
         var distance = Vector3.Distance(transform.position, target.position);
         if (distance > shootRange * 3)
            return;
         
         lastVisiblePlayerPosition = target.position;
         if (distance > dontComeCloserRange)
            MoveTowards (lastVisiblePlayerPosition);
         else
            RotateTowards(lastVisiblePlayerPosition);

         var forward = transform.TransformDirection(Vector3.forward);
         var targetDirection = lastVisiblePlayerPosition - transform.position;
         targetDirection.y = 0;

         var angle = Vector3.Angle(targetDirection, forward);

         // Start shooting if close and play is in sight
         if (distance < shootRange && angle < shootAngle)
            yield StartCoroutine("Shoot");
      } else {
         yield StartCoroutine("SearchPlayer", lastVisiblePlayerPosition);
         // Player not visible anymore - stop attacking
         if (!CanSeeTarget ())
            return;
      }

      yield;
   }
}

function SearchPlayer (position : Vector3) {
   // Run towards the player but after 3 seconds timeout and go back to Patroling
   var timeout = 3.0;
   while (timeout > 0.0) {
      MoveTowards(position);

      // We found the player
      if (CanSeeTarget ())
         return;[size=50][/size]

      timeout -= Time.deltaTime;
      yield;
   }
}

function RotateTowards (position : Vector3) {
   SendMessage("SetSpeed", 0.0);
   
   var direction = position - transform.position;
   direction.y = 0;
   if (direction.magnitude < 0.1)
      return;
   
   // Rotate towards the target
   transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
   transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);
}

function MoveTowards (position : Vector3) {
   var direction = position - transform.position;
   direction.y = 0;
   if (direction.magnitude < 0.5) {
      SendMessage("SetSpeed", 0.0);
      return;
   }
   
   // Rotate towards the target
   transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
   transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);

   // Modify speed so we slow down when we are not facing the target
   var forward = transform.TransformDirection(Vector3.forward);
   var speedModifier = Vector3.Dot(forward, direction.normalized);
   speedModifier = Mathf.Clamp01(speedModifier);

   // Move the character
   direction = forward * speed * speedModifier;
   GetComponent (CharacterController).SimpleMove(direction);
   
   SendMessage("SetSpeed", speed * speedModifier, SendMessageOptions.DontRequireReceiver);
}

function PickNextWaypoint (currentWaypoint : AutoWayPoint) {
   // We want to find the waypoint where the character has to turn the least

   // The direction in which we are walking
   var forward = transform.TransformDirection(Vector3.forward);

   // The closer two vectors, the larger the dot product will be.
   var best = currentWaypoint;
   var bestDot = -10.0;
   for (var cur : AutoWayPoint in currentWaypoint.connected) {
      var direction = Vector3.Normalize(cur.transform.position - transform.position);
      var dot = Vector3.Dot(direction, forward);
      if (dot > bestDot && cur != currentWaypoint) {
         bestDot = dot;
         best = cur;
      }
   }
   
   return best;
}

скрипт получает transform тегированный как red team.но!загвоздка в том,что я всегда получаю одно и тоже значение в transform ,т.е. всегда получаю первый подходящий для этого экземпляр класса transform .вопрос - можно ли какимто макаром получить ближайший к себе transform,помеченый тёгом red team(в свою очередь,этот transform ещё и rigidbody)? и просьба админу починить форму ввода сообщения,ато блин печатать нормально невозможно,скролбар всегда на середине,а когда я чтото печатаю,зараза,всё дёргается.юзаю ослика,если это важно
А вам тоже нравится в мороз выпускать изо рта тонкую струйку пара и чувствовать себя драконом?:)
Аватара пользователя
6opoDuJI0
UNIт
 
Сообщения: 85
Зарегистрирован: 06 янв 2010, 20:00

Re: оптимизация AI скрипта

Сообщение 6opoDuJI0 06 янв 2010, 22:30

как говорится,пока о проблеме не отпишеш,с проблемой не разберёшся ^_^
украденный кусок кода из explosion simple.js из всё тогоже fps tutorial помог частично разобратся с проблемой
но!повторюсь,частично.
имеется экземпляр класса collider.нужно определить хозяина этого коллайдера,т.е. получить экземпляры тех ГО,которые провоцировали коллизию
сделать это нужно для того,чтобы узнать тёг этого геймобьекта ^_^
А вам тоже нравится в мороз выпускать изо рта тонкую струйку пара и чувствовать себя драконом?:)
Аватара пользователя
6opoDuJI0
UNIт
 
Сообщения: 85
Зарегистрирован: 06 янв 2010, 20:00

Re: оптимизация AI скрипта

Сообщение Zaicheg 07 янв 2010, 12:30

6opoDuJI0 писал(а):имеется экземпляр класса collider.нужно определить хозяина этого коллайдера,т.е. получить экземпляры тех ГО,которые провоцировали коллизию

Без проблем.

Collider col01;
GameObject go01;
go01 = col01.gameObject;

http://unity3d.com/support/documentatio ... m=Collider
Дьяченко Роман
e-mail: _zaicheg.reg@gmail.com
skype: zaicheg12
vkontakte: _vk.com/zaichegq
Работа: _wie3.com _www.sanviz.com
Аватара пользователя
Zaicheg
Адепт
 
Сообщения: 3024
Зарегистрирован: 19 июн 2009, 15:12
Откуда: Череповец

Re: оптимизация AI скрипта

Сообщение 6opoDuJI0 07 янв 2010, 21:10

зайчик,вы не правы
BCE0019: 'GameObject' is not a member of 'UnityEngine.Collider'.
А вам тоже нравится в мороз выпускать изо рта тонкую струйку пара и чувствовать себя драконом?:)
Аватара пользователя
6opoDuJI0
UNIт
 
Сообщения: 85
Зарегистрирован: 06 янв 2010, 20:00

Re: оптимизация AI скрипта

Сообщение Zaicheg 07 янв 2010, 21:27

6opoDuJI0 писал(а):зайчик,вы не правы
BCE0019: 'GameObject' is not a member of 'UnityEngine.Collider'.

Нет, я прав.
Вот полностью рабочий код, проверил:
Код: Выделить всё
using UnityEngine;
using System.Collections;

public class Script01 : MonoBehaviour
{
    public GameObject go1;
    public GameObject go2;
    public Collider co;

    void Start()
    {
        co = go1.GetComponent<BoxCollider>();
        go2 = co.gameObject;
    }
}
Дьяченко Роман
e-mail: _zaicheg.reg@gmail.com
skype: zaicheg12
vkontakte: _vk.com/zaichegq
Работа: _wie3.com _www.sanviz.com
Аватара пользователя
Zaicheg
Адепт
 
Сообщения: 3024
Зарегистрирован: 19 июн 2009, 15:12
Откуда: Череповец

Re: оптимизация AI скрипта

Сообщение 6opoDuJI0 07 янв 2010, 21:28

во!обьединение двух скриптов из fps tutorial дало относительно неплохой AI скрипт для тупого монстра)
монстр целится в rigidbody помеченый тёгом Red Team
ищет новую цель после каждого выстрела
еслиже нету ниодной приемлемой цели,AI застывает
атакует в случае,если цель видна.если же не видна,или идёт на последнюю видимую позицию цели,или прекращает "охоту"
Код: Выделить всё
var speed = 3.0;
var rotationSpeed = 5.0;
var shootRange = 15.0;
var attackRange = 30.0;
var shootAngle = 40.0;
var dontComeCloserRange = 5.0;
var delayShootTime = 0.35;
var pickNextWaypointDistance = 2.0;
var target : Transform;

private var lastShot = -10.0;

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

function Start () {
   // Auto setup player as target through tags
   if (target == null && GameObject.FindWithTag("Red Team"))
   SearchClosestTarget();
      //target = GameObject.FindWithTag("Red Team").transform;
      
   Patrol();
}

function Patrol () {
   var curWayPoint = AutoWayPoint.FindClosest(transform.position);
   while (true) {
      var waypointPosition = curWayPoint.transform.position;
      // Are we close to a waypoint? -> pick the next one!
      if (Vector3.Distance(waypointPosition, transform.position) < pickNextWaypointDistance)
         curWayPoint = PickNextWaypoint (curWayPoint);

      // Attack the player and wait until
      // - player is killed
      // - player is out of sight      
      if (CanSeeTarget ())
         yield StartCoroutine("AttackPlayer");
      if (!CanSeeTarget())
      SearchClosestTarget();
      // Move towards our target
      MoveTowards(waypointPosition);
      
      yield;
   }
}


function CanSeeTarget () : boolean {
   if (Vector3.Distance(transform.position, target.position) > attackRange)
      return false;
      
   var hit : RaycastHit;
   if (Physics.Linecast (transform.position, target.position, hit))
      return hit.transform == target;      

   return false;
}

function Shoot () {
   // Start shoot animation
   animation.CrossFade("shoot", 0.3);

   // Wait until half the animation has played
   yield WaitForSeconds(delayShootTime);
   
   // Fire gun
   BroadcastMessage("Fire");
   
   // Wait for the rest of the animation to finish
   yield WaitForSeconds(animation["shoot"].length - delayShootTime);
   SearchClosestTarget();
}

function AttackPlayer () {
   var lastVisiblePlayerPosition = target.position;
   while (true) {
      if (CanSeeTarget ()) {
         // Target is dead - stop hunting
         if (target == null){
         return;
            }

         // Target is too far away - give up   
         var distance = Vector3.Distance(transform.position, target.position);
         if (distance > shootRange * 3)
            return;
         
         lastVisiblePlayerPosition = target.position;
         if (distance > dontComeCloserRange)
            MoveTowards (lastVisiblePlayerPosition);
         else
            RotateTowards(lastVisiblePlayerPosition);

         var forward = transform.TransformDirection(Vector3.forward);
         var targetDirection = lastVisiblePlayerPosition - transform.position;
         targetDirection.y = 0;

         var angle = Vector3.Angle(targetDirection, forward);

         // Start shooting if close and play is in sight
         if (distance < shootRange && angle < shootAngle)
            yield StartCoroutine("Shoot");
      } else {
         yield StartCoroutine("SearchPlayer", lastVisiblePlayerPosition);
         // Player not visible anymore - stop attacking
         if (!CanSeeTarget ())
            return;
      }

      yield;
   }
}

function SearchPlayer (position : Vector3) {
   // Run towards the player but after 3 seconds timeout and go back to Patroling
   var timeout = 3.0;
   while (timeout > 0.0) {
      MoveTowards(position);

      // We found the player
      if (CanSeeTarget ())
         return;

      timeout -= Time.deltaTime;
      yield;
   }
}

function RotateTowards (position : Vector3) {
   SendMessage("SetSpeed", 0.0);
   
   var direction = position - transform.position;
   direction.y = 0;
   if (direction.magnitude < 0.1)
      return;
   
   // Rotate towards the target
   transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
   transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);
}

function MoveTowards (position : Vector3) {
   var direction = position - transform.position;
   direction.y = 0;
   if (direction.magnitude < 0.5) {
      SendMessage("SetSpeed", 0.0);
      return;
   }
   
   // Rotate towards the target
   transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
   transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);

   // Modify speed so we slow down when we are not facing the target
   var forward = transform.TransformDirection(Vector3.forward);
   var speedModifier = Vector3.Dot(forward, direction.normalized);
   speedModifier = Mathf.Clamp01(speedModifier);

   // Move the character
   direction = forward * speed * speedModifier;
   GetComponent (CharacterController).SimpleMove(direction);
   
   SendMessage("SetSpeed", speed * speedModifier, SendMessageOptions.DontRequireReceiver);
}

function PickNextWaypoint (currentWaypoint : AutoWayPoint) {
   // We want to find the waypoint where the character has to turn the least

   // The direction in which we are walking
   var forward = transform.TransformDirection(Vector3.forward);

   // The closer two vectors, the larger the dot product will be.
   var best = currentWaypoint;
   var bestDot = -10.0;
   for (var cur : AutoWayPoint in currentWaypoint.connected) {
      var direction = Vector3.Normalize(cur.transform.position - transform.position);
      var dot = Vector3.Dot(direction, forward);
      if (dot > bestDot && cur != currentWaypoint) {
         bestDot = dot;
         best = cur;
      }
   }
   
   return best;
}

function SearchClosestTarget(){
var AIpos = transform.position;
var mindist = attackRange  ;
var colliders : Collider[] = Physics.OverlapSphere (AIpos, attackRange);
for (var hit in colliders) {
      if (!hit)
         continue;
      
      if (hit.rigidbody) {
                           
         var closestPoint = hit.rigidbody.ClosestPointOnBounds(AIpos);
         
         var distance = Vector3.Distance(closestPoint, AIpos);

         if (distance < mindist) {
         if (hit.gameObject.tag == "Red Team")
         {
         target = hit.transform;}}
      }
   }


return;
};
А вам тоже нравится в мороз выпускать изо рта тонкую струйку пара и чувствовать себя драконом?:)
Аватара пользователя
6opoDuJI0
UNIт
 
Сообщения: 85
Зарегистрирован: 06 янв 2010, 20:00

Re: оптимизация AI скрипта

Сообщение 6opoDuJI0 08 янв 2010, 01:42

Извиняюсь перед зайкой,дело было в регистре первого символа названия класса
а вот и сам скрипт ^_^
на днях выложу пример использования
Код: Выделить всё
var speed = 3.0;
var rotationSpeed = 5.0;
var shootRange = 15.0;
var attackRange = 30.0;
var shootAngle = 40.0;
var dontComeCloserRange = 5.0;
var delayShootTime = 0.35;
var pickNextWaypointDistance = 2.0;
var target : Transform;
var defaulttarget : Transform;
var TargetTag : String;

private var lastShot = -10.0;

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

function Start () {
defaulttarget = transform;
   target=defaulttarget;
   SearchClosestTarget();
   Patrol();
}

function Patrol () {
   var curWayPoint = AutoWayPoint.FindClosest(transform.position);
   while (true) {
      var waypointPosition = curWayPoint.transform.position;
      // Are we close to a waypoint? -> pick the next one!
      if (Vector3.Distance(waypointPosition, transform.position) < pickNextWaypointDistance)
         curWayPoint = PickNextWaypoint (curWayPoint);

      // Attack the player and wait until
      // - player is killed
      // - player is out of sight      
      if (CanSeeTarget ())
         yield StartCoroutine("AttackPlayer");
      if (!CanSeeTarget()){
      target=defaulttarget;
      SearchClosestTarget();
      // Move towards our target
      MoveTowards(waypointPosition);}
      if (target==defaulttarget){SearchClosestTarget();}
      if (target==null){target=defaulttarget;}
      yield;
   }
}


function CanSeeTarget () : boolean {
   if (Vector3.Distance(transform.position, target.position) > attackRange)
      return false;
      
   var hit : RaycastHit;
   if (Physics.Linecast (transform.position, target.position, hit))
      return hit.transform == target;      

   return false;
}

function Shoot () {
   // Start shoot animation
   animation.CrossFade("shoot", 0.3);

   // Wait until half the animation has played
   yield WaitForSeconds(delayShootTime);
   
   // Fire gun
   BroadcastMessage("Fire");
   
   // Wait for the rest of the animation to finish
   yield WaitForSeconds(animation["shoot"].length - delayShootTime);
   SearchClosestTarget();
}

function AttackPlayer () {
   var lastVisiblePlayerPosition = target.position;
   while (true) {
      if (CanSeeTarget ()) {
         // Target is dead - stop hunting
         if (target == null){
         target=defaulttarget;
         
            }

         // Target is too far away - give up   
         var distance = Vector3.Distance(transform.position, target.position);
         if (distance > shootRange * 3)
            return;
         
         lastVisiblePlayerPosition = target.position;
         if (distance > dontComeCloserRange)
            MoveTowards (lastVisiblePlayerPosition);
         else
            RotateTowards(lastVisiblePlayerPosition);

         var forward = transform.TransformDirection(Vector3.forward);
         var targetDirection = lastVisiblePlayerPosition - transform.position;
         targetDirection.y = 0;

         var angle = Vector3.Angle(targetDirection, forward);

         // Start shooting if close and play is in sight
         if (distance < shootRange && angle < shootAngle)
            yield StartCoroutine("Shoot");
      } else {
         yield StartCoroutine("SearchPlayer", lastVisiblePlayerPosition);
         // Player not visible anymore - stop attacking
         if (!CanSeeTarget ())
         {
         SearchClosestTarget();
            return;}
      }

      yield;
   }
}

function SearchPlayer (position : Vector3) {
   // Run towards the player but after 3 seconds timeout and go back to Patroling
   var timeout = 3.0;
   while (timeout > 0.0) {
      MoveTowards(position);

      // We found the player
      if (CanSeeTarget ())
         return;

      timeout -= Time.deltaTime;
      yield;
   }
}

function RotateTowards (position : Vector3) {
   SendMessage("SetSpeed", 0.0);
   
   var direction = position - transform.position;
   direction.y = 0;
   if (direction.magnitude < 0.1)
      return;
   
   // Rotate towards the target
   transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
   transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);
}

function MoveTowards (position : Vector3) {
   var direction = position - transform.position;
   direction.y = 0;
   if (direction.magnitude < 0.5) {
      SendMessage("SetSpeed", 0.0);
      return;
   }
   
   // Rotate towards the target
   transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
   transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);

   // Modify speed so we slow down when we are not facing the target
   var forward = transform.TransformDirection(Vector3.forward);
   var speedModifier = Vector3.Dot(forward, direction.normalized);
   speedModifier = Mathf.Clamp01(speedModifier);

   // Move the character
   direction = forward * speed * speedModifier;
   GetComponent (CharacterController).SimpleMove(direction);
   
   SendMessage("SetSpeed", speed * speedModifier, SendMessageOptions.DontRequireReceiver);
}

function PickNextWaypoint (currentWaypoint : AutoWayPoint) {
   // We want to find the waypoint where the character has to turn the least

   // The direction in which we are walking
   var forward = transform.TransformDirection(Vector3.forward);

   // The closer two vectors, the larger the dot product will be.
   var best = currentWaypoint;
   var bestDot = -10.0;
   for (var cur : AutoWayPoint in currentWaypoint.connected) {
      var direction = Vector3.Normalize(cur.transform.position - transform.position);
      var dot = Vector3.Dot(direction, forward);
      if (dot > bestDot && cur != currentWaypoint) {
         bestDot = dot;
         best = cur;
      }
   }
   
   return best;
}

function SearchClosestTarget(){
var lasttarget = target;
var AIpos = transform.position;
var mindist = attackRange  ;
var colliders : Collider[] = Physics.OverlapSphere (AIpos, attackRange);
for (var hit in colliders) {
      if (!hit)
         continue;
      
      if (hit.rigidbody) {
                           
         var closestPoint = hit.rigidbody.ClosestPointOnBounds(AIpos);
         
         var distance = Vector3.Distance(closestPoint, AIpos);

         if (distance < mindist) {
         if (hit.gameObject.tag == TargetTag)
         {
         target = hit.transform;}}
         if (!CanSeeTarget()){
         target=lasttarget;
         }//target=lasttarget;
      }
   }


return;
};

function Update()
{if (target==null){target=defaulttarget;}
if (target==defaulttarget){SearchClosestTarget();}
};
А вам тоже нравится в мороз выпускать изо рта тонкую струйку пара и чувствовать себя драконом?:)
Аватара пользователя
6opoDuJI0
UNIт
 
Сообщения: 85
Зарегистрирован: 06 янв 2010, 20:00

Re: оптимизация AI скрипта

Сообщение Скромняга 16 янв 2011, 12:49

на днях выложу пример использования

Выложил? Где?
Скромняга
UNIт
 
Сообщения: 57
Зарегистрирован: 19 дек 2010, 20:51

Re: оптимизация AI скрипта

Сообщение Alcatraz 07 июн 2011, 12:24

примера нет...жаль!.. x_x
Unity3D Game Developer
Аватара пользователя
Alcatraz
UNITрон
 
Сообщения: 236
Зарегистрирован: 07 июн 2011, 09:12
Откуда: Москва
  • Сайт
  • ICQ


Вернуться в Искуственный Интеллект

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

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