目录
43、机器人对敌方的检测和移动逻辑
更新PlayerBot.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
using Random = UnityEngine.Random;
public class PlayerBot : Player
{
……
IEnumerator DetectPlayers()
{
yield return new WaitForEndOfFrame();
while (true)
{
inRange.Clear();
Collider[] cols = Physics.OverlapSphere(transform.position, range, LayerMask.GetMask("Player"));
for (int i = 0; i < cols.Length; ++i)
{
Player p = cols[i].gameObject.GetComponent<Player>();
if (p.teamIndex != teamIndex && !inRange.Contains(cols[i].gameObject))
{
inRange.Add(cols[i].gameObject);
}
}
yield return new WaitForSeconds(1);
}
}
private void RandomPoint(Vector3 center, float range, out Vector3 result)
{
result = Vector3.zero;
for (int i = 0; i < 30; ++i)
{
Vector3 randomPoint = center + (Vector3) Random.insideUnitCircle*range;
NavMeshHit hit;
if (NavMesh.SamplePosition(randomPoint, out hit, 1f, NavMesh.AllAreas))
{
result = hit.position;
break;
}
}
agent.SetDestination(result);
}
void FixedUpdate()
{
if (isDead) return;
if (inRange.Count == 0)
{
if (Vector3.Distance(transform.position, targetPoint) < agent.stoppingDistance)
{
RandomPoint(transform.position, range * 3, out targetPoint);
}
}
else
{
if (Vector3.Distance(transform.position, targetPoint) < agent.stoppingDistance)
{
RandomPoint(inRange[0].transform.position, range * 2, out targetPoint);
}
}
}
}
44、Navmesh路径
选择窗口-AI-导航,生成如下
此时烘培了,发现地形上山坡上有些地方,也在范围内,所以只能自定义了
这样就自己制作cube来确定路线范围了
当前cube上显示浅蓝色,所以路线范围覆盖到了这个cube上,所以为了全面覆盖地图,就制作很多个cube,如图
为了方便演示,将Mesh Renderer设置一下
这样就看不到方块的外形了
而且仍然可以显示
将PlayerBot设置一下
最后由于Player的刚体没有设置触发器,所以这些cube,
要设置成触发器,取消碰撞。
测试
【bug修复】从上图可以看到,机器人是悬空的,离地面有一定的距离,这样的结果就是机器人的炮台有可能高于自己,从而开炮打不到自己,原因在于在烘培路线时,是在cube的表面烘培的,而cube本身就有一定的高度,虽然最后可以将cube隐藏,但是路线就是悬空的了,所以这些机器人也就是悬空了,处理方法就是将这些cube的高度y设置成0.1即可。