《纪念碑谷》是如何欺骗人们的视觉的?



本人研究生程序猿一枚,毕设做的Unity游戏设计,最近刚刚玩通了《纪念碑谷》,被这款完美的作品震撼了。由于了解到《纪念碑谷》是用Unity进行开发的,本着个人兴趣和对这个游戏的热情,我大致地了解了一下《纪念碑谷》的开发流程和技术实现,在这里和大家分享一下。

本回答将会大致解答《纪念碑谷》是如何在技术层面上实现这些不可能,从而让人们在视觉上获得完美的体验的(如何通过技术欺骗你们的视觉的)。资料来源是ustwo monument valley team的技术主管应Unity官方邀请对游戏开发者做的presentation

由于主讲人讲得比较概括(不愿透露过多技术细节),以下答案还会加入一些我个人的分析,如有错误有请大神们指正。

OK,废话说了好多,下面是干货。

个人总结:《纪念碑谷》其实就是通过将人们从2D平面看见的路径,在3D的游戏场景中加以实现。人们看见的效果其实只是3D游戏场景的一个投影(Projection)。

下面的内容我将配合图片进行讲解~多图预警!!

这个是presentation的主题:创造不可能!由于本答案侧重介绍技术原理,presentation中涉及测试,用户体验和关卡设计等不相关内容不予提及。
 


主讲人一上来就摆上了潘洛斯三角形,从别的角度看实物是一个奇形怪状的东西,可是如果从特定角度看过去,就变成了那个神奇的三角形~这就是monument valley team开发秉承的思想:See things in different angle!同时也是技术上实现的核心。
 


然后可以看到,在Unity的游戏场景(左图)里其实也是这么个奇怪的几何体!可是调好摄像机的角度(右图)效果就出来了
 


于是问题就来了。我们在玩游戏的时候看到的效果感觉艾达是在一条路上走的(右图中艾达可以从三角形最上面的角通过中间的角到达下方的角)。可是在二手游戏出售平台3D的场景中两条路(左图中根本木有中间的角)根本没有交汇,那艾达是怎么走过去的呢?

答案就是对路径进行标记,如下图


由图中我们可以看到,可供艾达行走的矩形路面都用Node进行了标记,Node由蓝色的Boundary Point和绿色的Connection Indicator。我个人认为游戏程序的寻路算法是基于Node组成的路径网络的,而通过对Connection Indicator进行处理,可以决定不同的Node之间是否相连。通过这种方法,技术人员可以轻松地根据视觉效果在3D场景中标出路径,下面是效果展示:
 


图中可以看见两个实际上分离的Connection Indicator,换个角度后就重合了。

有些同学会有这样的疑问:就算视觉上重合了,可是艾达的位置应该也有改变呀,远近不同会导致物体大小在视觉上的变化,可是怎么完全看不出来?

我来告诉你,其实艾达的位置并不是一直位于方块的上面,只是让你看着像而已...请看下图:
 


由图我们可以知道艾达的位置并不是单纯地在方块上面,而是针对用户的视角进行了偏移。可是这些在技术上怎么实现呢。我推测是通过Node来实现的,由于Node是一个圆心处于矩形单位正中心的球体,通过预先设定艾达通过特定Node时离圆心的距离,从特定的角度看就像在大路上行走一样。

我这么推测的原因是主讲人在presentation中明确表示艾达通过曲面的时候,是通过调整艾达和Node圆心的相对倾斜度来实现走曲线的效果的。
 


而且Node还决定了艾达通过它的时候采取什么动画,这就是他们实现爬梯子和走楼梯的动画的原理。当一个梯子同时可以当做地面(左图路径)或者梯子(右图路径)的时候他们还头疼了一阵,后来通过在这种功能重叠的地方放置多个Node,然后通过艾达的位置来决定具体哪一个Node有效。
 


由此可见艾达的行走是由基于标记的寻路系统决定的,用于标记的Node还储藏了特定的渲染方式。通过定义特定的位置,旋转角度以及动画,来保证艾达行走的真实效果。

以上为大概的原理!看起来貌似是比较简单,可是据说实际实现起来问题一大堆。

上面说了通过设置Connection Indicator可以标记哪些节点相互连接,可是实际玩得时候有些情况还需要对某些点进行闭塞,如下图
 


在这个图里,通过视觉我们可以发现当艾达位于左上角的时候,她是三个地方都可以去的,寻路算法必须通过人们的点击输入来选择性地闭塞掉一些Connection Indicator,如下图。
 


然后下面是NPC的路径图,直接上不同的Node,各走各路哈~
 


这些就是presentation关于纪念碑谷技术设计部分的全部内容啦。最后上一张完整关卡的实际效果与视觉效果对比图!
 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用Python中的turtle库绘制八一英雄纪念碑的代码和效果图: ```python import turtle # 设置画笔 t = turtle.Pen() t.pensize(5) t.speed(10) # 绘制底座 t.penup() t.goto(-200, -200) t.pendown() t.fillcolor("#BFBFBF") t.begin_fill() for i in range(2): t.forward(400) t.left(90) t.forward(100) t.left(90) t.end_fill() # 绘制主体 t.penup() t.goto(-150, -100) t.pendown() t.fillcolor("#FFD700") t.begin_fill() t.left(45) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) .right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) .right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right(135) t.forward(200) t.right(90) t.forward(200) t.right(135) t.forward(283) t.right

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值