本篇文章对应 Nowpaper 老师在B站发布的视频《 如何在3D场景中实现炫酷传送门,和简单的小地图功能,RenderTexture技术应用》!

B站链接:https://www.bilibili.com/video/BV1K3411m7Ma

Cocos论坛:https://forum.cocos.org/t/topic/121977

RenderTexture技术

RenderTexture是游戏引擎的重要技术之一,它的原理是渲染摄像机的画面成为一个纹理,进阶的应用就是附着到材质上,变成对应的功能。

比如:

  • 俯视小地图

  • 屏幕上分屏显示视角

  • 能够看到目的地情景的传送门

  • 狙击枪瞄准镜里的画面

  • 引擎中的摄像机的预览

  • 引擎中画布UI

只不过目标可能是模型也可能是一个平面的精灵,依据不同的需求达到不同的目的。

在 Creator 3 中

游戏开发工具和引擎 CocosCreator 3.x 版本以后,提供了完整的3D世界开发功能,使得我们能够完成前面提到的功能,今天我将简单来展示,在 Cocos Creator 中如何使用RenderToTexture实现小地图和炫酷的传送门。

小地图

首先我准备了一个测试场景,方便展示成果,这个测试场景是我自己随便搭建的,这个还是有很多的问题,就不单独提供了,先来实现小地图,小地图的实现比较简单,几乎不用写代码。

论坛上的其他小地图做法都是直接移动控制第二摄像机的画面来实现,本文使用Sprite精灵来接受和显示渲染纹理,能够更好的定制你的UI画面,具体做法如下:

  1. 先建立一个UI Canvas,这个UI中放置一个Sprite精灵,调整到你想要的位置。

  2. 然后建立一个摄像机,摄像机向下照射,设置好位置和旋转参数,调整到你想要的观看位置和角度。

  3. 然后在资产里,建立一个Render Texture的资产,简单设置一下参数,主要要将资产的Width和Height设置成为小地图同等比例的大小,否则它将显示不出来。

  4. 选择摄像机,把摄像机的RenderTexture的目标,指向到这个资产。

  5. 然后选择之前的精灵,将这个Render Texture的资产赋给它的SpriteFrame的属性。

保存运行看看,就可以达到渲染效果。但是现在我们发现,移动并不会跟着人物走。

所以要给摄像机简单建立一个 TopCamareFollow 的脚本,在脚本的 Update 里面,不停的为它设置和角色一样的x、z的位置信息。

在这个脚本中添加一个目标指向,在 update 中添加如下代码,除了y以外的所有轴坐标,都和目标同步更新,代码如下:

import { _decorator, Component, Node } from 'cc';
const { ccclass, property } = _decorator;@ccclass('TopCameraFollow')
export class TopCameraFollow extends Component {@property(Node)target:Node = null;start () {}update (deltaTime: number) {this.node.setWorldPosition(this.target.worldPosition.x,this.node.worldPosition.y,this.target.worldPosition.z)}
}

将它添加到摄像机中,并将主角作为跟随目标,现在摄像机就可以跟着人物行动了。

在摄像机和 RenderTexture 资产里,有很多有趣的参数,可以各种尝试。

比如:你不喜欢带有透视效果的小地图,也可以将摄像机的拍摄参数设置成为正交,变成无透视的效果,其实很多俯视游戏,都是用这种方法实现。

传送门

也许著名游戏《传送门》曾经震撼于你,也许任意门是你儿时的梦想,现在我们通过简单的开发,让你的游戏里拥有一个。

在目标点设立一个摄像机,比如在遥远的地方有个小岛,记住这是同一个场景。

创建一个摄像机,调整到你想拍摄的的位置。

然后我们为它制作一个脚本,就叫传送门观察者吧!

在代码里定一个目标指向,用来指向将渲染的画面投射到什么物体,然后在start里写下下面的代码。

所以你需要稍微更新一下,然后将需要投射的材质设置和应用到的目标模型上,我的代码就是这样的。

import { _decorator, Component, Node, MeshRenderer, Camera, RenderTexture, Material } from 'cc';
const { ccclass, property } = _decorator;@ccclass('GateWayCamera')
export class GateWayCamera extends Component {@property(MeshRenderer)target:MeshRenderer = null;start () {const renderTex = new RenderTexture();renderTex.reset({width: 256,height: 256});const cameraComp = this.getComponent(Camera);cameraComp.targetTexture = renderTex;const pass = this.target.material.passes[0];const defines = { SAMPLE_FROM_RT: true, ...pass.defines };const renderMat = new Material();renderMat.initialize({effectAsset: this.target.material.effectAsset,defines,});this.target.setMaterial(renderMat, 0);renderMat.setProperty('mainTexture', renderTex, 0);}}

回到Creator中,在你想要的位置上做一个模型,什么形状都行,取决于你的传送门到底是什么形式的。

然后我们需要为它换一个材质,用来接收RenderTexture 。

新建一个材质,然后将 Sample From Rt 选项选上,并开启漫反射贴图(Use Albedo Map),保存设置。

将这个材质应用到传送门的展示的模型上,替换掉默认第一个0索引的材质。

为传送门摄像机添加刚刚写的脚本,并且将目标Target的属性将刚刚建立的模型引用。

运行,控制角色来看看!可以发现,目标的画面已经投射到了这个模型上,如果角度有点问题,说明模型坐标不太对,做一下调整旋转即可。

在这个模型上就渲染出了目标摄像机的画面,但是它目前只是一个固定的摄像机,从不同的角度来观察似乎太呆板了。

它应该跟着主角在移动的时候,会相对着你的主摄像机一同同步,为了实现这个功能我们得写个同步脚本了,先创建一个脚本就叫 GateWayCameraSync 代码如下:

import { _decorator, Component, Node, Vec3, v3 } from 'cc';
const { ccclass, property } = _decorator;@ccclass('GateWayCameraSync')
export class GateWayCameraSync extends Component {@property(Node)target:Node = null;private offset:Vec3 = null;private vec3:Vec3 = v3();start () {this.offset = this.node.worldPosition.clone().subtract(this.target.position);}update (deltaTime: number) {if(this.target){Vec3.add(this.vec3,this.target.worldPosition,this.offset);this.node.setWorldPosition(this.vec3);this.node.setWorldRotation(this.target.worldRotation);}}
}

在最开始,它需要计算出和主摄像机的差值, 通过target属性引用到目标摄像机。

在脚本运行的开始,通过向量的减法,得到相对于目标的世界坐标的偏移量,然后在update中不停的作同步。

现在返回到Creator,为摄像机挂上这个脚本。将主摄像机添加引用,为了更自然,你需要将摄像机稍微调整一下位置,因为初始位置和传送门其实并不是非常合适的。

真正的传送

传送门的效果肯定是传送,所以我们还得完成传送操作。为了达成这个能力,我们将会用上触发器。

选中传送门的模型,为它添加一个碰撞体,把作为触发器的选项勾上,由于它不是物理物件,所以不需要添加物理实体。

然后添加一个脚本,叫做触发传送,用来将触发碰撞后,将自己给瞬移到目标点,代码如下:

import { _decorator, Component, Node, Collider } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('TriggerTransfer')
export class TriggerTransfer extends Component {@property(Node)target:Node = null;start () {const c = this.getComponent(Collider);c.on('onTriggerEnter',this.onTriggerEnter,this);}private onTriggerEnter(){this.node.setWorldPosition(this.target.worldPosition);}
}

上面的代码中,使用了一个目标的引用来快速瞬移到它的坐标点。

其实手动输入一个坐标也可以的,但是有个节点物体作参照,显得更直观一点。

先在 Start 的时候开始监听触发事件,触发器事件触发的时候,将自己的位置 position 直接设置成为目标 position 属性,就达到了瞬移效果。

在回到 Creator 将脚本添加到主角身上,找到引用的物体,我就简单点,直接将目标点设置到了传送门摄像机身上。

现在看看效果,当主角碰到传送门物体的时候,触发了碰撞事件,从而将自己传送到了目标点。

优化

画面看起来也不怎么清晰,这个可以通过修改渲染图的大小来解决。

const renderTex = new RenderTexture();
renderTex.reset({width: 512,height: 512
});

传送门里的画面有点黑,看起来非常不和谐,解决方法是直接增加传送门摄像机的曝光度,调两个档次就可以了。

正反问题,其实传送门在正反前后看到的内容应该一致,但是由于我们采用了摄像机完全同步,所以在后面看就比较诡异。

这个部分如果想修改,则需要作一些数学上的计算,在这里就不实现了,你只需要将传送门的目标位置,作一下反转判定就可以。

特效

这光秃秃的传送门肯定不如有特效的加持显得高级,后面我们用一下粒子系统,完成制作炫酷的效果。

先准备一个图像,弄一个有透明的光圈,

你可以依据自己的需求做调整,把贴图放到工程里,最开始新建一个粒子用的材质,因为自从Creator 3以后的版本,图片纹理不能直接应用到粒子上,需要一个材质承接贴图,打开漫反射贴图,把前面导入的光圈纹理放上去,点击‘同意’应用。

在场景中新建一个粒子系统,然后去掉发射模块,调整一下大小、位置参数,并将粒子材质做一下修改,替换成我们刚刚新建的那个,然后把渲染模式改成了模型,选择面片作为基本模型。

这里有个3.3版本的小bug,你会发现之前引用的材质不见了, 不用担心,它只是没显示出来。

由于方向问题,还需要修改一些基础的参数以及大小让它正好套住传送门的模型,具体还得看你的传送门大小跟朝向。

粒子系统上勾选上旋转模块,将旋转z轴的角度设置成为-180,完成,现在基本上就能看到一个整体效果了

如果你想整更多的活,比如加上其他喷射也未尝不可,剩下的就是各自发挥了,希望各位能够在其中发现更多的有趣的应用。

结语

Creator 3.x 以后的版本有了更完善的 3D 游戏引擎的特性,使得很多有趣的玩法得以发挥!我们可以看到从 3.0 到 3.3 官方做了大量优化改进,相信以后会越来越好。

我是 Nowpaper 混迹游戏行业的一个老爸!

本期教程Demo源码还在整理中,请大家关注我的B站动态或论坛帖。

如果你喜欢这期教程,请考虑一键三联加关注,这是我做更多视频的动力,一爸作游戏越来越有戏,咱们下次再见!

B站频道:
https://space.bilibili.com/38487134
Cocos论坛帖:
https://forum.cocos.org/t/topic/121977

RenderTexture实现小地图和炫酷的传送门!(干货收藏)相关推荐

  1. 炫酷传送门HTML5动画js特效

    下载地址 基于Three.js的HTML5 3D动画,这个动画模拟了游戏中的一个炫酷的3D场景,支持360度视角查看,也支持鼠标滚轮进行缩放.画面中主要展现了一个游戏中传送门的效果,同时还有路两边的围 ...

  2. 【炫酷秀】仅用4行代码再现《黑客帝国》数字雨,可立即在终端实现!

    关注上方"深度学习技术前沿",选择"星标公众号", 资源干货,第一时间送达! 提到<黑客帝国>,字符雨可谓是让人印象深刻. 这种科技感爆棚的特效,你 ...

  3. 牛客寒假5-D.炫酷路途

    链接:https://ac.nowcoder.com/acm/contest/331/D 题意: 小希现在要从寝室赶到机房,路途可以按距离分为N段,第i个和i+1个是直接相连的,只需要一秒钟就可以相互 ...

  4. IDEA的一些炫酷的插件

    最近项目比较忙,很久没有更新IDEA系列了,今天介绍一下IDEA的一些炫酷的插件,IDEA强大的插件库,不仅能给我们带来一些开发的便捷,还能体现我们的与众不同. 打开setting文件选择Plugin ...

  5. C# Winform自定义控件资源汇总(炫酷界面的零件)

    最近在用C#Winform做一个关于GNSS作业仿真的软件,这次界面想做的和别人写的WPF一样炫酷些,然而自定义控件太麻烦,于是就到网络搜索轮子哥造好的轮子,随着编程世界的开源化和中国程序员的崛起,有 ...

  6. 安卓炫酷的抽屉菜单——JPSpringMenu

    一个炫酷的抽屉菜单--JPSpringMenu GitHub地址:传送门 看到这个,本来想搜搜它的穿件方式,就是应用,结果查找了一番,都是github的那一点解释 看到这,决定还是自己动手一番吧 具体 ...

  7. Android探索之旅(第十四篇)Android中实现炫酷效果的Demo(持续收录中......)

    RangeSeekBar Android简单实现订单模块类APP的物流详情页 Android开发中阴影效果的实现 Android 炫酷多重水波纹 MultiWaveHeader 利用Spannable ...

  8. 2021CodePen炫酷无比的作品

    说到 CodePen,前端开发者们肯定不会陌生.如果说 Dribbble 是设计师们聚集的圣地,那么 CodePen 则是前端开发者们约"码"的天堂.它不仅提供给你了一个 Show ...

  9. android炫酷的自定义view,Android自定义View实现炫酷进度条

    本文实例为大家分享了Android实现炫酷进度条的具体代码,供大家参考,具体内容如下 下面我们来实现如下效果: 第一步:创建attrs文件夹,自定义属性: 第二步:自定义View: /** * Cre ...

最新文章

  1. 有无目标的人生差10倍!赶紧和娃把新年计划做起来
  2. 最全ACM常用STL
  3. mysql int 转 varchar_Java后端程序员必备:MySQL索引失效的十大杂症
  4. VM两个虚拟机之间的通讯测试
  5. Redis--blpop命令使用
  6. Abbott's Revenge UVA - 816(BFS典型例题)
  7. php处理头像,(头像处理)PHP把图片转换成圆形png
  8. 有道换域名,目标中立、客观、包容
  9. 基因编辑最新研究成果进展(2021年11月)
  10. gorm 记录sql日志 每天一个日志文件
  11. 联烯基甲醇氧化合成联烯基羧酸化合物-齐岳研究
  12. python制作图表(爬取数据之后分析最后制成图表)
  13. 搭建智能DNS---就近原则
  14. 除了菊纹识别,AI还有哪些奇奇怪怪的识别能力?
  15. SSD-Tensorflow 512x512 训练配置
  16. 团队使我成长,学习使我快乐
  17. 解决mysql导出Excel中文乱码问题
  18. vscode是什么,如何安装vscode
  19. 建设企业的数据化引擎,网易严选数据中台的经验和方法论
  20. 腾讯10年测试老鸟分享:转行穷三年?那是你准备没做好吧···

热门文章

  1. linux apt 更新软件,apt get 更新软件
  2. 5G千兆智能网关的车联网应用
  3. java热敏POS打印机编程
  4. netDxf实现对cad文件的读取与写入
  5. 马帅:我的同事王开源-真正开源斗士
  6. netstat -ano|findstr
  7. c语言求解一元三次方程(二分法和公式法)
  8. JavaScript 中的事件类型4(读书笔记思维导图)
  9. 在移动硬盘中,安装CentOS 7双系统
  10. IMX6UL系列小屏驱动之像素时钟无法修改