Unity实战 RTS3D即时战略游戏开发(六) Navigation Mesh 自动寻路

 大家好,我是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  或者关注我的公众号:

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值