1. 前言

    最近连续做了很多代码动态生成Mesh的工作,从动态生成修改瞄准范围的Mesh到可破坏的墙壁,以及之前写了一半导航网格生成.
    想借此机会整理下最近的积累,如果在阅读过程中发现一些问题或是有争议的地方,欢迎交流

2. Mesh数据简介

    
    一个Mesh的必要结构有: 顶点,三角形
    用于渲染的Mesh一般就会有:
        UV:   一般会有多组,一般0是主贴图uv,Unity中1是lightmaps使用 2是dynamic GI使用
        法线: 处理光照等
        颜色: 一般作为额外数据存储
        其他数据;

3.创建简单的Mesh

 Vector3[] newVertices = { 
        new Vector3(-0.5f, 0, 0), new Vector3(0.5f, 0, 0), 
        new Vector3(-0.5f, 0, 1), new Vector3(0.5f, 0, 1) 
    };
 Vector2[] newUV = { 
        new Vector2(0, 0), new Vector2(1, 0), 
        new Vector2(0, 1), new Vector2(1, 1) 
    };
 int[] newTriangles = { 0, 2, 1, 2, 3, 1 };
   LineMesh = new Mesh();
 LineMesh.vertices = newVertices;
 LineMesh.uv = newUV;
 LineMesh.triangles = newTriangles;
 LineMesh.RecalculateBounds();        
    
    应用在游戏里:
        a. 拖尾,轮胎印
        b. 技能瞄准特效

4.格子地图转NavMesh
     过程概述:
        1 划分区域       
        这步比较简单,把相连的局域划分再一起就可以了
        
        2 每个范围的边缘点
        针对每个局域计算边界,先用Marching squares 算法 获取轮廓再用Douglas-Peucker算法压缩轨迹
        
        3 生成全Mesh
        将空间内的关键点,边数据,用 Delaunay 德洛内三角划分,该算法比较复杂,但网上有很多实现
        一个Unity中的实现: https://github.com/Scrawk/Hull-Delaunay-Voronoi 
        一个纯算法的实现: https://www.cs.cmu.edu/~quake/triangle.html   
        需要注意的是,有时候划分出来的边,和预想中的边不一致,需要处理一下
                            
                            
        
        4 剔除阻挡内的三角形

        5 对比Unity原生的导航网格生成数据
         
    最终结果分析
        这里给的过程只是由格子地图数据往导航网格数据转化的一种方法,并不是真正的导航网格生成算法.
        缺少了关于半径的处理,多层空间的处理,凸多边形划分等操作

5. 可破坏的墙壁

    可破坏的墙壁一般有三种实现方法
    1. 将有限种类的砖块按照简单逻辑组合成一面墙,破损时,按砖块掉落
        如彩虹6号中的木板墙就是用这种方法做的
    2. 将原本的Mesh离线拆分为几块,在破碎时整体爆开
        一般的整体可破坏物都是这么做的,比如木栅栏
    3. 某个部位被破坏时,实时在Mesh上扣一个洞
        把墙壁被破坏的部分当做是阻挡,和之前所讨论的格子地图转导航网格的算法十分类似
        
    4. 有一些额外的数据要处理
        a 将2D的Mesh片生成为3D的墙壁
            需要将顶点位移复制一份,背面三角形反向,边缘补上侧面
        b 显示部分数据,需要额外计算顶点的uv值
        c 破碎边缘的处理,参考2D格子地图的边界处理方式,在边缘上铺上一层破碎效果的边
            



    


创建Mesh->格子地图转NavMesh->可破坏墙壁的更多相关文章

  1. cocos2dx中的格子地图TileMap

    格子地图的优点: a.节省内存,我们知道对于一款游戏来说,如果以图片来作为地图的话,对于神庙逃亡,魂斗罗这样的场景很多,地图很长的游戏显然不现实,因为图片很占内存,但是这些游戏的地图有一个特点就是:重 ...

  2. 创建用户故事地图(User Story Mapping)的8个步骤

    [小编]上周六了解了用户故事地图后,小编又查阅了一些资料,找到了以下这篇关于如何组织用户故事地图规划的文章,分享给大家.也希望大家如果有好的实践,也可以留言一起交流. 原文地址:http://winn ...

  3. threeJS创建mesh,创建平面,设置mesh的平移,旋转、缩放、自传、透明度、拉伸

    这个小案例是当初我在学习的时候,小的一个小案例,代码还需要进一步优化:还请谅解~~:主要用到了threeJS创建mesh,创建平面,设置mesh的平移,旋转.缩放.自传.透明度.拉伸等这些小功能: 采 ...

  4. javascript 百度地图无秘钥(appkey)创建marker标记地图

    创建简单的marker地图不一定需要去百度地图申请key,简单代码实现marker地图,效果如图: html代码如下,代码中的baidu.api.js参考后面的隐藏代码: <!DOCTYPE h ...

  5. Unity通过脚本创建Mesh(网格)

    ##1.创建一个带Mesh的物体 Unity中的网格作为组件不能脱离物体单独存在 新建脚本CreateMesh public class CreateMesh: MonoBehaviour { voi ...

  6. Unity3D学习笔记4——创建Mesh高级接口

    目录 1. 概述 2. 详论 3. 其他 4. 参考 1. 概述 在文章Unity3D学习笔记2--绘制一个带纹理的面中使用代码的方式创建了一个Mesh,不过这套接口在Unity中被称为简单接口.与其 ...

  7. unity2018使用tileMap生成地图 类似泰拉瑞亚创建和销毁地图块

    参考网站:https://blog.csdn.net/pz789as/article/details/79540890 using System.Collections; using System.C ...

  8. unity, 用脚本创建mesh

    创建一个空gameObject,添加Mesh Filter和Mesh Renderer两个component,再添加一个脚本createMeshScript: using UnityEngine;us ...

  9. Unity中动态创建Mesh

    什么是Mesh? Mesh是指的模型的网格,3D模型是由多边形拼接而成,而多边形实际上又是由多个三角形拼接而成的.即一个3D模型的表面其实是由多个彼此相连的三角面构成.三维空间中,构成这些三角形的点和 ...

随机推荐

  1. 洛谷—— P1098 字符串的展开

    https://www.luogu.org/problem/show?pid=1098 题目描述 在初赛普及组的“阅读程序写结果”的问题中,我们曾给出一个字符串展开的例子:如果在输入的字符串中,含有类 ...

  2. poj——2239 Selecting Courses

    poj——2239   Selecting Courses Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10656   A ...

  3. 开源项目SwipeBackLayout的问题处理

    在安卓系统4.4会出现滑动时底层没有之前的activity界面?解决:在主界面设置如下: <item name="android:windowIsTranslucent"&g ...

  4. maven pom.xml文件介绍

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...

  5. Java: 创建自带依赖库的Jar包

    pom.xml文件如下: <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&quo ...

  6. HTML的DIV如何实现垂直居中

    外部的DIV必须有如下代码 display:table-cell; vertical-align:middle;   这样可以保证里面的东西,无论是DIV还是文本都可以垂直居中

  7. iOS iOS8中 问题&quot;registerForRemoteNotificationTypes: is not supported in iOS 8.0 and later&quot; 解决方式

    问题重述: iOS 8中改变了通知注冊的方式,假设App须要同一时候支持iOS 7 和 8 的话,须要首先检查selector. 解决方式:在Xcode 6中 - (BOOL)application: ...

  8. Boost中的Timer的使用——计算时间流逝

    使用Boost中的Timer库计算程序的运行时间 程序开发人员都会面临一个共同的问题,即写出高质量的代码完毕特定的功能.评价代码质量的一个重要标准就是算法的运行效率,也就是算法的运行时间.为了可靠的提 ...

  9. C项目实践--图书管理系统(2)

    前面在<<C项目实践-图书管理系统(1)>>中把系统中的三大功能模块中可能涉及到的常量,结构体及相关函数进行了声明定义,下来就来实现它们. 执行系统首先从登录到系统开始,所以首 ...

  10. JDBC连接数据库查询信息的步骤(提取成配置文件方式)

    硬编码格式的弊端:数据库发生改变时,要重新修改代码,重新编译和部署 解决方法:将数据库信息写在配置文件当中,让程序通过读取配置文件来获得这些信息 jdbc.driver.class=com.mysql ...