大家好,我是Zander,我们接着来开发Rts3D即时战略游戏开发。上一章我们创建了鼠标管理控制器,接下来我们要为单位添加寻路功能。为了能让单位在地图上移动,我们需要知道在哪里点击了鼠标右键,首先要创建新的交互方式,在Interactions文件夹下创建一个RightClickNavigation脚本,暂时不添加方法,我们打开RtsManager脚本,为了能检测到在哪里点击了鼠标右键,首先我们需要知道地形的碰撞体,在RTSManager中添加如下:
public TerrainCollider MapCollider;
接下来我们还需要一个方法来确定点击了地图哪里,或者哪里都没有点
public Vector3? ScreenPointToMapPosition(Vector2 point) //带有? 表明它是可空类型,如果没有点击地面则返回Null
{
var ray = Camera.main.ScreenPointToRay (point);
RaycastHit hit;
if (!MapCollider.Raycast (ray, out hit, Mathf.Infinity))
return null;
return hit.point;
}
接下来,我们来修改一下RTSManager的Start方法,选中并操控敌军单位没有任何意义,但是可以选择查看他们的信息,确保不控制的有AI的单位没有Navigation脚本, 修改后如下:
// Use this for initialization
void Start () {
Current = this;
foreach (var p in Players) {
foreach (var u in p.StartingUnits)
{
var go = (GameObject)GameObject.Instantiate(u, p.Location.position, p.Location.rotation);
if (!p.IsAi)
{
go.AddComponent<RightClickNavigation>();
}
}
}
}
返回到 场景中的Manager中,发现RTSManager脚本中多出了一个叫MapCollider的新字段,将地形信息赋给它,如图:
这样就能够在地图哪里点击右键了,接下来我们要使主角移动了,选择预设DrontUint,为其添加Nav Mesh Agent组件,这个组件可以通过导航网格寻路并移动,添加完后,我们把它的初始值设置一下如图:
然后开始编辑RightClickNavigation脚本,如下:
using UnityEngine;
using System.Collections;
public class RightClickNavigation : Interaction {
/// <summary>
/// 在距目的地多远时准备停止移动,
/// 使用它的原因是当我们派遣多个单位到统一位置时,他们都会争取到达准确的位置,这不是我们想要,我们需要一个安全距离
/// </summary>
public float RelaxDistance = 5;
private NavMeshAgent agent;
private Vector3 target = Vector3.zero;//目的地的位置
private bool selected = false;//当玩家点击右键事是否要执行选中操作
private bool isActive = false; //NavMesh是否启用并控制单位移动
public override void Deselect ()
{
selected = false;
}
public override void Select ()
{
selected = true;
}
/// <summary>
/// 向目的地导航的方法
/// </summary>
public void SendToTarget()
{
agent.SetDestination (target);
agent.Resume (); //如果代理定下来了,设置的目的地也不会有作用,所以需要代理恢复移动
isActive = true;
}
// Use this for initialization
void Start () {
agent = GetComponent<NavMeshAgent> (); //获取当前的NavMeshAgent脚本
}
// Update is called once per frame
void Update () {
if (selected && Input.GetMouseButtonDown (1)) //点击右键并被选中
{
var tempTarget = RtsManager.Current.ScreenPointToMapPosition(Input.mousePosition);
if (tempTarget.HasValue) //我们可能再次点击选中的物体,并且选中的物体也可能为Null
{
target = tempTarget.Value;
SendToTarget();
}
}
if (isActive && Vector3.Distance (target, transform.position) < RelaxDistance)
{
agent.Stop ();
isActive = false;
}
}
}
好了,返回到Unity中,运行就可以发现选中后的单位可以自动寻路了
这章就到这了,欢迎大家加入QQ群:280993838 或者关注我的公众号: