跟我一起用unity做小地图!
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楼空无一人的场景。这显然是无法接受的。
进入地下城
下面就是个特殊例子了,进入地下城或者蜿蜒曲折的山洞咋办?
众所周知,地下城都是带“盖子”的,天生带屋顶,如果你还是把摄像机放在天空,就有点像进入高楼那种情况了,诡异。而且地下城里高高低低,上上下下,摄像机卡在隔壁房间,甚至卡在你根本没设计的墙外世界,看到外面诡异的天空盒子,这就很像某部科幻电影里的场景了...这是完全无法接受的!
怎么办呢?碰撞检测
吧!从摄像机发射一根射线到人物,如果中间碰撞了设定为墙壁图层的物体,就是穿墙了,这时候就把摄像机前移到碰撞点前面一些的位置,这样就不会有问题了。
下面我们开始实现。
结语
其实小地图上可以玩的花样肯定还有很多,这些就等各位大佬慢慢挖掘,自己实现啦。也欢迎大家不吝分享自己的经验,一起进步~