Unity寻路系统跟摄像机实战

这两天研究了一下unity的寻路系统跟摄像机的一些东西

在游戏中,我们经常会用到寻路这个功能,以前的做法多数是使用A*算法

而unity中自己带有了一套寻路系统供我们使用,关于这个这个用法,我们可以从《unity 4.x从入门到精通》的第九章了解到如何生成一个寻路网格

本文重点是展示这个寻路系统的使用效果,结合《unity 4.x从入门到精通》上摄像机相关的知识(185-189页),来做一个人物寻路,然后小地图显示场景效果

本文unity版本为4.6版本,用到的技术要点如下:

1.unity自带的寻路系统

2.理解鼠标点击2D屏幕,用射线方式映射到世界3D坐标,确定移动的目标点

3.摄像机画中画技术

4.摄像机跟随物体技术

5.UGUI的使用


好,现在我来一步步讲解我的制作过程

首先我们创建一个空的GameObject,用于装载地面,阻碍物,模拟人物等物体,

接着我们创建一个plane作为我们的地面,修改他的scale为10,1,10

然后我们创建一个sphere做作为我们的模拟人物,创建后,添加Nav Mesh Agent控件

创建三个cube作为我们的阻碍物,这三个cube需要设置为static,不然生成寻路网格的时候会无效

加一个平行光照到我们的plane上

创建一个点灯源,稍后作为我们鼠标点击位置的示意用

场景效果如下图所示

生成寻路网格点击Window->Navigation,在Object那里选择All后,直接点击Bake按钮生成就可以

生成后,会在你存放场景的目录下有一个跟场景名一样的文件夹,里面放着网格信息的



接着,我们用UGUI来建一个UI,它的右上角显示小地图的

直接点击GameObject->UI->RawImage来建立一个UGUI的UI系统,然后调整RawImage的大小为128X128

然后我们新建一个摄像机,命名为textureCamera

新建UGUI的Canvas下的Render Mode选Screen space overlay就可以了,意思就是覆盖在屏幕之上

为何我们要用RawImage,因为我们注意到,摄像机有一个叫做targetImage的成员参数,这个参数是用于存储摄像机映射场景画面到这个targetImage上去的

这个参数初始值为空,需要我们自己建立一个RenderTexture对象去传给它,设置了这个参数之后,这个摄像机的画面就不会自动合并到我们的屏幕上去了

需要我们用脚本控制显示这个targetImage才能看到这个摄像机原本看见的画面

我们就用此原理来达到制作小地图的效果

整个场景对象结构图如下


下面贴一下用到的脚本

1.角色控制脚本,主要接受鼠标点击,然后转换到世界坐标上去,然后通知人物走到那个位置

using UnityEngine;
using System.Collections;

public class PlayerController : MonoBehaviour {
    private NavMeshAgent man;
    public Transform pointLightPos;

	// Use this for initialization
	void Start () {
        man = GetComponent<NavMeshAgent>();
        if (null == pointLightPos)
        {
            pointLightPos = GameObject.Find("Point light").transform;
        }
	}
	
	// Update is called once per frame
	void Update () {
        //man.SetDestination(targetPos.position);
        //按下了鼠标左键,就发出射线
        if (Input.GetMouseButtonDown(0))
        {
            //调用射线函数检测
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                //检测到碰撞就设置点光灯的位置
                pointLightPos.position = new Vector3(hit.point.x,transform.position.y,hit.point.z);
                man.SetDestination(hit.point);
            }
        }
	}

}
把上面的playercontroller.cs绑定到player的物体对象上去,并拉点灯源到那个pointLisht去

另外这里说一下,我发现这个鼠标点击映射到世界坐标中主要是按Main Camera的坐标去映射的,其他的Camera要通过写特殊脚本的方式去映射

大家可以试试,这里mark一下


2.地图摄像机中的targertTexture替换脚本

using UnityEngine;
using System.Collections;

public class CameraController : MonoBehaviour {

    private RenderTexture renderTexture;
    Camera textureCamera;

	// Use this for initialization
	void Start () {
        //创建一个临时的RenderTexture,给摄像机的targetTexture存储摄像机画面用
        renderTexture = RenderTexture.GetTemporary(128, 128, 24, RenderTextureFormat.ARGB32);
        renderTexture.isPowerOfTwo = false;
        renderTexture.useMipMap = false;
        //获取摄像机组件,然后设置targertTexture
        textureCamera = GetComponent<Camera>();
        textureCamera.targetTexture = renderTexture;
	}
	
	// Update is called once per frame
	void Update () {
	
	}
}

把这个脚本绑定到textureCamera上去


3.UGUI上显示小地图的控制脚本

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class ShowImage : MonoBehaviour {

    private RawImage rawImage;
    public Camera textureCamera = null;

	// Use this for initialization
	void Start () {
        rawImage = GetComponent<RawImage>();
        if (null == textureCamera)
        {
            textureCamera = GameObject.FindGameObjectWithTag("texturecamera").GetComponent<Camera>();
        }
	}
	
	// Update is called once per frame
	void Update () {
        //直接使用摄像机的targetTexture替换
        rawImage.texture = textureCamera.targetTexture;
	}
}
把这个脚本绑定在UGUI中的RawImage中区

4.主摄像机设置跟随在人物后面,动态跟随

using UnityEngine;
using System.Collections;

public class CameraFollow : MonoBehaviour {

    public GameObject player;
    private Camera camera;

	// Use this for initialization
	void Start () {
        camera = GetComponent<Camera>();
	}
	
	// Update is called once per frame
	void Update () {
        //计算摄像机位置
        Vector3 newPos = player.transform.position + (-20.0f * player.transform.forward) + new Vector3(0.0f,20.0f,0.0f);
        transform.position = newPos;
        //设置摄像机的摄像方向为对着物品方向
        transform.rotation = Quaternion.LookRotation(player.transform.position - transform.position);
	}
}
把这个脚本绑定到Main Camera中区


好了最后看看我做的东西最后做到的效果


最后我上传一下这个项目的包,大家有需要可以下载来看一看,我是新手,有什么不足之处欢迎大家交流,下载地址为:

http://download.csdn.net/detail/a6627651/8617683


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值