zoukankan      html  css  js  c++  java
  • unity传送门类似效果实现

    简述

    在传送门中,核心的玩法是在地上或者墙上打开2个可以联通的洞来实现传送的效果。以此扩展加入解谜要素构成游戏的核心。

    这里尝试使用unity来实现传送门的核心功能,具体功能分析如下:

    1、传送门的模型

    2、传送门的贴图

    3、传送门的传送功能

    这里我们需要以下软件:3dmax 2014,unity3d 5.4.0,visual studio 2015

    一、传送门的模型和uv

           打开3dmax,确认系统单位和显示单位都为米,如果不为米,改成米

    image

            建立一个圆柱体,高度段数1,端面分段1,边数32,调整到适当大小,转化为可编辑多边形,删除除了顶部面之外的所有面,位置归0。再次转化为可编辑多边形。

    image

            使用uvw展开命令,进行uv展开

    image

            更改模型的名称和材质的名称,导出fbx文件

    image

    二、传送门的动态贴图

    1、静态效果实现

            打开unity,导入模型,导入一个适当的场景包作为测试场景,创建一个可以用键盘控制的Player,用于场景游历和功能测试

    image

    image

            创建一个新的摄像机,放在其他位置,作为传送的目标点。创建一个RenderTexture,拖拽到摄像机的Target Texture上。将摄像机的Clear flag改为solid color。适当更改相机的Viewport Rect。

            将导入的传送门模型拖拽到场景中,放置在一面墙上,设置模型材质的贴图为RenderTexture。

            可以看到效果如下

    image

    2、动态效果实现

            传送门的效果类似与一个洞,在不同的位置看过去,显示的大小和物件都是有差别的。就类似你通过一个窗户看外面的世界类似。所以,我们要根据玩家的摄像机相对与传送门的相对位置关系,来设置目标点摄像机的相关数据,比如,视角,位置,选择和裁剪等。

    • 目标摄像机和传送点的距离=玩家和传送门的距离
    • 目标摄像机的裁剪距离=目标摄像机和传送点的距离
    • 目标摄像机始终朝向传送点
    • 目标摄像机的视角=2*Atan(传送门高度/2/目标摄像机和传送点的距离)

            注意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,可以前往下载

            演示地址:http://v.youku.com/v_show/id_XMTY5MzE3MzU0MA==.html

    个人博客请访问:http://www.cnblogs.com/CodeGize/
  • 相关阅读:
    代码空间项目 -- InstantiationException的异常
    代码空间项目 -- 窗口移动
    代码空间项目 -- alert窗口自定义
    代码空间项目 -- 获取当前时间之前的某一天-Calender类的使用
    代码空间项目 -- cookie的基本使用
    Hibernate主要查询方式
    关于hibernate配置步骤
    线程创建后为什么要调用CloseHandle
    C++子类父类构造函数的关系
    socket API CSocket CAsyncSocket 用法及区别
  • 原文地址:https://www.cnblogs.com/CodeGize/p/5792211.html
Copyright © 2011-2022 走看看