[Решено] ЗРЕНИЕ МОБОВ - Форум Игроделов
Пн, 21 Июл 2025, 08:12 
 
Приветствую Вас Гость Главная | Регистрация | Вход
Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
[Решено] ЗРЕНИЕ МОБОВ
dostalitionДата: Пн, 21 Янв 2013, 01:50 | Сообщение # 1
 
Сообщений: 155
Награды: 0
Репутация: 9
Статус: Offline
Пару месяцев назад начал осваивать Юньку ... Всё шло хорошо, пока не добрался до написания кода ИИ ... Т.к. использую инди-версию, NAVIGATOR (NAVMESH), соответственно, не работает. Пришлось скачать замену - AstarPathfindingProject ... Кое-как разобрался, как сделать, чтобы моб начал преследование на определённой дистанции и атаку на ближней, чтобы поворачивался всегда лицом ко Мне и проигрывались соответствующие анимации ... Но проблема в том, что если между Мной и мобом стена , а расстояние соответствует расстоянию агра, то моб всё-равно Меня "видит" и рулит ко Мне ... Покопавшись в интернетах, понял, что можно решить эту проблему , например, рэйкастом , но не могу понять , как именно вписать код с райкастом в скрипт AIFollow , который идёт в комплекте с AstarPathfindingProject и в котором происходит всё вышеперечисленное ... sad Будьте добры, подскажите как решить эту проблему. Может не райкастом, а как-то по-ругому .... Скрипт этот на шарпе ...

Сообщение отредактировал TheReaper - Чт, 24 Янв 2013, 23:43
 
СообщениеПару месяцев назад начал осваивать Юньку ... Всё шло хорошо, пока не добрался до написания кода ИИ ... Т.к. использую инди-версию, NAVIGATOR (NAVMESH), соответственно, не работает. Пришлось скачать замену - AstarPathfindingProject ... Кое-как разобрался, как сделать, чтобы моб начал преследование на определённой дистанции и атаку на ближней, чтобы поворачивался всегда лицом ко Мне и проигрывались соответствующие анимации ... Но проблема в том, что если между Мной и мобом стена , а расстояние соответствует расстоянию агра, то моб всё-равно Меня "видит" и рулит ко Мне ... Покопавшись в интернетах, понял, что можно решить эту проблему , например, рэйкастом , но не могу понять , как именно вписать код с райкастом в скрипт AIFollow , который идёт в комплекте с AstarPathfindingProject и в котором происходит всё вышеперечисленное ... sad Будьте добры, подскажите как решить эту проблему. Может не райкастом, а как-то по-ругому .... Скрипт этот на шарпе ...

Автор - dostalition
Дата добавления - 21 Янв 2013 в 01:50
seamanДата: Пн, 21 Янв 2013, 08:35 | Сообщение # 2
Гуру
 
Сообщений: 1748
Награды: 10
Репутация: 660
Статус: Offline
В следующий раз внимательнее смотрите куда пишете. Это что у Вас новый "ИГРОВОЙ ПРОЕКТ"?
 
СообщениеВ следующий раз внимательнее смотрите куда пишете. Это что у Вас новый "ИГРОВОЙ ПРОЕКТ"?

Автор - seaman
Дата добавления - 21 Янв 2013 в 08:35
dostalitionДата: Пн, 21 Янв 2013, 12:24 | Сообщение # 3
 
Сообщений: 155
Награды: 0
Репутация: 9
Статус: Offline
Прошу прощения ... Первый раз пишусь на форуме ...
 
СообщениеПрошу прощения ... Первый раз пишусь на форуме ...

Автор - dostalition
Дата добавления - 21 Янв 2013 в 12:24
ЛевшаДата: Пн, 21 Янв 2013, 13:43 | Сообщение # 4
Черный Волк
 
Сообщений: 7257
Награды: 30
Репутация: 3313
Статус: Offline
Цитата (dostalition)
Скрипт этот на шарпе

И как бы его увидеть ? smile Экстасенсы и гадалки в отпуске...


X.cor.R (Prologue)
 
Сообщение
Цитата (dostalition)
Скрипт этот на шарпе

И как бы его увидеть ? smile Экстасенсы и гадалки в отпуске...

Автор - Левша
Дата добавления - 21 Янв 2013 в 13:43
dostalitionДата: Пн, 21 Янв 2013, 14:03 | Сообщение # 5
 
Сообщений: 155
Награды: 0
Репутация: 9
Статус: Offline
Ща попробую закинуть smile Первый раз у Вас тут smile

Код

using UnityEngine;
using System.Collections;
using Pathfinding;

/** Example AI.
* \deprecated This script has been deprecated, use AIPath or MineBotAI instead */
[RequireComponent (typeof(Seeker))]
[RequireComponent (typeof(CharacterController))]
public class AIFollow : MonoBehaviour {

/** Target to move to */
public Transform target;

/** How often to search for a new path */
public float repathRate = 0.1F;

/** The minimum distance to a waypoint to consider it as "reached" */
public float pickNextWaypointDistance = 2F;

/** The minimum distance to the end point of a path to consider it "reached" (multiplied with #pickNextWaypointDistance).
* This value is multiplied with #pickNextWaypointDistance before it is used. Recommended range [0...1] */
public float targetReached = 1.0F;

/** Units per second */
public float speed = 6;

/** How fast the AI can turn around */
public float rotationSpeed = 7;

public bool drawGizmos = false;

/** Should paths be searched for.
* Setting this to false will make the AI not search for paths anymore, can save some CPU cycles.
* It will check every #repathRate seconds if it should start to search for paths again.
* \note It will not cancel paths which are currently being calculated */
public bool canSearch = true;

/** Can it move. Enables or disables movement and rotation */
public bool canMove = true;

/** Seeker component which handles pathfinding calls */
protected Seeker seeker;

/** CharacterController which handles movement */
protected CharacterController controller;

/** NavmeshController which handles movement if not null*/
protected NavmeshController navmeshController;

/** Transform, cached because of performance */
protected Transform tr;

protected float lastPathSearch = -9999;

protected int pathIndex = 0;

/** This is the path the AI is currently following */
protected Vector3[] path;

/** Use this for initialization */
public void Start () {
seeker = GetComponent<Seeker>();
controller = GetComponent<CharacterController>();
navmeshController = GetComponent<NavmeshController>();

tr = transform;
Repath ();
}

/** Will make the AI give up it's current path and stop completely. */
public void Reset () {
path = null;
}

/** Called when a path has completed it's calculation */
public void OnPathComplete (Path p) {

/*if (Time.time-lastPathSearch >= repathRate) {
Repath ();
} else {*/
StartCoroutine (WaitToRepath ());
//}

//If the path didn't succeed, don't proceed
if (p.error) {
return;
}

//Get the calculated path as a Vector3 array
path = p.vectorPath;

//Find the segment in the path which is closest to the AI
//If a closer segment hasn't been found in '6' iterations, break because it is unlikely to find any closer ones then
float minDist = Mathf.Infinity;
int notCloserHits = 0;

for (int i=0;i<path.Length-1;i++) {
float dist = Mathfx.DistancePointSegmentStrict (path[i],path[i+1],tr.position);
if (dist < minDist) {
notCloserHits = 0;
minDist = dist;
pathIndex = i+1;
} else if (notCloserHits > 6) {
break;
}
}
}

/** Waits the remaining time until the AI should issue a new path request.
* The remaining time is defined by Time.time - lastPathSearch */
public IEnumerator WaitToRepath () {
float timeLeft = repathRate - (Time.time-lastPathSearch);

yield return new WaitForSeconds (timeLeft);
Repath ();
}

/** Stops the AI.
* Also stops new search queries from being made
* \version Before 3.0.8 This does not prevent new path calls from making the AI move again
* \see #Resume
* \see #canMove
* \see #canSearch */
public void Stop () {
canMove = false;
canSearch = false;
}

/** Resumes walking and path searching the AI.
* \version Added in 3.0.8
* \see #Stop
* \see #canMove
* \see #canSearch */
public void Resume () {
canMove = true;
canSearch = true;
}

/** Recalculates the path to #target.
* Queries a path request to the Seeker, the path will not be calculated instantly, but will be put on a queue and calculated as fast as possible.
* It will wait if the current path request by this seeker has not been completed yet.
* \see Seeker::IsDone */
public virtual void Repath () {
lastPathSearch = Time.time;

if (seeker == null || target == null || !canSearch || !seeker.IsDone ()) {
StartCoroutine (WaitToRepath ());
return;
}

//for (int i=0;i<1000;i++) {
//MultithreadPath mp = new MultithreadPath (transform.position,target.position,null);
//Path p = new Path (transform.position,target.position,null);
//    AstarPath.StartPath (mp);
//}
//Debug.Log (AstarPath.pathQueue.Count);

//StartCoroutine (WaitToRepath ());
/*ConstantPath cpath = new ConstantPath(transform.position,null);
//Must be set to avoid it from searching towards Vector3.zero
cpath.heuristic = Heuristic.None;
//Here you set how far it should search
cpath.maxGScore = 2000;
AstarPath.StartPath (cpath);*/
//FloodPathTracer fpathTrace = new FloodPathTracer (transform.position,fpath,null);
//seeker.StartPath (fpathTrace,OnPathComplete);

Path p = new Path(transform.position,target.position,null);
seeker.StartPath (p,OnPathComplete);
//Start a new path from transform.positon to target.position, return the result to the function OnPathComplete
//seeker.StartPath (transform.position,target.position,OnPathComplete);
}

/** Start a new path moving to \a targetPoint */
public void PathToTarget (Vector3 targetPoint) {
lastPathSearch = Time.time;

if (seeker == null) {
return;
}

//Start a new path from transform.positon to target.position, return the result to OnPathComplete
seeker.StartPath (transform.position,targetPoint,OnPathComplete);
}

/** Called when the AI reached the end of path.
* This will be called once for every path it completes, so if you have a really fast repath rate it will call this function often if when it stands on the end point.
*/
public virtual void ReachedEndOfPath () {
//The AI has reached the end of the path
//Set animation
tr.animation.Play("attack");
tr.LookAt(target.position);
tr.eulerAngles = new Vector3(0, tr.eulerAngles.y, 0);
}

/** Update is called once per frame */
public void Update () {

float dist = Vector3.Distance(target.position, transform.position);
//bool luch = Physics.Raycast (transform.position,target.position);
if(dist <=40)
{

if (path == null || pathIndex >= path.Length || pathIndex < 0 || !canMove) {
return;
}

//Change target to the next waypoint if the current one is close enough
Vector3 currentWaypoint = path[pathIndex];
currentWaypoint.y = tr.position.y;
while ((currentWaypoint - tr.position).sqrMagnitude < pickNextWaypointDistance*pickNextWaypointDistance) {
pathIndex++;
if (pathIndex >= path.Length) {
//Use a lower pickNextWaypointDistance for the last point. If it isn't that close, then decrement the pathIndex to the previous value and break the loop
if ((currentWaypoint - tr.position).sqrMagnitude < (pickNextWaypointDistance*targetReached)*(pickNextWaypointDistance*targetReached)) {
ReachedEndOfPath ();
return;
} else {
pathIndex--;
//Break the loop, otherwise it will try to check for the last point in an infinite loop
break;
}
}
currentWaypoint = path[pathIndex];
currentWaypoint.y = tr.position.y;
}

Vector3 dir = currentWaypoint - tr.position;

// Rotate towards the target
tr.rotation = Quaternion.Slerp (tr.rotation, Quaternion.LookRotation(dir), rotationSpeed * Time.deltaTime);
tr.eulerAngles = new Vector3(0, tr.eulerAngles.y, 0);

Vector3 forwardDir = transform.forward;
//Move Forwards - forwardDir is already normalized
forwardDir = forwardDir * speed;
forwardDir *= Mathf.Clamp01 (Vector3.Dot (dir.normalized, tr.forward));

if (navmeshController != null) {
navmeshController.SimpleMove (tr.position,forwardDir);
} else {
controller.SimpleMove (forwardDir);
}
//Set animation
tr.animation.Play ("run");
}
else
{
tr.animation.Play ("idle");
}
}

/** Draws helper gizmos.
* Currently draws a circle around the current target point with the size showing how close the AI need to get to it for it to count as "reached".
*/
public void OnDrawGizmos () {

if (!drawGizmos || path == null || pathIndex >= path.Length || pathIndex < 0) {
return;
}

Vector3 currentWaypoint = path[pathIndex];
currentWaypoint.y = tr.position.y;

Debug.DrawLine (transform.position,currentWaypoint,Color.blue);

float rad = pickNextWaypointDistance;
if (pathIndex == path.Length-1) {
rad *= targetReached;
}

Vector3 pP = currentWaypoint + rad*new Vector3 (1,0,0);
for (float i=0;i<2*System.Math.PI;i+= 0.1F) {
Vector3 cP = currentWaypoint + new Vector3 ((float)System.Math.Cos (i)*rad,0,(float)System.Math.Sin(i)*rad);
Debug.DrawLine (pP,cP,Color.yellow);
pP = cP;
}
Debug.DrawLine (pP, currentWaypoint + rad*new Vector3 (1,0,0),Color.yellow);
}

}
 
СообщениеЩа попробую закинуть smile Первый раз у Вас тут smile

Код

using UnityEngine;
using System.Collections;
using Pathfinding;

/** Example AI.
* \deprecated This script has been deprecated, use AIPath or MineBotAI instead */
[RequireComponent (typeof(Seeker))]
[RequireComponent (typeof(CharacterController))]
public class AIFollow : MonoBehaviour {

/** Target to move to */
public Transform target;

/** How often to search for a new path */
public float repathRate = 0.1F;

/** The minimum distance to a waypoint to consider it as "reached" */
public float pickNextWaypointDistance = 2F;

/** The minimum distance to the end point of a path to consider it "reached" (multiplied with #pickNextWaypointDistance).
* This value is multiplied with #pickNextWaypointDistance before it is used. Recommended range [0...1] */
public float targetReached = 1.0F;

/** Units per second */
public float speed = 6;

/** How fast the AI can turn around */
public float rotationSpeed = 7;

public bool drawGizmos = false;

/** Should paths be searched for.
* Setting this to false will make the AI not search for paths anymore, can save some CPU cycles.
* It will check every #repathRate seconds if it should start to search for paths again.
* \note It will not cancel paths which are currently being calculated */
public bool canSearch = true;

/** Can it move. Enables or disables movement and rotation */
public bool canMove = true;

/** Seeker component which handles pathfinding calls */
protected Seeker seeker;

/** CharacterController which handles movement */
protected CharacterController controller;

/** NavmeshController which handles movement if not null*/
protected NavmeshController navmeshController;

/** Transform, cached because of performance */
protected Transform tr;

protected float lastPathSearch = -9999;

protected int pathIndex = 0;

/** This is the path the AI is currently following */
protected Vector3[] path;

/** Use this for initialization */
public void Start () {
seeker = GetComponent<Seeker>();
controller = GetComponent<CharacterController>();
navmeshController = GetComponent<NavmeshController>();

tr = transform;
Repath ();
}

/** Will make the AI give up it's current path and stop completely. */
public void Reset () {
path = null;
}

/** Called when a path has completed it's calculation */
public void OnPathComplete (Path p) {

/*if (Time.time-lastPathSearch >= repathRate) {
Repath ();
} else {*/
StartCoroutine (WaitToRepath ());
//}

//If the path didn't succeed, don't proceed
if (p.error) {
return;
}

//Get the calculated path as a Vector3 array
path = p.vectorPath;

//Find the segment in the path which is closest to the AI
//If a closer segment hasn't been found in '6' iterations, break because it is unlikely to find any closer ones then
float minDist = Mathf.Infinity;
int notCloserHits = 0;

for (int i=0;i<path.Length-1;i++) {
float dist = Mathfx.DistancePointSegmentStrict (path[i],path[i+1],tr.position);
if (dist < minDist) {
notCloserHits = 0;
minDist = dist;
pathIndex = i+1;
} else if (notCloserHits > 6) {
break;
}
}
}

/** Waits the remaining time until the AI should issue a new path request.
* The remaining time is defined by Time.time - lastPathSearch */
public IEnumerator WaitToRepath () {
float timeLeft = repathRate - (Time.time-lastPathSearch);

yield return new WaitForSeconds (timeLeft);
Repath ();
}

/** Stops the AI.
* Also stops new search queries from being made
* \version Before 3.0.8 This does not prevent new path calls from making the AI move again
* \see #Resume
* \see #canMove
* \see #canSearch */
public void Stop () {
canMove = false;
canSearch = false;
}

/** Resumes walking and path searching the AI.
* \version Added in 3.0.8
* \see #Stop
* \see #canMove
* \see #canSearch */
public void Resume () {
canMove = true;
canSearch = true;
}

/** Recalculates the path to #target.
* Queries a path request to the Seeker, the path will not be calculated instantly, but will be put on a queue and calculated as fast as possible.
* It will wait if the current path request by this seeker has not been completed yet.
* \see Seeker::IsDone */
public virtual void Repath () {
lastPathSearch = Time.time;

if (seeker == null || target == null || !canSearch || !seeker.IsDone ()) {
StartCoroutine (WaitToRepath ());
return;
}

//for (int i=0;i<1000;i++) {
//MultithreadPath mp = new MultithreadPath (transform.position,target.position,null);
//Path p = new Path (transform.position,target.position,null);
//    AstarPath.StartPath (mp);
//}
//Debug.Log (AstarPath.pathQueue.Count);

//StartCoroutine (WaitToRepath ());
/*ConstantPath cpath = new ConstantPath(transform.position,null);
//Must be set to avoid it from searching towards Vector3.zero
cpath.heuristic = Heuristic.None;
//Here you set how far it should search
cpath.maxGScore = 2000;
AstarPath.StartPath (cpath);*/
//FloodPathTracer fpathTrace = new FloodPathTracer (transform.position,fpath,null);
//seeker.StartPath (fpathTrace,OnPathComplete);

Path p = new Path(transform.position,target.position,null);
seeker.StartPath (p,OnPathComplete);
//Start a new path from transform.positon to target.position, return the result to the function OnPathComplete
//seeker.StartPath (transform.position,target.position,OnPathComplete);
}

/** Start a new path moving to \a targetPoint */
public void PathToTarget (Vector3 targetPoint) {
lastPathSearch = Time.time;

if (seeker == null) {
return;
}

//Start a new path from transform.positon to target.position, return the result to OnPathComplete
seeker.StartPath (transform.position,targetPoint,OnPathComplete);
}

/** Called when the AI reached the end of path.
* This will be called once for every path it completes, so if you have a really fast repath rate it will call this function often if when it stands on the end point.
*/
public virtual void ReachedEndOfPath () {
//The AI has reached the end of the path
//Set animation
tr.animation.Play("attack");
tr.LookAt(target.position);
tr.eulerAngles = new Vector3(0, tr.eulerAngles.y, 0);
}

/** Update is called once per frame */
public void Update () {

float dist = Vector3.Distance(target.position, transform.position);
//bool luch = Physics.Raycast (transform.position,target.position);
if(dist <=40)
{

if (path == null || pathIndex >= path.Length || pathIndex < 0 || !canMove) {
return;
}

//Change target to the next waypoint if the current one is close enough
Vector3 currentWaypoint = path[pathIndex];
currentWaypoint.y = tr.position.y;
while ((currentWaypoint - tr.position).sqrMagnitude < pickNextWaypointDistance*pickNextWaypointDistance) {
pathIndex++;
if (pathIndex >= path.Length) {
//Use a lower pickNextWaypointDistance for the last point. If it isn't that close, then decrement the pathIndex to the previous value and break the loop
if ((currentWaypoint - tr.position).sqrMagnitude < (pickNextWaypointDistance*targetReached)*(pickNextWaypointDistance*targetReached)) {
ReachedEndOfPath ();
return;
} else {
pathIndex--;
//Break the loop, otherwise it will try to check for the last point in an infinite loop
break;
}
}
currentWaypoint = path[pathIndex];
currentWaypoint.y = tr.position.y;
}

Vector3 dir = currentWaypoint - tr.position;

// Rotate towards the target
tr.rotation = Quaternion.Slerp (tr.rotation, Quaternion.LookRotation(dir), rotationSpeed * Time.deltaTime);
tr.eulerAngles = new Vector3(0, tr.eulerAngles.y, 0);

Vector3 forwardDir = transform.forward;
//Move Forwards - forwardDir is already normalized
forwardDir = forwardDir * speed;
forwardDir *= Mathf.Clamp01 (Vector3.Dot (dir.normalized, tr.forward));

if (navmeshController != null) {
navmeshController.SimpleMove (tr.position,forwardDir);
} else {
controller.SimpleMove (forwardDir);
}
//Set animation
tr.animation.Play ("run");
}
else
{
tr.animation.Play ("idle");
}
}

/** Draws helper gizmos.
* Currently draws a circle around the current target point with the size showing how close the AI need to get to it for it to count as "reached".
*/
public void OnDrawGizmos () {

if (!drawGizmos || path == null || pathIndex >= path.Length || pathIndex < 0) {
return;
}

Vector3 currentWaypoint = path[pathIndex];
currentWaypoint.y = tr.position.y;

Debug.DrawLine (transform.position,currentWaypoint,Color.blue);

float rad = pickNextWaypointDistance;
if (pathIndex == path.Length-1) {
rad *= targetReached;
}

Vector3 pP = currentWaypoint + rad*new Vector3 (1,0,0);
for (float i=0;i<2*System.Math.PI;i+= 0.1F) {
Vector3 cP = currentWaypoint + new Vector3 ((float)System.Math.Cos (i)*rad,0,(float)System.Math.Sin(i)*rad);
Debug.DrawLine (pP,cP,Color.yellow);
pP = cP;
}
Debug.DrawLine (pP, currentWaypoint + rad*new Vector3 (1,0,0),Color.yellow);
}

}

Автор - dostalition
Дата добавления - 21 Янв 2013 в 14:03
thiefbrotherДата: Вт, 22 Янв 2013, 15:48 | Сообщение # 6
 
Сообщений: 74
Награды: 0
Репутация: 10
Статус: Offline
есть очень хороший пример по раю в справке юньки.
вот этот
а именно :
Код
   void Update() {
          Vector3 fwd = transform.TransformDirection(Vector3.forward);
          if (Physics.Raycast(transform.position, fwd, 10))
              print("There is something in front of the object!");
            
      }
}

этот код разъясняется так :
Код
Vector3 fwd = transform.TransformDirection(Vector3.forward); // создается вектор направления луча,   
//направлен он вперед от нашего игрока(transform), ну по идее   
   //не обязательно игрока, это может быть что угодно .
          if (Physics.Raycast(transform.position, fwd, 10)) // если Луч(позиция, откуда будет бросаться наш луч(в данном случае это наш субъект(transform)) и   
// задается направление (fwd), которую мы задавали выше
// и расстояние "10" , 10 юнитов/метров.   
// Получается у нас, тут условие : Если от начальной точки, до точки конца луча на 10 юнитов есть что-нибудь, то пишется   
              print("There is something in front of the object!"); // вот это

А вот урок , где разъясняют довольна четко про райкаст и столкновения с лучом .
Ссылка_ТЫК
С помощью этого, сделайте мобов умнее :))


Сообщение отредактировал thiefbrother - Вт, 22 Янв 2013, 15:50
 
Сообщениеесть очень хороший пример по раю в справке юньки.
вот этот
а именно :
Код
   void Update() {
          Vector3 fwd = transform.TransformDirection(Vector3.forward);
          if (Physics.Raycast(transform.position, fwd, 10))
              print("There is something in front of the object!");
            
      }
}

этот код разъясняется так :
Код
Vector3 fwd = transform.TransformDirection(Vector3.forward); // создается вектор направления луча,   
//направлен он вперед от нашего игрока(transform), ну по идее   
   //не обязательно игрока, это может быть что угодно .
          if (Physics.Raycast(transform.position, fwd, 10)) // если Луч(позиция, откуда будет бросаться наш луч(в данном случае это наш субъект(transform)) и   
// задается направление (fwd), которую мы задавали выше
// и расстояние "10" , 10 юнитов/метров.   
// Получается у нас, тут условие : Если от начальной точки, до точки конца луча на 10 юнитов есть что-нибудь, то пишется   
              print("There is something in front of the object!"); // вот это

А вот урок , где разъясняют довольна четко про райкаст и столкновения с лучом .
Ссылка_ТЫК
С помощью этого, сделайте мобов умнее :))

Автор - thiefbrother
Дата добавления - 22 Янв 2013 в 15:48
dostalitionДата: Вт, 22 Янв 2013, 21:56 | Сообщение # 7
 
Сообщений: 155
Награды: 0
Репутация: 9
Статус: Offline
БЛИН ! Написал ответ, а он не появился :(( Ща заново наштампую sad smile БЛАГОДАРЮ ЗА ОТВЕТ smile Я уже кое-что разчехлил ... smile Вот решил сделать зрение при помощи триггера-бокса и лайнкаста. Триггер повесил на моба так, чтобы он ловил игрока по площади спереди и по бокам (типа бокового зрения), ну , а лайн проверяет нет ли прекрад между мобом и гроком , и ввёл переменную VIDIT, которая становится правдивой, когда именно ИГРОК попадает в триггер и луч его достаёт. Вот скрипт using UnityEngine;
Код
using System.Collections;

public class ZRENIE : MonoBehaviour {

public bool VIDIT;

public Transform target;

void OnTriggerStay(Collider other) {

var layerMask = 1 << 9 | 1 << 8;

if (other.gameObject.name == "Player1" && !Physics.Linecast (transform.position, target.position, layerMask))
{
VIDIT = true;

}

else{
VIDIT = false;}

}

void OnTriggerExit(Collider other) {

if (other.gameObject.name == "Player1")
{
VIDIT = false;}

}

}


Добавлено (22.01.2013, 21:53)
---------------------------------------------
Блин , опять неправильно код вставил сюда ... Надо между рамочками ? :)) Ну, так вот ... Это только скрипт зрения, сам по себе он работает нормально, а нахождение пути и передвижение в других находятся ... Так вот теперь Я не могу никак нормально эти скрипты соединить. Вот , в частности, нужно это "зрение" добавить в скрипт AIFollow, который Я подготовил, как мог, но результат неутешительный ... Может подскажет Кто как правильно прицепить ЗРЕНИЕ К СЛЕЖЕНИЮ smile Переменная VIDIT открытая, использую её из скрипта AIFollow , там для этого переменная VZOR
Код
using UnityEngine;
using System.Collections;
using Pathfinding;

/** Example AI.
* \deprecated This script has been deprecated, use AIPath or MineBotAI instead */
[RequireComponent (typeof(Seeker))]
[RequireComponent (typeof(CharacterController))]
public class AIFollow : MonoBehaviour {
public bool VZOR;
/** Target to move to */
public Transform target;

/** How often to search for a new path */
public float repathRate = 0.1F;

/** The minimum distance to a waypoint to consider it as "reached" */
public float pickNextWaypointDistance = 2F;

/** The minimum distance to the end point of a path to consider it "reached" (multiplied with #pickNextWaypointDistance).
* This value is multiplied with #pickNextWaypointDistance before it is used. Recommended range [0...1] */
public float targetReached = 1.0F;

/** Units per second */
public float speed = 6;

/** How fast the AI can turn around */
public float rotationSpeed = 7;

public bool drawGizmos = false;

/** Should paths be searched for.
* Setting this to false will make the AI not search for paths anymore, can save some CPU cycles.
* It will check every #repathRate seconds if it should start to search for paths again.
* \note It will not cancel paths which are currently being calculated */
public bool canSearch = true;

/** Can it move. Enables or disables movement and rotation */
public bool canMove = true;

/** Seeker component which handles pathfinding calls */
protected Seeker seeker;

/** CharacterController which handles movement */
protected CharacterController controller;

/** NavmeshController which handles movement if not null*/
protected NavmeshController navmeshController;

/** Transform, cached because of performance */
protected Transform tr;

protected float lastPathSearch = -9999;

protected int pathIndex = 0;

/** This is the path the AI is currently following */
protected Vector3[] path;

/** Use this for initialization */
public void Start () {
seeker = GetComponent<Seeker>();
controller = GetComponent<CharacterController>();
navmeshController = GetComponent<NavmeshController>();

tr = transform;
Repath ();
}

/** Will make the AI give up it's current path and stop completely. */
public void Reset () {
path = null;
}

/** Called when a path has completed it's calculation */
public void OnPathComplete (Path p) {

/*if (Time.time-lastPathSearch >= repathRate) {
Repath ();
} else {*/
StartCoroutine (WaitToRepath ());
//}

//If the path didn't succeed, don't proceed
if (p.error) {
return;
}

//Get the calculated path as a Vector3 array
path = p.vectorPath;

//Find the segment in the path which is closest to the AI
//If a closer segment hasn't been found in '6' iterations, break because it is unlikely to find any closer ones then
float minDist = Mathf.Infinity;
int notCloserHits = 0;

for (int i=0;i<path.Length-1;i++) {
float dist = Mathfx.DistancePointSegmentStrict (path[i],path[i+1],tr.position);
if (dist < minDist) {
notCloserHits = 0;
minDist = dist;
pathIndex = i+1;
} else if (notCloserHits > 6) {
break;
}
}
}

/** Waits the remaining time until the AI should issue a new path request.
* The remaining time is defined by Time.time - lastPathSearch */
public IEnumerator WaitToRepath () {
float timeLeft = repathRate - (Time.time-lastPathSearch);

yield return new WaitForSeconds (timeLeft);
Repath ();
}

/** Stops the AI.
* Also stops new search queries from being made
* \version Before 3.0.8 This does not prevent new path calls from making the AI move again
* \see #Resume
* \see #canMove
* \see #canSearch */
public void Stop () {
canMove = false;
canSearch = false;
}

/** Resumes walking and path searching the AI.
* \version Added in 3.0.8
* \see #Stop
* \see #canMove
* \see #canSearch */
public void Resume () {
canMove = true;
canSearch = true;
}

/** Recalculates the path to #target.
* Queries a path request to the Seeker, the path will not be calculated instantly, but will be put on a queue and calculated as fast as possible.
* It will wait if the current path request by this seeker has not been completed yet.
* \see Seeker::IsDone */
public virtual void Repath () {
lastPathSearch = Time.time;

if (seeker == null || target == null || !canSearch || !seeker.IsDone ()) {
StartCoroutine (WaitToRepath ());
return;
}

//for (int i=0;i<1000;i++) {
//MultithreadPath mp = new MultithreadPath (transform.position,target.position,null);
//Path p = new Path (transform.position,target.position,null);
//    AstarPath.StartPath (mp);
//}
//Debug.Log (AstarPath.pathQueue.Count);

//StartCoroutine (WaitToRepath ());
/*ConstantPath cpath = new ConstantPath(transform.position,null);
//Must be set to avoid it from searching towards Vector3.zero
cpath.heuristic = Heuristic.None;
//Here you set how far it should search
cpath.maxGScore = 2000;
AstarPath.StartPath (cpath);*/
//FloodPathTracer fpathTrace = new FloodPathTracer (transform.position,fpath,null);
//seeker.StartPath (fpathTrace,OnPathComplete);

Path p = new Path(transform.position,target.position,null);
seeker.StartPath (p,OnPathComplete);
//Start a new path from transform.positon to target.position, return the result to the function OnPathComplete
//seeker.StartPath (transform.position,target.position,OnPathComplete);
}

/** Start a new path moving to \a targetPoint */
public void PathToTarget (Vector3 targetPoint) {
lastPathSearch = Time.time;

if (seeker == null) {
return;
}

//Start a new path from transform.positon to target.position, return the result to OnPathComplete
seeker.StartPath (transform.position,targetPoint,OnPathComplete);
}

/** Called when the AI reached the end of path.
* This will be called once for every path it completes, so if you have a really fast repath rate it will call this function often if when it stands on the end point.
*/
public virtual void ReachedEndOfPath () {
//The AI has reached the end of the path
//Set animation
tr.animation.Play("attack");
tr.LookAt(target.position);
tr.eulerAngles = new Vector3(0, tr.eulerAngles.y, 0);
}

/** Update is called once per frame */
public void Update () {
VZOR = GameObject.Find("TRIG").GetComponent<ZRENIE>().VIDIT;
if(VZOR == true)
{

if (path == null || pathIndex >= path.Length || pathIndex < 0 || !canMove) {
return;
}

//Change target to the next waypoint if the current one is close enough
Vector3 currentWaypoint = path[pathIndex];
currentWaypoint.y = tr.position.y;
while ((currentWaypoint - tr.position).sqrMagnitude < pickNextWaypointDistance*pickNextWaypointDistance) {
pathIndex++;
if (pathIndex >= path.Length) {
//Use a lower pickNextWaypointDistance for the last point. If it isn't that close, then decrement the pathIndex to the previous value and break the loop
if ((currentWaypoint - tr.position).sqrMagnitude < (pickNextWaypointDistance*targetReached)*(pickNextWaypointDistance*targetReached)) {
ReachedEndOfPath ();
return;
} else {
pathIndex--;
//Break the loop, otherwise it will try to check for the last point in an infinite loop
break;
}
}
currentWaypoint = path[pathIndex];
currentWaypoint.y = tr.position.y;
}

Vector3 dir = currentWaypoint - tr.position;

// Rotate towards the target
tr.rotation = Quaternion.Slerp (tr.rotation, Quaternion.LookRotation(dir), rotationSpeed * Time.deltaTime);
tr.eulerAngles = new Vector3(0, tr.eulerAngles.y, 0);

Vector3 forwardDir = transform.forward;
//Move Forwards - forwardDir is already normalized
forwardDir = forwardDir * speed;
forwardDir *= Mathf.Clamp01 (Vector3.Dot (dir.normalized, tr.forward));

if (navmeshController != null) {
navmeshController.SimpleMove (tr.position,forwardDir);
} else {
controller.SimpleMove (forwardDir);
}
//Set animation
tr.animation.Play ("run");
}
else
{

tr.animation.Play ("idle");
}
}

/** Draws helper gizmos.
* Currently draws a circle around the current target point with the size showing how close the AI need to get to it for it to count as "reached".
*/
public void OnDrawGizmos () {

if (!drawGizmos || path == null || pathIndex >= path.Length || pathIndex < 0) {
return;
}

Vector3 currentWaypoint = path[pathIndex];
currentWaypoint.y = tr.position.y;

Debug.DrawLine (transform.position,currentWaypoint,Color.blue);

float rad = pickNextWaypointDistance;
if (pathIndex == path.Length-1) {
rad *= targetReached;
}

Vector3 pP = currentWaypoint + rad*new Vector3 (1,0,0);
for (float i=0;i<2*System.Math.PI;i+= 0.1F) {
Vector3 cP = currentWaypoint + new Vector3 ((float)System.Math.Cos (i)*rad,0,(float)System.Math.Sin(i)*rad);
Debug.DrawLine (pP,cP,Color.yellow);
pP = cP;
}
Debug.DrawLine (pP, currentWaypoint + rad*new Vector3 (1,0,0),Color.yellow);
}

}


Добавлено (22.01.2013, 21:56)
---------------------------------------------
Жду помощи ... smile И скажите КТО-НИБУДЬ как правильно вставлять сюда код !!!
 
СообщениеБЛИН ! Написал ответ, а он не появился :(( Ща заново наштампую sad smile БЛАГОДАРЮ ЗА ОТВЕТ smile Я уже кое-что разчехлил ... smile Вот решил сделать зрение при помощи триггера-бокса и лайнкаста. Триггер повесил на моба так, чтобы он ловил игрока по площади спереди и по бокам (типа бокового зрения), ну , а лайн проверяет нет ли прекрад между мобом и гроком , и ввёл переменную VIDIT, которая становится правдивой, когда именно ИГРОК попадает в триггер и луч его достаёт. Вот скрипт using UnityEngine;
Код
using System.Collections;

public class ZRENIE : MonoBehaviour {

public bool VIDIT;

public Transform target;

void OnTriggerStay(Collider other) {

var layerMask = 1 << 9 | 1 << 8;

if (other.gameObject.name == "Player1" && !Physics.Linecast (transform.position, target.position, layerMask))
{
VIDIT = true;

}

else{
VIDIT = false;}

}

void OnTriggerExit(Collider other) {

if (other.gameObject.name == "Player1")
{
VIDIT = false;}

}

}


Добавлено (22.01.2013, 21:53)
---------------------------------------------
Блин , опять неправильно код вставил сюда ... Надо между рамочками ? :)) Ну, так вот ... Это только скрипт зрения, сам по себе он работает нормально, а нахождение пути и передвижение в других находятся ... Так вот теперь Я не могу никак нормально эти скрипты соединить. Вот , в частности, нужно это "зрение" добавить в скрипт AIFollow, который Я подготовил, как мог, но результат неутешительный ... Может подскажет Кто как правильно прицепить ЗРЕНИЕ К СЛЕЖЕНИЮ smile Переменная VIDIT открытая, использую её из скрипта AIFollow , там для этого переменная VZOR
Код
using UnityEngine;
using System.Collections;
using Pathfinding;

/** Example AI.
* \deprecated This script has been deprecated, use AIPath or MineBotAI instead */
[RequireComponent (typeof(Seeker))]
[RequireComponent (typeof(CharacterController))]
public class AIFollow : MonoBehaviour {
public bool VZOR;
/** Target to move to */
public Transform target;

/** How often to search for a new path */
public float repathRate = 0.1F;

/** The minimum distance to a waypoint to consider it as "reached" */
public float pickNextWaypointDistance = 2F;

/** The minimum distance to the end point of a path to consider it "reached" (multiplied with #pickNextWaypointDistance).
* This value is multiplied with #pickNextWaypointDistance before it is used. Recommended range [0...1] */
public float targetReached = 1.0F;

/** Units per second */
public float speed = 6;

/** How fast the AI can turn around */
public float rotationSpeed = 7;

public bool drawGizmos = false;

/** Should paths be searched for.
* Setting this to false will make the AI not search for paths anymore, can save some CPU cycles.
* It will check every #repathRate seconds if it should start to search for paths again.
* \note It will not cancel paths which are currently being calculated */
public bool canSearch = true;

/** Can it move. Enables or disables movement and rotation */
public bool canMove = true;

/** Seeker component which handles pathfinding calls */
protected Seeker seeker;

/** CharacterController which handles movement */
protected CharacterController controller;

/** NavmeshController which handles movement if not null*/
protected NavmeshController navmeshController;

/** Transform, cached because of performance */
protected Transform tr;

protected float lastPathSearch = -9999;

protected int pathIndex = 0;

/** This is the path the AI is currently following */
protected Vector3[] path;

/** Use this for initialization */
public void Start () {
seeker = GetComponent<Seeker>();
controller = GetComponent<CharacterController>();
navmeshController = GetComponent<NavmeshController>();

tr = transform;
Repath ();
}

/** Will make the AI give up it's current path and stop completely. */
public void Reset () {
path = null;
}

/** Called when a path has completed it's calculation */
public void OnPathComplete (Path p) {

/*if (Time.time-lastPathSearch >= repathRate) {
Repath ();
} else {*/
StartCoroutine (WaitToRepath ());
//}

//If the path didn't succeed, don't proceed
if (p.error) {
return;
}

//Get the calculated path as a Vector3 array
path = p.vectorPath;

//Find the segment in the path which is closest to the AI
//If a closer segment hasn't been found in '6' iterations, break because it is unlikely to find any closer ones then
float minDist = Mathf.Infinity;
int notCloserHits = 0;

for (int i=0;i<path.Length-1;i++) {
float dist = Mathfx.DistancePointSegmentStrict (path[i],path[i+1],tr.position);
if (dist < minDist) {
notCloserHits = 0;
minDist = dist;
pathIndex = i+1;
} else if (notCloserHits > 6) {
break;
}
}
}

/** Waits the remaining time until the AI should issue a new path request.
* The remaining time is defined by Time.time - lastPathSearch */
public IEnumerator WaitToRepath () {
float timeLeft = repathRate - (Time.time-lastPathSearch);

yield return new WaitForSeconds (timeLeft);
Repath ();
}

/** Stops the AI.
* Also stops new search queries from being made
* \version Before 3.0.8 This does not prevent new path calls from making the AI move again
* \see #Resume
* \see #canMove
* \see #canSearch */
public void Stop () {
canMove = false;
canSearch = false;
}

/** Resumes walking and path searching the AI.
* \version Added in 3.0.8
* \see #Stop
* \see #canMove
* \see #canSearch */
public void Resume () {
canMove = true;
canSearch = true;
}

/** Recalculates the path to #target.
* Queries a path request to the Seeker, the path will not be calculated instantly, but will be put on a queue and calculated as fast as possible.
* It will wait if the current path request by this seeker has not been completed yet.
* \see Seeker::IsDone */
public virtual void Repath () {
lastPathSearch = Time.time;

if (seeker == null || target == null || !canSearch || !seeker.IsDone ()) {
StartCoroutine (WaitToRepath ());
return;
}

//for (int i=0;i<1000;i++) {
//MultithreadPath mp = new MultithreadPath (transform.position,target.position,null);
//Path p = new Path (transform.position,target.position,null);
//    AstarPath.StartPath (mp);
//}
//Debug.Log (AstarPath.pathQueue.Count);

//StartCoroutine (WaitToRepath ());
/*ConstantPath cpath = new ConstantPath(transform.position,null);
//Must be set to avoid it from searching towards Vector3.zero
cpath.heuristic = Heuristic.None;
//Here you set how far it should search
cpath.maxGScore = 2000;
AstarPath.StartPath (cpath);*/
//FloodPathTracer fpathTrace = new FloodPathTracer (transform.position,fpath,null);
//seeker.StartPath (fpathTrace,OnPathComplete);

Path p = new Path(transform.position,target.position,null);
seeker.StartPath (p,OnPathComplete);
//Start a new path from transform.positon to target.position, return the result to the function OnPathComplete
//seeker.StartPath (transform.position,target.position,OnPathComplete);
}

/** Start a new path moving to \a targetPoint */
public void PathToTarget (Vector3 targetPoint) {
lastPathSearch = Time.time;

if (seeker == null) {
return;
}

//Start a new path from transform.positon to target.position, return the result to OnPathComplete
seeker.StartPath (transform.position,targetPoint,OnPathComplete);
}

/** Called when the AI reached the end of path.
* This will be called once for every path it completes, so if you have a really fast repath rate it will call this function often if when it stands on the end point.
*/
public virtual void ReachedEndOfPath () {
//The AI has reached the end of the path
//Set animation
tr.animation.Play("attack");
tr.LookAt(target.position);
tr.eulerAngles = new Vector3(0, tr.eulerAngles.y, 0);
}

/** Update is called once per frame */
public void Update () {
VZOR = GameObject.Find("TRIG").GetComponent<ZRENIE>().VIDIT;
if(VZOR == true)
{

if (path == null || pathIndex >= path.Length || pathIndex < 0 || !canMove) {
return;
}

//Change target to the next waypoint if the current one is close enough
Vector3 currentWaypoint = path[pathIndex];
currentWaypoint.y = tr.position.y;
while ((currentWaypoint - tr.position).sqrMagnitude < pickNextWaypointDistance*pickNextWaypointDistance) {
pathIndex++;
if (pathIndex >= path.Length) {
//Use a lower pickNextWaypointDistance for the last point. If it isn't that close, then decrement the pathIndex to the previous value and break the loop
if ((currentWaypoint - tr.position).sqrMagnitude < (pickNextWaypointDistance*targetReached)*(pickNextWaypointDistance*targetReached)) {
ReachedEndOfPath ();
return;
} else {
pathIndex--;
//Break the loop, otherwise it will try to check for the last point in an infinite loop
break;
}
}
currentWaypoint = path[pathIndex];
currentWaypoint.y = tr.position.y;
}

Vector3 dir = currentWaypoint - tr.position;

// Rotate towards the target
tr.rotation = Quaternion.Slerp (tr.rotation, Quaternion.LookRotation(dir), rotationSpeed * Time.deltaTime);
tr.eulerAngles = new Vector3(0, tr.eulerAngles.y, 0);

Vector3 forwardDir = transform.forward;
//Move Forwards - forwardDir is already normalized
forwardDir = forwardDir * speed;
forwardDir *= Mathf.Clamp01 (Vector3.Dot (dir.normalized, tr.forward));

if (navmeshController != null) {
navmeshController.SimpleMove (tr.position,forwardDir);
} else {
controller.SimpleMove (forwardDir);
}
//Set animation
tr.animation.Play ("run");
}
else
{

tr.animation.Play ("idle");
}
}

/** Draws helper gizmos.
* Currently draws a circle around the current target point with the size showing how close the AI need to get to it for it to count as "reached".
*/
public void OnDrawGizmos () {

if (!drawGizmos || path == null || pathIndex >= path.Length || pathIndex < 0) {
return;
}

Vector3 currentWaypoint = path[pathIndex];
currentWaypoint.y = tr.position.y;

Debug.DrawLine (transform.position,currentWaypoint,Color.blue);

float rad = pickNextWaypointDistance;
if (pathIndex == path.Length-1) {
rad *= targetReached;
}

Vector3 pP = currentWaypoint + rad*new Vector3 (1,0,0);
for (float i=0;i<2*System.Math.PI;i+= 0.1F) {
Vector3 cP = currentWaypoint + new Vector3 ((float)System.Math.Cos (i)*rad,0,(float)System.Math.Sin(i)*rad);
Debug.DrawLine (pP,cP,Color.yellow);
pP = cP;
}
Debug.DrawLine (pP, currentWaypoint + rad*new Vector3 (1,0,0),Color.yellow);
}

}


Добавлено (22.01.2013, 21:56)
---------------------------------------------
Жду помощи ... smile И скажите КТО-НИБУДЬ как правильно вставлять сюда код !!!

Автор - dostalition
Дата добавления - 22 Янв 2013 в 21:56
thiefbrotherДата: Вт, 22 Янв 2013, 22:11 | Сообщение # 8
 
Сообщений: 74
Награды: 0
Репутация: 10
Статус: Offline
Код
using UnityEngine;  
  using System.Collections;  
  using Pathfinding;  

  /** Example AI.  
  * \deprecated This script has been deprecated, use AIPath or MineBotAI instead */  
  [RequireComponent (typeof(Seeker))]  
  [RequireComponent (typeof(CharacterController))]  
  public class AIFollow : MonoBehaviour {  
  public bool VZOR;  
  /** Target to move to */  
   
  public bool VIDIT;  

   //public Transform target;  

  public Transform target;  

  /** How often to search for a new path */  
  public float repathRate = 0.1F;  

  /** The minimum distance to a waypoint to consider it as "reached" */  
  public float pickNextWaypointDistance = 2F;  

  /** The minimum distance to the end point of a path to consider it "reached" (multiplied with #pickNextWaypointDistance).  
  * This value is multiplied with #pickNextWaypointDistance before it is used. Recommended range [0...1] */  
  public float targetReached = 1.0F;  

  /** Units per second */  
  public float speed = 6;  

  /** How fast the AI can turn around */  
  public float rotationSpeed = 7;  

  public bool drawGizmos = false;  

  /** Should paths be searched for.  
  * Setting this to false will make the AI not search for paths anymore, can save some CPU cycles.  
  * It will check every #repathRate seconds if it should start to search for paths again.  
  * \note It will not cancel paths which are currently being calculated */  
  public bool canSearch = true;  

  /** Can it move. Enables or disables movement and rotation */  
  public bool canMove = true;  

  /** Seeker component which handles pathfinding calls */  
  protected Seeker seeker;  

  /** CharacterController which handles movement */  
  protected CharacterController controller;  

  /** NavmeshController which handles movement if not null*/  
  protected NavmeshController navmeshController;  

  /** Transform, cached because of performance */  
  protected Transform tr;  

  protected float lastPathSearch = -9999;  

  protected int pathIndex = 0;  

  /** This is the path the AI is currently following */  
  protected Vector3[] path;  

  /** Use this for initialization */  
  public void Start () {  
  seeker = GetComponent<Seeker>();  
  controller = GetComponent<CharacterController>();  
  navmeshController = GetComponent<NavmeshController>();  

  tr = transform;  
  Repath ();  
  }  

  /** Will make the AI give up it's current path and stop completely. */  
  public void Reset () {  
  path = null;  
  }  

  /** Called when a path has completed it's calculation */  
  public void OnPathComplete (Path p) {  

  /*if (Time.time-lastPathSearch >= repathRate) {  
  Repath ();  
  } else {*/  
  StartCoroutine (WaitToRepath ());  
  //}  

  //If the path didn't succeed, don't proceed  
  if (p.error) {  
  return;  
  }  

  //Get the calculated path as a Vector3 array  
  path = p.vectorPath;  

  //Find the segment in the path which is closest to the AI  
  //If a closer segment hasn't been found in '6' iterations, break because it is unlikely to find any closer ones then  
  float minDist = Mathf.Infinity;  
  int notCloserHits = 0;  

  for (int i=0;i<path.Length-1;i++) {  
  float dist = Mathfx.DistancePointSegmentStrict (path[i],path[i+1],tr.position);  
  if (dist < minDist) {  
  notCloserHits = 0;  
  minDist = dist;  
  pathIndex = i+1;  
  } else if (notCloserHits > 6) {  
  break;  
  }  
  }  
  }  

  /** Waits the remaining time until the AI should issue a new path request.  
  * The remaining time is defined by Time.time - lastPathSearch */  
  public IEnumerator WaitToRepath () {  
  float timeLeft = repathRate - (Time.time-lastPathSearch);  

  yield return new WaitForSeconds (timeLeft);  
  Repath ();  
  }  

  /** Stops the AI.  
  * Also stops new search queries from being made  
  * \version Before 3.0.8 This does not prevent new path calls from making the AI move again  
  * \see #Resume  
  * \see #canMove  
  * \see #canSearch */  
  public void Stop () {  
  canMove = false;  
  canSearch = false;  
  }  

  /** Resumes walking and path searching the AI.  
  * \version Added in 3.0.8  
  * \see #Stop  
  * \see #canMove  
  * \see #canSearch */  
  public void Resume () {  
  canMove = true;  
  canSearch = true;  
  }  

  /** Recalculates the path to #target.  
  * Queries a path request to the Seeker, the path will not be calculated instantly, but will be put on a queue and calculated as fast as possible.  
  * It will wait if the current path request by this seeker has not been completed yet.  
  * \see Seeker::IsDone */  
  public virtual void Repath () {  
  lastPathSearch = Time.time;  

  if (seeker == null || target == null || !canSearch || !seeker.IsDone ()) {  
  StartCoroutine (WaitToRepath ());  
  return;  
  }  

  //for (int i=0;i<1000;i++) {  
  //MultithreadPath mp = new MultithreadPath (transform.position,target.position,null);  
  //Path p = new Path (transform.position,target.position,null);  
  //    AstarPath.StartPath (mp);  
  //}  
  //Debug.Log (AstarPath.pathQueue.Count);  

  //StartCoroutine (WaitToRepath ());  
  /*ConstantPath cpath = new ConstantPath(transform.position,null);  
  //Must be set to avoid it from searching towards Vector3.zero  
  cpath.heuristic = Heuristic.None;  
  //Here you set how far it should search  
  cpath.maxGScore = 2000;  
  AstarPath.StartPath (cpath);*/  
  //FloodPathTracer fpathTrace = new FloodPathTracer (transform.position,fpath,null);  
  //seeker.StartPath (fpathTrace,OnPathComplete);  

  Path p = new Path(transform.position,target.position,null);  
  seeker.StartPath (p,OnPathComplete);  
  //Start a new path from transform.positon to target.position, return the result to the function OnPathComplete  
  //seeker.StartPath (transform.position,target.position,OnPathComplete);  
  }  

  /** Start a new path moving to \a targetPoint */  
  public void PathToTarget (Vector3 targetPoint) {  
  lastPathSearch = Time.time;  

  if (seeker == null) {  
  return;  
  }  

  //Start a new path from transform.positon to target.position, return the result to OnPathComplete  
  seeker.StartPath (transform.position,targetPoint,OnPathComplete);  
  }  

  /** Called when the AI reached the end of path.  
  * This will be called once for every path it completes, so if you have a really fast repath rate it will call this function often if when it stands on the end point.  
  */  
  public virtual void ReachedEndOfPath () {  
  //The AI has reached the end of the path  
  //Set animation  
  tr.animation.Play("attack");  
  tr.LookAt(target.position);  
  tr.eulerAngles = new Vector3(0, tr.eulerAngles.y, 0);  
  }  

//triggerstay;

void OnTriggerStay(Collider other) {  

  var layerMask = 1 << 9 | 1 << 8;  

  if (other.gameObject.name == "Player1" && !Physics.Linecast (transform.position, target.position, layerMask))  
  {  
  VIDIT = true;  

  }  

  else{  
  VIDIT = false;}  

  }  

  void OnTriggerExit(Collider other) {  

  if (other.gameObject.name == "Player1")  
  {  
  VIDIT = false;}  

  }  

//triggerstat_end;

  /** Update is called once per frame */  
  public void Update () {  
  VZOR = GameObject.Find("TRIG").GetComponent<ZRENIE>().VIDIT;  
  if(VZOR == true)  
  {  

  if (path == null || pathIndex >= path.Length || pathIndex < 0 || !canMove) {  
  return;  
  }  

  //Change target to the next waypoint if the current one is close enough  
  Vector3 currentWaypoint = path[pathIndex];  
  currentWaypoint.y = tr.position.y;  
  while ((currentWaypoint - tr.position).sqrMagnitude < pickNextWaypointDistance*pickNextWaypointDistance) {  
  pathIndex++;  
  if (pathIndex >= path.Length) {  
  //Use a lower pickNextWaypointDistance for the last point. If it isn't that close, then decrement the pathIndex to the previous value and break the loop  
  if ((currentWaypoint - tr.position).sqrMagnitude < (pickNextWaypointDistance*targetReached)*(pickNextWaypointDistance*targetReached)) {  
  ReachedEndOfPath ();  
  return;  
  } else {  
  pathIndex--;  
  //Break the loop, otherwise it will try to check for the last point in an infinite loop  
  break;  
  }  
  }  
  currentWaypoint = path[pathIndex];  
  currentWaypoint.y = tr.position.y;  
  }  

  Vector3 dir = currentWaypoint - tr.position;  

  // Rotate towards the target  
  tr.rotation = Quaternion.Slerp (tr.rotation, Quaternion.LookRotation(dir), rotationSpeed * Time.deltaTime);  
  tr.eulerAngles = new Vector3(0, tr.eulerAngles.y, 0);  

  Vector3 forwardDir = transform.forward;  
  //Move Forwards - forwardDir is already normalized  
  forwardDir = forwardDir * speed;  
  forwardDir *= Mathf.Clamp01 (Vector3.Dot (dir.normalized, tr.forward));  

  if (navmeshController != null) {  
  navmeshController.SimpleMove (tr.position,forwardDir);  
  } else {  
  controller.SimpleMove (forwardDir);  
  }  
  //Set animation  
  tr.animation.Play ("run");  
  }  
  else  
  {  

  tr.animation.Play ("idle");  
  }  
  }  

  /** Draws helper gizmos.  
  * Currently draws a circle around the current target point with the size showing how close the AI need to get to it for it to count as "reached".  
  */  
  public void OnDrawGizmos () {  

  if (!drawGizmos || path == null || pathIndex >= path.Length || pathIndex < 0) {  
  return;  
  }  

  Vector3 currentWaypoint = path[pathIndex];  
  currentWaypoint.y = tr.position.y;  

  Debug.DrawLine (transform.position,currentWaypoint,Color.blue);  

  float rad = pickNextWaypointDistance;  
  if (pathIndex == path.Length-1) {  
  rad *= targetReached;  
  }  

  Vector3 pP = currentWaypoint + rad*new Vector3 (1,0,0);  
  for (float i=0;i<2*System.Math.PI;i+= 0.1F) {  
  Vector3 cP = currentWaypoint + new Vector3 ((float)System.Math.Cos (i)*rad,0,(float)System.Math.Sin(i)*rad);  
  Debug.DrawLine (pP,cP,Color.yellow);  
  pP = cP;  
  }  
  Debug.DrawLine (pP, currentWaypoint + rad*new Vector3 (1,0,0),Color.yellow);  
  }  

  }

как-то так вроде бы
 
Сообщение
Код
using UnityEngine;  
  using System.Collections;  
  using Pathfinding;  

  /** Example AI.  
  * \deprecated This script has been deprecated, use AIPath or MineBotAI instead */  
  [RequireComponent (typeof(Seeker))]  
  [RequireComponent (typeof(CharacterController))]  
  public class AIFollow : MonoBehaviour {  
  public bool VZOR;  
  /** Target to move to */  
   
  public bool VIDIT;  

   //public Transform target;  

  public Transform target;  

  /** How often to search for a new path */  
  public float repathRate = 0.1F;  

  /** The minimum distance to a waypoint to consider it as "reached" */  
  public float pickNextWaypointDistance = 2F;  

  /** The minimum distance to the end point of a path to consider it "reached" (multiplied with #pickNextWaypointDistance).  
  * This value is multiplied with #pickNextWaypointDistance before it is used. Recommended range [0...1] */  
  public float targetReached = 1.0F;  

  /** Units per second */  
  public float speed = 6;  

  /** How fast the AI can turn around */  
  public float rotationSpeed = 7;  

  public bool drawGizmos = false;  

  /** Should paths be searched for.  
  * Setting this to false will make the AI not search for paths anymore, can save some CPU cycles.  
  * It will check every #repathRate seconds if it should start to search for paths again.  
  * \note It will not cancel paths which are currently being calculated */  
  public bool canSearch = true;  

  /** Can it move. Enables or disables movement and rotation */  
  public bool canMove = true;  

  /** Seeker component which handles pathfinding calls */  
  protected Seeker seeker;  

  /** CharacterController which handles movement */  
  protected CharacterController controller;  

  /** NavmeshController which handles movement if not null*/  
  protected NavmeshController navmeshController;  

  /** Transform, cached because of performance */  
  protected Transform tr;  

  protected float lastPathSearch = -9999;  

  protected int pathIndex = 0;  

  /** This is the path the AI is currently following */  
  protected Vector3[] path;  

  /** Use this for initialization */  
  public void Start () {  
  seeker = GetComponent<Seeker>();  
  controller = GetComponent<CharacterController>();  
  navmeshController = GetComponent<NavmeshController>();  

  tr = transform;  
  Repath ();  
  }  

  /** Will make the AI give up it's current path and stop completely. */  
  public void Reset () {  
  path = null;  
  }  

  /** Called when a path has completed it's calculation */  
  public void OnPathComplete (Path p) {  

  /*if (Time.time-lastPathSearch >= repathRate) {  
  Repath ();  
  } else {*/  
  StartCoroutine (WaitToRepath ());  
  //}  

  //If the path didn't succeed, don't proceed  
  if (p.error) {  
  return;  
  }  

  //Get the calculated path as a Vector3 array  
  path = p.vectorPath;  

  //Find the segment in the path which is closest to the AI  
  //If a closer segment hasn't been found in '6' iterations, break because it is unlikely to find any closer ones then  
  float minDist = Mathf.Infinity;  
  int notCloserHits = 0;  

  for (int i=0;i<path.Length-1;i++) {  
  float dist = Mathfx.DistancePointSegmentStrict (path[i],path[i+1],tr.position);  
  if (dist < minDist) {  
  notCloserHits = 0;  
  minDist = dist;  
  pathIndex = i+1;  
  } else if (notCloserHits > 6) {  
  break;  
  }  
  }  
  }  

  /** Waits the remaining time until the AI should issue a new path request.  
  * The remaining time is defined by Time.time - lastPathSearch */  
  public IEnumerator WaitToRepath () {  
  float timeLeft = repathRate - (Time.time-lastPathSearch);  

  yield return new WaitForSeconds (timeLeft);  
  Repath ();  
  }  

  /** Stops the AI.  
  * Also stops new search queries from being made  
  * \version Before 3.0.8 This does not prevent new path calls from making the AI move again  
  * \see #Resume  
  * \see #canMove  
  * \see #canSearch */  
  public void Stop () {  
  canMove = false;  
  canSearch = false;  
  }  

  /** Resumes walking and path searching the AI.  
  * \version Added in 3.0.8  
  * \see #Stop  
  * \see #canMove  
  * \see #canSearch */  
  public void Resume () {  
  canMove = true;  
  canSearch = true;  
  }  

  /** Recalculates the path to #target.  
  * Queries a path request to the Seeker, the path will not be calculated instantly, but will be put on a queue and calculated as fast as possible.  
  * It will wait if the current path request by this seeker has not been completed yet.  
  * \see Seeker::IsDone */  
  public virtual void Repath () {  
  lastPathSearch = Time.time;  

  if (seeker == null || target == null || !canSearch || !seeker.IsDone ()) {  
  StartCoroutine (WaitToRepath ());  
  return;  
  }  

  //for (int i=0;i<1000;i++) {  
  //MultithreadPath mp = new MultithreadPath (transform.position,target.position,null);  
  //Path p = new Path (transform.position,target.position,null);  
  //    AstarPath.StartPath (mp);  
  //}  
  //Debug.Log (AstarPath.pathQueue.Count);  

  //StartCoroutine (WaitToRepath ());  
  /*ConstantPath cpath = new ConstantPath(transform.position,null);  
  //Must be set to avoid it from searching towards Vector3.zero  
  cpath.heuristic = Heuristic.None;  
  //Here you set how far it should search  
  cpath.maxGScore = 2000;  
  AstarPath.StartPath (cpath);*/  
  //FloodPathTracer fpathTrace = new FloodPathTracer (transform.position,fpath,null);  
  //seeker.StartPath (fpathTrace,OnPathComplete);  

  Path p = new Path(transform.position,target.position,null);  
  seeker.StartPath (p,OnPathComplete);  
  //Start a new path from transform.positon to target.position, return the result to the function OnPathComplete  
  //seeker.StartPath (transform.position,target.position,OnPathComplete);  
  }  

  /** Start a new path moving to \a targetPoint */  
  public void PathToTarget (Vector3 targetPoint) {  
  lastPathSearch = Time.time;  

  if (seeker == null) {  
  return;  
  }  

  //Start a new path from transform.positon to target.position, return the result to OnPathComplete  
  seeker.StartPath (transform.position,targetPoint,OnPathComplete);  
  }  

  /** Called when the AI reached the end of path.  
  * This will be called once for every path it completes, so if you have a really fast repath rate it will call this function often if when it stands on the end point.  
  */  
  public virtual void ReachedEndOfPath () {  
  //The AI has reached the end of the path  
  //Set animation  
  tr.animation.Play("attack");  
  tr.LookAt(target.position);  
  tr.eulerAngles = new Vector3(0, tr.eulerAngles.y, 0);  
  }  

//triggerstay;

void OnTriggerStay(Collider other) {  

  var layerMask = 1 << 9 | 1 << 8;  

  if (other.gameObject.name == "Player1" && !Physics.Linecast (transform.position, target.position, layerMask))  
  {  
  VIDIT = true;  

  }  

  else{  
  VIDIT = false;}  

  }  

  void OnTriggerExit(Collider other) {  

  if (other.gameObject.name == "Player1")  
  {  
  VIDIT = false;}  

  }  

//triggerstat_end;

  /** Update is called once per frame */  
  public void Update () {  
  VZOR = GameObject.Find("TRIG").GetComponent<ZRENIE>().VIDIT;  
  if(VZOR == true)  
  {  

  if (path == null || pathIndex >= path.Length || pathIndex < 0 || !canMove) {  
  return;  
  }  

  //Change target to the next waypoint if the current one is close enough  
  Vector3 currentWaypoint = path[pathIndex];  
  currentWaypoint.y = tr.position.y;  
  while ((currentWaypoint - tr.position).sqrMagnitude < pickNextWaypointDistance*pickNextWaypointDistance) {  
  pathIndex++;  
  if (pathIndex >= path.Length) {  
  //Use a lower pickNextWaypointDistance for the last point. If it isn't that close, then decrement the pathIndex to the previous value and break the loop  
  if ((currentWaypoint - tr.position).sqrMagnitude < (pickNextWaypointDistance*targetReached)*(pickNextWaypointDistance*targetReached)) {  
  ReachedEndOfPath ();  
  return;  
  } else {  
  pathIndex--;  
  //Break the loop, otherwise it will try to check for the last point in an infinite loop  
  break;  
  }  
  }  
  currentWaypoint = path[pathIndex];  
  currentWaypoint.y = tr.position.y;  
  }  

  Vector3 dir = currentWaypoint - tr.position;  

  // Rotate towards the target  
  tr.rotation = Quaternion.Slerp (tr.rotation, Quaternion.LookRotation(dir), rotationSpeed * Time.deltaTime);  
  tr.eulerAngles = new Vector3(0, tr.eulerAngles.y, 0);  

  Vector3 forwardDir = transform.forward;  
  //Move Forwards - forwardDir is already normalized  
  forwardDir = forwardDir * speed;  
  forwardDir *= Mathf.Clamp01 (Vector3.Dot (dir.normalized, tr.forward));  

  if (navmeshController != null) {  
  navmeshController.SimpleMove (tr.position,forwardDir);  
  } else {  
  controller.SimpleMove (forwardDir);  
  }  
  //Set animation  
  tr.animation.Play ("run");  
  }  
  else  
  {  

  tr.animation.Play ("idle");  
  }  
  }  

  /** Draws helper gizmos.  
  * Currently draws a circle around the current target point with the size showing how close the AI need to get to it for it to count as "reached".  
  */  
  public void OnDrawGizmos () {  

  if (!drawGizmos || path == null || pathIndex >= path.Length || pathIndex < 0) {  
  return;  
  }  

  Vector3 currentWaypoint = path[pathIndex];  
  currentWaypoint.y = tr.position.y;  

  Debug.DrawLine (transform.position,currentWaypoint,Color.blue);  

  float rad = pickNextWaypointDistance;  
  if (pathIndex == path.Length-1) {  
  rad *= targetReached;  
  }  

  Vector3 pP = currentWaypoint + rad*new Vector3 (1,0,0);  
  for (float i=0;i<2*System.Math.PI;i+= 0.1F) {  
  Vector3 cP = currentWaypoint + new Vector3 ((float)System.Math.Cos (i)*rad,0,(float)System.Math.Sin(i)*rad);  
  Debug.DrawLine (pP,cP,Color.yellow);  
  pP = cP;  
  }  
  Debug.DrawLine (pP, currentWaypoint + rad*new Vector3 (1,0,0),Color.yellow);  
  }  

  }

как-то так вроде бы

Автор - thiefbrother
Дата добавления - 22 Янв 2013 в 22:11
dostalitionДата: Вт, 22 Янв 2013, 23:08 | Сообщение # 9
 
Сообщений: 155
Награды: 0
Репутация: 9
Статус: Offline
БЛАГОДАРЮ ВСЕХ за внимание и помощь ВОПРОС РЕШЕН smile Нужно было убрать лишние проверки вхождения в триггер командой RETURN [/code]using UnityEngine;
Код
using System.Collections;
public class ZRENIE : MonoBehaviour {
public bool VIDIT;
public Transform target;
void OnTriggerStay(Collider other) {
if (other.gameObject.name != "Player1")
return;
var layerMask = 1 << 9 | 1 << 8;
if (other.gameObject.name == "Player1" && !Physics.Linecast (transform.position, target.position, layerMask))
{
VIDIT = true;
}
else{
VIDIT = false;}
}
void OnTriggerExit(Collider other) {
if (other.gameObject.name == "Player1")
{
VIDIT = false;}
}
}
 
СообщениеБЛАГОДАРЮ ВСЕХ за внимание и помощь ВОПРОС РЕШЕН smile Нужно было убрать лишние проверки вхождения в триггер командой RETURN [/code]using UnityEngine;
Код
using System.Collections;
public class ZRENIE : MonoBehaviour {
public bool VIDIT;
public Transform target;
void OnTriggerStay(Collider other) {
if (other.gameObject.name != "Player1")
return;
var layerMask = 1 << 9 | 1 << 8;
if (other.gameObject.name == "Player1" && !Physics.Linecast (transform.position, target.position, layerMask))
{
VIDIT = true;
}
else{
VIDIT = false;}
}
void OnTriggerExit(Collider other) {
if (other.gameObject.name == "Player1")
{
VIDIT = false;}
}
}

Автор - dostalition
Дата добавления - 22 Янв 2013 в 23:08
  • Страница 1 из 1
  • 1
Поиск:
Загрузка...

Game Creating CommUnity © 2009 - 2025