在大多数情况下,这个剧本有效,但是偶尔会有一个敌人在寻路时失败并穿过建筑物或墙壁。有没有办法可以阻止这个?
using UnityEngine;
using System.Collections;
namespace Daniel {
public class EnemyAI : Living {
// Detection private int range = 10; private float speed = 10f; private bool isThereAnyThing = false;
// Waypoints/Targets
public GameObject[] targets;
private float rotationSpeed = 900f;
private RaycastHit hit;
GameObject target;
[SerializeField]
private int randomTarget = 0;
[SerializeField]
float timeToNextCheck = 3;
public float effectTimer = 2f;
public GameObject deathEffect;
public LayerMask detectThis;
void Start()
{
randomTarget = Random.Range(0, 8);
target = targets[randomTarget];
}
void FixedUpdate()
{
timeToNextCheck = timeToNextCheck - Time.deltaTime;
ScanForNewWaypoint();
LookAtTarget();
Move();
CheckForObsticales();
}
void LookAtTarget()
{
//Look At Somthly Towards the Target if there is nothing in front.
if (!isThereAnyThing)
{
Vector3 relativePos = target.transform.position - transform.position;
Quaternion rotation = Quaternion.LookRotation(relativePos);
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime);
}
}
void Move()
{
// Enemy translate in forward direction.
transform.Translate(Vector3.forward * Time.deltaTime * speed);
}
public void CheckForObsticales()
{
//Checking for any Obstacle in front.
// Two rays left and right to the object to detect the obstacle.
Transform leftRay = transform;
Transform rightRay = transform;
//Use Phyics.RayCast to detect the obstacle
if (Physics.Raycast(leftRay.position + (transform.right * 7f), transform.forward, out hit, range, detectThis) || Physics.Raycast(rightRay.position - (transform.right * 7f), transform.forward, out hit, range))
{
if (hit.collider.gameObject.CompareTag("Obstacles"))
{
isThereAnyThing = true;
transform.Rotate(Vector3.up * Time.deltaTime * rotationSpeed);
}
}
// Now Two More RayCast At The End of Object to detect that object has already pass the obsatacle.
// Just making this boolean variable false it means there is nothing in front of object.
if (Physics.Raycast(transform.position - (transform.forward * 4), transform.right, out hit, 10, detectThis) ||
Physics.Raycast(transform.position - (transform.forward * 4), -transform.right, out hit, 10, detectThis))
{
if (hit.collider.gameObject.CompareTag("Obstacles"))
{
isThereAnyThing = false;
}
}
}
public void ScanForNewWaypoint()
{
CheckForObsticales();
if (timeToNextCheck <= 0)
{
timeToNextCheck = Random.Range(6, 3);
randomTarget = Random.Range(0, 8);
target = targets[randomTarget];
}
}
public override void TakeHit(float dmg, Vector3 hitPoint, Vector3 hitDirection)
{
if (dmg >= health)
{
Destroy(Instantiate(deathEffect, hitPoint, Quaternion.FromToRotation(Vector3.forward, hitDirection)) as GameObject, effectTimer);
Debug.Log("Exploded");
}
base.TakeHit(dmg, hitPoint, hitDirection);
}
}
}
答案 0 :(得分:0)
现在,这是人们在使用物理引擎时遇到的最常见问题之一,并且相信我有很多因素会影响您所面临的结果/后果。人们设计的最常见解决方案是使用更新 执行每一帧进行物理计算完全错误。所有与物理相关的计算都需要在固定更新内执行,否则在更新中执行基于物理的模拟将会过于昂贵,这意味着每一帧都是如此。如果您的 Enemy 正在经历墙壁并且物理碰撞缺失,您可以采取的最佳解决方案是调整Unity中的一些物理相关属性这些位于编辑&gt;&gt;&gt;项目设置&gt;&gt;&gt;时间更改检查器中的时间步长和最大允许时间步长,以便将碰撞设置为正确。在处理像尺度,质量和碰撞器等物理时,还要记住一些其他的事情。这里有一个Link关于统一物理设置的详细机制。在处理和调整物理设置之前,请务必阅读并理解链接的内容。