unity开发之游戏视野剔除显示FieldOfViewRenderer
游戏视野剔除显示FieldOfViewRenderer
- 中文
- 简介
- 主要功能
- 图片预览
- 部分代码
- 图形绘制器 DrawHelper
- 基础扇形类
- 定义shader美观优化
- 使用步骤:
- 下载链接
- 更新:
- English
- FieldOfViewRenderer Description
- Download
中文
简介
游戏中的英雄,小怪等单位的视野显示.因为工作需求做了一个游戏中单位的视野剔除显示的功能,网上相关资源太少,有的可能也不是很适合,比如没有剔除,功能不完善,性能开销太大等,最后用自己的方式实现了策划需求.查了下网上貌似没有这样做的,想到很多游戏项目估计都有这些需求,现在贡献出来,还请斧正.
主要功能
- 通过配档显示敌人视野的范围.
- 有障碍物的地方视野会剔除渲染.
- 自定义shader,通过美术给定的图片采样渲染出不同透明度有渐变效果的纹理.
- 代码简洁易懂,扩展性高.数据类型接口丰富,(如:可通过给定颜色改变视野颜色,以起到显示状态作用.)
- 性能开销可调整,高质量的情况也不会开销太大.
- 提供其他可行方案,供选择对比.
图片预览
下载包体里有详细的说明和录制视频,这里贴出预览图
部分代码
Demo全部代码都在Scripts文件夹里.命名和注释都一目了然,建议下载后直接看源码,这里简单介绍下.
图形绘制器 DrawHelper
主要就是通过Unity封装的GL类库直接绘制相应图形
入口函数是OnPostRender,包含此函数的脚本挂摄像机上,就会被每帧调用.
在其他地方调用AddSector和RemoveSector达到添加移除所需要绘制的扇形视野
当绘制器检测到有图形需要绘制的时候 就绘制,
void OnPostRender(){if (allSectors.Count > 0)DrawTriangle(allSectors);//绘制其他图形}private void DrawTriangle(List<Sector> sectors){if (sectors.Count <= 0) return;GL.PushMatrix();mat.SetPass(0);//GL.LoadOrtho();GL.Begin(GL.TRIANGLES);foreach (var sector in sectors){sector.PushGLVertex();}GL.End();GL.PopMatrix();}/// <summary>/// 添加需要绘制扇形(视野)/// </summary>/// <param name="sector"></param>public void AddSector(Sector sector){if (allSectors.Contains(sector)) return;allSectors.Add(sector);}//正式项目中需要用到移除视野(如死亡的时候)public void RemoveSector(Sector sector){if (allSectors.Contains(sector))allSectors.Remove(sector);}
基础扇形类
基础扇形类,就是小怪英雄等单位视野显示的图形.
扇形由许多小三角形拼合而成,三角形由顶点决定,而我们需要把被障碍物挡住的定点剔除, 所以剔除顶点,计算顶点,重构三角形是关键.
绘制出的图形需要和游戏单位保持相对固定的位置关系,所以需要转换坐标系同步更新位置.
最后,显示的图形不能直接显示到单位的眼睛上,而是显示到脚下,所以需要做一个偏移,虽然视野剔除还是从眼睛哪里发起的.
public Transform origin;public float angleFov = 90; //视野角度public float R = 2f; //视野最远距离public float r = 0.3f;public int quality = 72; //越大质量越高(12的倍数)public float startAngle = 0;public Color color = Color.green; //视野颜色(可以通过改变颜色显示不同的状态,如看到敌人变红色)public Vector3[] vertices;/// <summary>/// 视野显示的高度/// </summary>public float offsetY = 0.2f;/// <summary>/// 将顶点等数据传送给GL/// </summary>public void PushGLVertex(){GL.Color(color);int verCount = 0;var vertices = this.RefreshVertices();if (null == vertices) return;int wholeCount = vertices.Length - vertices.Length % 3;if (0 == this.r)wholeCount = vertices.Length;//以下为舍进算法,可能会导致渲染出的FOV和配档差一点点for (int i = 0; i < wholeCount; i++){verCount++;vertice = vertices[i];GL.TexCoord2(GetUVx(vertice), 0.5f);GL.Vertex3(vertice.x, vertice.y, vertice.z);if (0 != this.r){if (verCount >= 3 && vertices.Length - i > 3){i = i - 2;verCount = 0;}}else{if (verCount >= 2){if (vertices.Length - i > 1){i--;}verCount = 0;GL.TexCoord2(GetUVx(this.origin.position), 0.5f);GL.Vertex3(this.origin.position.x, this.origin.position.y, this.origin.position.z);}}}}/// <summary>/// 更新扇形顶点数据/// </summary>/// <returns></returns>public Vector3[] RefreshVertices(){startAngle = origin.eulerAngles.y + angleFov / 2;float angleCurr = startAngle;offsetVec3 = new Vector3(origin.position.x, offsetY, origin.position.z);for (int i = 0; i <= quality; i++){Vector3 curVec = new Vector3();curVec.z = Mathf.Cos(Mathf.Deg2Rad * angleCurr);curVec.x = Mathf.Sin(Mathf.Deg2Rad * angleCurr);Vector3 posCurrMax;RaycastHit hit;//Debug.DrawRay(origin.position, curVec * R, Color.green,0.1f);//可以取消此行注释显示扫描射线//if (Physics.Raycast(origin.position, curVec * R, out hit, R, ~(int)Layers.Corpse))//可以过滤掉某些层if (Physics.Raycast(origin.position, curVec * R, out hit, R)){posCurrMax = curVec * Vector3.Distance(hit.point, origin.position) + offsetVec3;//Debug.DrawLine(origin.position,hit.point,Color.red,0.1f);}else{posCurrMax = curVec * R + offsetVec3;}Vector3 posCurrMin = curVec * r + offsetVec3;if (0 != r){vertices[2 * i] = posCurrMin;vertices[2 * i + 1] = posCurrMax;}else{vertices[i] = posCurrMax;}angleCurr -= angleDelta;}return vertices;}
定义shader美观优化
计划的功能都实现出来了,骚策划还不满足,需要再在视觉上优化下,要根据视野远近来个强弱渐变
自定义一个shader实现.
在计算扇形的时候需要抓取UV,以便shader里做渐变渲染.
//获取UVprivate float GetUVx(Vector3 vertex){return Mathf.Clamp01(Vector3.SqrMagnitude(vertex - origin.position) / (R * R));}// GL.TexCoord2(GetUVx(vertice), 0.5f);SubShader{Tags { "RenderType" = "Transparent" }LOD 100Pass{Blend SrcAlpha OneMinusSrcAlphaCull OffCGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;float4 color : COLOR;};struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;float4 color : TEXCOORD1;};float4 _FieldColor;sampler2D _AlphaTex;float4 _AlphaTex_ST;v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = v.uv;o.color = v.color;return o;}fixed4 frag (v2f i) : SV_Target{fixed4 col = _FieldColor;return fixed4(i.color.rgb, tex2D(_AlphaTex, i.uv).r);}ENDCG}}
使用步骤:
导入下载的包体,打开里面的Demo场景即可预览使用.打上合适的灯光会更好看.若存在问题或者需要修改请执行以下步骤.
1. 将在MainCamera上添加DrawHelper绘制器,并绑定材质FieldOfViewRenderer.
2. 在你的单位的眼睛或者虚拟点上添加Eye脚本(也可以在脚本里面添加一个eyeTrans的变量,这样脚本可以放在单位根节点,只需要初始化eyeTrans即可)
不明白可以看截图和视频
(之前在网上找到了一个通过摄像机剔除而渲染视野的方案,功能满足,但是开销太大,根本没法用到工程中(加入后20帧).于是采用GL底层直接渲染视野.此方案不需要创建mesh,并且所有的视野图形都一批渲染出来,不会像mesh渲染那样可能分批次.之所以不叫FieldOfVisionRenderer是为了和网上的某方案区分)
下载链接
https://download.csdn.net/download/qq_19646749/11033676
转载请注明出处 (*_^)
(若下载不了 请告诉我)
更新:
2019/03/18 加入了滑动框选功能 详情见FieldOfViewRenderer_andBoxSelect.unitypackage(Unity2018.3.5)
English
FieldOfViewRenderer Description
It is used for the enemy’s vision field in the game.
Main functions:
- Display the enemy’s range of vision.
- The vision field with obstacles won’t be rendered.
- Customize shader to render texture with gradient effect with different transparency by sampling images given by art staff.
- The code is simple and easy to understand, with high expansibility. (for example, the view color can be changed by a given color to display the state).
- It costs little even you set it to high quality. The performance cost can be adjusted.(It is better than some other’s solution.)
- Provide other suitable way for comparison and selection.
Use steps: Importing the package,openning the Demo scene,then you can preview it. If there are problems or need to modify, please perform the following steps.
- Drag the DrawHelper(script) into to the MainCamera and Drag the FieldOfViewRenderer(material) into the Mat.
- Add the Eye(script) to your unit’s eye or virtual point .
Update: I add BoxSelect-module in this project at 03/18/2019 . Inporting FieldOfViewRenderer_andBoxSelect.unitypackage to see detail.
Unity Version:2017.4.2f2 thank u very much !
Download
https://download.csdn.net/download/qq_19646749/11033676
Reprint please indicate the source
unity开发之游戏视野剔除显示FieldOfViewRenderer相关推荐
- 使用Unity开发RPG游戏完整指南(全)
使用Unity开发RPG游戏完整指南(全) - GameRes游资网 关注公众号 风色年代(itfantasycc) 200G Unity资料合集送上~ 本教程教大家如何使用Unity创建一个RPG游 ...
- 用Flash、HTML5和Unity开发网页游戏的现实
今天对于全球的Flash开发者来说是黑暗的一天,因为Adobe宣布将不再对移动设备上的浏览器进行Flash技术支持.在这之前,Adobe刚刚宣布了公司范围内的大幅度裁员.尽管这似乎并不是什么严重的问题 ...
- 游戏开发学习记录01-关于在Unity开发的游戏中部署后端云的选择
目前我还是一名在校学生,而且现在还没有学习数据库方面的知识,所以目前我不具备后端搭建服务器和数据库的知识.所以在之前学习安卓开发过程中,了解到了现在有一种服务-后端云,可以不用费时的去完成后端的开发, ...
- Flash、HTML和Unity开发网页游戏的现实比较
2011-11-21 这一天对于全球的flash开发者来说是一个黑暗的日子,因为Adobe宣布它将停止对移动浏览器上flash的支持.在此之前一天,Adobe刚刚宣布大规模裁员,这看起来似乎不是什么大 ...
- 实战分享1:如何使用华为VR Glass 6dof 基于 OpenXR@ unity 开发VR游戏/应用
目录 1 环境准备 2 使用OpenXR + XR Interaction Toolkit 2.1 工程准备 2.1.1 安装openxr相关插件 2.1.2 配置工程 2.1.3 Debugger ...
- unity 克隆_使用Unity开发Portal游戏克隆
unity 克隆 Learn game development principles by coding a Portal-like game using Unity and C#. The prin ...
- 【转】unity开发android游戏(一)搭建Unity安卓开发环境
http://blog.csdn.net/chenggong2dm/article/details/20654075 1,下载安装Java的JDK: http://www.oracle.com/tec ...
- unity开发android游戏(一)搭建Unity安卓开发环境
1,下载安装Java的JDK: http://www.oracle.com/technetwork/java/javase/downloads/index.html (JDK中,包含JRE) 如果是6 ...
- 细数那些年我们一起玩过的Unity3D游戏(unity开发的游戏有哪些)
经典重现<新仙剑OL> <新仙剑OL>采用跨平台Unity3D引擎,耗资数千万,历时三年多,由台湾大宇正版授权,"仙剑之父"姚壮宪监制的全球首款Unity3 ...
最新文章
- 《数字短片创作(修订版)》——第一部分 剧本创作 第1章 数字短片创意技法 剧本创作的构思...
- Ant简单工程的构建
- datagrid 的标题的内容不对应整齐
- 让安全威胁无所遁形,全方位掌握攻击“前世今生”的黑科技来了
- vue+layui获取CheckBox的值
- 体系结构方案 -ETL 中间件
- Go语言Web框架gwk介绍 (四)
- PaddleOCR文字识别使用
- CCF201509-1 数列分段(100分)
- python 3全栈开发-面向对象之绑定方法(classmethod与staticmethod的区别)、多态、封装的特性property...
- 动画算计算机专业吗,能够定义角色功能的计算机动画系统属于。 (1.0分)
- Mad Libs 游戏
- 怎么刷android10,安卓10的刷机教程,教你刷好Killer的精简包
- Linux 磁盘动态扩容 PVM(转载)
- 曙光服务器显示器接入只显示logo,显示屏只显示显示屏品牌logo,没有其他反应
- 借用百度翻译,用pyqt5 搞定pdf和word文档翻译,排版基本不变,免费好用
- c语言日历时钟编程,基于DS1302的日历时钟(1602液晶显示DS1302时钟)C语言程序设计...
- postgresql 并发访问_postgresql 并发update下导致的死锁问题
- asp毕业设计——基于Delphi+udp+UDP的基于局域网的信息收发系统设计与实现(毕业论文+程序源码)——教务信息管理系统
- java ssh 服务器文件传输_java使用SFTP上传文件到资源服务器