在传送门中,核心的玩法是在地上或者墙上打开2个能够联通的洞来实现传送的效果。以此扩展加入解谜要素构成游戏的核心。php
这里尝试使用unity来实现传送门的核心功能,具体功能分析以下:html
一、传送门的模型git
二、传送门的贴图app
三、传送门的传送功能ide
这里咱们须要如下软件:3dmax 2014,unity3d 5.4.0,visual studio 2015测试
打开3dmax,确认系统单位和显示单位都为米,若是不为米,改为米spa
创建一个圆柱体,高度段数1,端面分段1,边数32,调整到适当大小,转化为可编辑多边形,删除除了顶部面以外的全部面,位置归0。再次转化为可编辑多边形。.net
使用uvw展开命令,进行uv展开3d
更改模型的名称和材质的名称,导出fbx文件code
打开unity,导入模型,导入一个适当的场景包做为测试场景,建立一个能够用键盘控制的Player,用于场景游历和功能测试
建立一个新的摄像机,放在其余位置,做为传送的目标点。建立一个RenderTexture,拖拽到摄像机的Target Texture上。将摄像机的Clear flag改成solid color。适当更改相机的Viewport Rect。
将导入的传送门模型拖拽到场景中,放置在一面墙上,设置模型材质的贴图为RenderTexture。
能够看到效果以下
传送门的效果相似与一个洞,在不一样的位置看过去,显示的大小和物件都是有差异的。就相似你经过一个窗户看外面的世界相似。因此,咱们要根据玩家的摄像机相对与传送门的相对位置关系,来设置目标点摄像机的相关数据,好比,视角,位置,选择和裁剪等。
注意Atan在unity中为弧度,须要再乘上Mathf.Rad2Deg转成角度
部分代码以下(这里利用父子关系实现位置变化,目标摄像机为传送点的子物体,因此目标摄像机的localposition也就是相对于传送点的相对距离)
internal protected void Update() { var cpos = Camera.main.transform.position; var mt = Render.worldToLocalMatrix; mt = Matrix4x4.TRS(Vector3.zero, Quaternion.AngleAxis(180, Vector3.up), Vector3.one) * mt; Camera.transform.localPosition = mt.MultiplyPoint(cpos); Camera.transform.LookAt(Point); Camera.nearClipPlane = -Camera.transform.localPosition.z; const float renderHeight = 3f; Camera.fieldOfView = 2 * Mathf.Atan(renderHeight / 2 / Camera.nearClipPlane) * Mathf.Rad2Deg; }
在传送门上增长一个collider,设置为Trigger,当玩家与之发生碰撞的时候设置玩家的位置数据
部分代码以下
internal protected void OnTriggerEnter(Collider other) { other.transform.root.rotation = other.transform.root.rotation * Point.rotation * Render.rotation; other.transform.root.position = Point.position; }
本项目总体难度不大,大约花费时间2天
目前项目已经开源,地址为http://git.oschina.net/CodeGize/PortalGame,能够前往下载