Мне нужно сделать что бы зомби мог видеть игрока постоянно... т.е где бы он ни был он должен добежать до игрока и нанести удар... но почему то когда attackRange делаю больше то ничего не меняется как он терял цель так и теряет...
Если конечно есть код получше с поиском путей что бы зомби могли обойти здание например.... то обьясните чет некоторые моменты в коде не понятны...
- Код: Выделить всё
var speed = 3.0;
var rotationSpeed = 5.0;
//Растояние до стрельбы
var shootRange = 15.0;
//На каком расстоянии он будет видеть цель
var attackRange = 30.0;
//хз зачем
var shootAngle = 4.0;
// тоже хз зачем
var dontComeCloserRange = 5.0;
var delayShootTime = 0.35;
var pickNextWaypointDistance = 2.0;
var target : Transform;
private var lastShot = -10.0;
// Удостоверься, что всегда есть CharacterController
@script RequireComponent (CharacterController)
function Start () {
// Проверяем есль ли цель. т.е игрок
if (target == null && GameObject.FindWithTag("Player"))
target = GameObject.FindWithTag("Player").transform;
Patrol();
}
function Patrol () {
var curWayPoint = AutoWayPoint.FindClosest(transform.position);
while (true) {
var waypointPosition = curWayPoint.transform.position;
// Мы близко к waypoint?-> выбирают следующий!
if (Vector3.Distance(waypointPosition, transform.position) < pickNextWaypointDistance)
curWayPoint = PickNextWaypoint (curWayPoint);
//Напади на игрока и жди до того как
//-игрок убит
//-игрок вне поля зрения
if (CanSeeTarget ())
yield StartCoroutine("AttackPlayer");
// Двинь нашу цель
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 () {
// Анимация выстрела
animation.CrossFade("shoot", 0.3);
// Ждать
yield WaitForSeconds(delayShootTime);
// Огонь
BroadcastMessage("Fire");
// Ждать пока анимация не проиграется
yield WaitForSeconds(animation["shoot"].length - delayShootTime);
}
function AttackPlayer () {
//Получаем позицию цели .те игрока
var lastVisiblePlayerPosition = target.position;
while (true) {
if (CanSeeTarget ()) {
// Если цель (игрок )мертв, то прекратить атаку
if (target == null)
return;
// Получаем расстояние от зомби до цели
var distance = Vector3.Distance(transform.position, target.position);
// Если это расстояние больше чем расстояние до стрельбы умножение на 3 (хз почему)
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);
// Начинаем атаку
if (distance < shootRange && angle < shootAngle)
yield StartCoroutine("Shoot");
} else {
yield StartCoroutine("SearchPlayer", lastVisiblePlayerPosition);
// Потеряли игрока... прекращаем атаку
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;
}
// Поворачиваемся к цели
transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);
// Измени скорость, таким образом мы замедляемся, когда мы не оказываемся перед целью
var forward = transform.TransformDirection(Vector3.forward);
var speedModifier = Vector3.Dot(forward, direction.normalized);
speedModifier = Mathf.Clamp01(speedModifier);
// Двигаемся
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;
}