【MonumentVally】纪念碑谷技术实现 您所在的位置:网站首页 纪念碑用什么看的词语 【MonumentVally】纪念碑谷技术实现

【MonumentVally】纪念碑谷技术实现

2023-08-24 11:22| 来源: 网络整理| 查看: 265

【MonumentVally】纪念碑谷技术实现 是什么

《纪念碑谷》(Monument Valley) 是一款由Ustwo独立游戏工作室在2014年开发和发行的解谜游戏。在游戏中,玩家引导主人公“公主”艾达在错视和不可能的几何物体构成的迷宫中行走,达到每个关卡的目的地。依靠强大的视觉错位设计获得2014年苹果设计奖,并获得苹果2014年最佳iPad游戏的提名。下面将针对游戏中如何实现视觉错位进行剖析。 在这里插入图片描述

怎么做 彭罗斯三角

下图是纪念碑谷官方透露出来的一个设计图纸,我们发现里面大量的使用了彭罗斯三角)的各种变种。

在这里插入图片描述

在这里插入图片描述

下面我们来看个最终实现的gif效果图

在这里插入图片描述

我们打开对应的Unity工程发现其实旋转的几何体实际上并不是像你看到的那样在一条直线上,是有一个视觉错位的。如下图所示

在这里插入图片描述

新建一个Slot.cs脚本

using UnityEngine; public class Slot : MonoBehaviour { public Cube cube; public Slot matched; void OnDrawGizmos() { if (matched == null) { Gizmos.color = Color.red; } else { Gizmos.color = Color.green; } Gizmos.matrix = transform.localToWorldMatrix; Gizmos.DrawCube (Vector3.zero, Vector3.one*0.1f); Gizmos.matrix = Matrix4x4.identity; } }

我们在Cube的四个方向上面绘制可以行走的点(绿色)和不可行走的点(红色),后面会根据这些点来控制艾达的移动路径。

在这里插入图片描述

新建一个Cube.cs脚本

using UnityEngine; public class Cube : MonoBehaviour { public Slot[] slots = new Slot[4]; void OnDrawGizmos() { Gizmos.matrix = transform.localToWorldMatrix; Gizmos.color = Color.green; Gizmos.DrawSphere (Vector3.zero, 0.2f); Gizmos.matrix = Matrix4x4.identity; foreach (var s in slots) { if (s.matched) { Gizmos.DrawLine (s.transform.position, transform.position); } } } }

可行走的两个绿点通过直线连接起来,目的是便于在Scene场景下观察。

原理

当点击屏幕的时候,算出玩家选中的是哪个Cube,然后计算玩家当前的位置和目标Target之间的方向,通过一定的速度及时设置玩家坐标即可。

Update函数为

void Update () { if (player.path != null) { float d = player.walkSpeed * Time.deltaTime; Cube targetCube = player.path.First.Value; Vector3 target = player.path.First.Value.transform.position; float dist = Vector3.Distance (player.transform.position, target); if (dist < d) { player.transform.position = target; player.path.RemoveFirst (); if (player.path.Count == 0) player.path = null; player.current = targetCube; player.gameObject.transform.SetParent (player.current.transform); } else { Vector3 dir = Vector3.Normalize( target - player.transform.position ); player.transform.position += dir * d; } } }

计算路径的代码如下

static LinkedList FindPath(Cube source, Cube dest) { if (source == dest) { return null; } var path = new LinkedList(); var nodes = new Dictionary(); nodes [source] = 0; var prev = new Dictionary (); var todo = new LinkedList(); todo.AddLast (source); bool found = false; while (todo.Count > 0) { Cube cur = todo.First.Value; todo.RemoveFirst (); int distance = nodes [cur] + 1; foreach (var s in cur.slots) { if (s.matched) { Cube other = s.matched.cube; if (!nodes.ContainsKey (other)) { nodes [other] = distance; todo.AddLast (other); prev [other] = cur; } if (other == dest) { found = true; break; } } } if (found) { break; } } if (!found) { return null; } string path_str = ""; Cube p = dest; while (p != source) { path_str += p.name + "


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有