• 跟我一起用unity做小地图!


    lol的小地图

    lol的小地图

    转载爬虫请自重,未问先转没排面

    不爱多做铺垫,小地图对于一些游戏来说多重要大家都懂,不然你也不会来看我这篇文章的,对不对?

    话不多说,开搞!

    一、主体功能

    一般来说,游戏里的迷你地图都是平面的。但是,默认的摄像机模式,即perspective(透视),是得不到这样的效果的。那怎么办?使用orthographic(正交)模式就好啦。

    修改后,控制视野的参数由Field of View变成了Size

    选择性显示

    如果把游戏中的所有东西都在小地图上渲染一遍,难免显得杂乱,失去了小地图的简明扼要这个特点。那怎么办呢?

    可以选择使用Layer(图层)来实现选择性显示。即给需要显示的物体加上特定的图层,这样的话,就可以在小地图里只显示具有指定图层的物体啦。

    最简单的做法,给要显示的物体加上图层showInMiniMap,只在迷你地图中渲染这些物体就可以了。但是呢,我不会这么做的...因为我衡量了一下,其实大部分物体都是要渲染的,所以...你懂得,我们给无需渲染的物体加上图层hideInMiniMap,然后过滤掉他们就好了!

    这个 showInMiniMap后面还有用处。

    引申:给NPC加上特定标记

    举一反三是一个很好的习惯,相信有些机智的小伙伴已经能想到了。如果给特定的NPC加上特定的图层,是不是就可以在地图上显示不同的标记呢?

    比如:

    • 敌人:红色点点
    • 自己:绿色长三角(三角尖指向当前朝向)
    • 商店老板:金袋icon
    • 装备升级:剑盾icon

    一种很简单的做法,就是给这些物体加上相应的icon模型,位置就和本物体重合,然后将icon模型设置为showInMiniMap,然后在主摄像机里剔除,让他们不会出现在视野里。然后给本来模型,加上hideInMiniMap图层,这样他们就不会出现在小地图了。

    如此一来就实现了游戏视图里看到的是模型,而小地图里看到的是icon了。

    二、进阶功能

    给小地图加个圆框

    让小地图和主角一起转动

    transform.rotation = Quaternion.Euler(
        new Vector3(
            transform.rotation.eulerAngles.x,
            playerTransform.rotation.eulerAngles.y,
            transform.rotation.eulerAngles.z
        )
    );
    

    加上指南针

    有些人,看到小地图,就想到圆;看到圆,就想起转动;看到转动,就想起指南针。 —— 鲁迅

    没错,接下来我们就做指南针。

    让指南针更逼真

    现实中的指南针并不会一瞬间指向南的,而是有个慢慢晃动校准的过程,我们也可以做出这样的效果来!

    compass.rotation = Quaternion.Lerp (
        compass.rotation,
        Quaternion.Euler (0, 0, playerTransform.rotation.eulerAngles.y+compassOrientationOffset),
        Time.deltaTime * compassRotationSpeed
    );
    

    Quaternion.Lerp 是个非常棒的函数, 处理旋转问题呱呱叫!比如说,120度转到-120度,我们无需自己判断是顺时针转动240度,还是逆时针转动120度,这个函数会自动帮您选择最小的度数(120度)转过去。

    三、完善功能

    为啥是先讲进阶,后讲完善呢?

    处理小地图灯光

    如果你的游戏世界里存在白天黑夜循环,比如dota2,你又不希望你的小地图黑夜比白天黑很多,顶多视野变得狭隘点。那么就需要给小地图设置另一套灯光渲染。

    void OnPreCull (){
        foreach(Light l in minimapLightsNotVisible)
            l.enabled = false;
        foreach(Light l in minimapLightsNoShadows)
            l.shadows = LightShadows.None;
        foreach(Light l in minimapLightsVisible)
            l.enabled = true;
    }
    
    void OnPostRender(){
        foreach(Light l in minimapLightsNotVisible)
            l.enabled = true;
        foreach(Light l in minimapLightsNoShadows)
            l.shadows = LightShadows.Soft;
        foreach(Light l in minimapLightsVisible)
            l.enabled = false;
    }
    

    处理在屋子里情况

    这里应该要分好几种情况,先说两种:

    • 低矮的屋子
    • 高楼

    首先,我们进了矮屋子咋办,因为小地图是头顶的摄像机渲染的,所以摄像机会被屋顶挡住。我在小地图里只能看到一个屋顶。这个根据业务需要,解决方法如下:

    • 你可以选择进入某个屋子后,就不渲染这个屋子的屋顶了(需要在代码中做相应的控制),这貌似是很多生存类游戏的解决方案。
    • 也可以选择就是要显示屋顶,都进了屋子里,这个屋子就是个地标,还要啥小地图?

    我们这里先提供第一种解决方案的实现。

    然后我进了一个高楼咋办?如果我停在1楼,因为摄像机高度是有限的,它很可能停留在3楼或者4楼,那就很诡异了,我在1楼某个屋子走来走去,摄像机却显示了3楼空无一人的场景。这显然是无法接受的。

    进入地下城

    下面就是个特殊例子了,进入地下城或者蜿蜒曲折的山洞咋办?

    众所周知,地下城都是带“盖子”的,天生带屋顶,如果你还是把摄像机放在天空,就有点像进入高楼那种情况了,诡异。而且地下城里高高低低,上上下下,摄像机卡在隔壁房间,甚至卡在你根本没设计的墙外世界,看到外面诡异的天空盒子,这就很像某部科幻电影里的场景了...这是完全无法接受的!

    怎么办呢?碰撞检测吧!从摄像机发射一根射线到人物,如果中间碰撞了设定为墙壁图层的物体,就是穿墙了,这时候就把摄像机前移到碰撞点前面一些的位置,这样就不会有问题了。

    下面我们开始实现。

    结语

    其实小地图上可以玩的花样肯定还有很多,这些就等各位大佬慢慢挖掘,自己实现啦。也欢迎大家不吝分享自己的经验,一起进步~

    本博客文章版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    Shell 批量搜索关键词并保存结果到文件中(数组、循环)
    解决tensorflow的Session Exception问题
    解决h5py的FutureWarning问题
    【转】Ubuntu16.04安装WPS
    [Linux] 随机切分文件内容
    [Python] 动态函数调用(通过函数名)
    [Python] dict字典的浅复制与深复制
    基于sklearn进行文本向量化
    Asp.Net MVC SingleServiceResolver类剖析
    Asp.Net MVC 高级特性(附带源码剖析)
  • 原文地址:https://www.cnblogs.com/laolieren/p/make_minimap_with_unity.html
Copyright © 2020-2023  润新知