查看原文
其他

Unity教程 | 简化碰撞几何体

2017-01-03 Unity官方 Unity官方平台

本篇教程将展示如何为导入的3D模型自动生成简化版的碰撞器。教程将以Google SketchUp为例,但其中的概念及代码也适用于其它建模工具。


注意:请点击【阅读原文】查看文中涉及到的所有代码。


简介

现代游戏大多模型精良,通常一个人物模型需要渲染数千个顶点及三角面。但角色的碰撞会以简化过后的Mesh进行计算。例如,Unity自带的标准角色碰撞器就是一个胶囊碰撞器。球体、立方体、胶囊体及一些简单几何体之间的碰撞计算非常高效。也可以单独计算并处理3D模型每个面之间的碰撞,Unity就专门设计了MeshCollider组件来处理这种类型的碰撞。但它有着较大的性能消耗,对整个游戏体验会带来较大的影响。


第一步 难题

现在游戏中比较标准的解决办法就是,对物理对象采用简化的碰撞网格。这就需要在开发过程中进行额外的步骤。除了创建3D模型之外,还需要创建碰撞网格并将其置于正确的位置。使用某些软件可以大幅度简化该流程。但如果使用Google SketchUp这样的3D建模工具就不行了。从SketchUp中导入模型至Unity只能动态生成MeshCollider。


对于这个问题,一种可能的解决方法是自动添加所有您需要的几何体。首先需要了解的是,一旦从SketchUp导入模型,Unity将保留其组件的层级结构。SketchUp支持组和组件的概念,它们作为几何实体(顶点及三角面)的容器,组合成为模型。组和组件在导入Unity时都会被转换为游戏对象。对于组件,Unity会保留SketchUp中的命名再加上一个增量编号。如果Sketchup模型包含两个Table组件的实例,Unity会将它们命名为Table #1 和Table #2。


第二步 解决方案

这个简易教程的核心思想就是迭代导入游戏对象,并且只为某些特定的组件添加碰撞器。因为导入的模型包含许多嵌套的游戏对象,所以需要以递归(recursion)的形式遍历它们。递归流程如下:

  1. 从代表所导入模型的游戏对象开始;

  2. 迭代它所包含的游戏对象;

-如果当前游戏对象满足标准(以Table为前缀命名),那就为其添加一个Collider并结束;

-如果不满足标准,那就继续迭代它的子节点并重复步骤2。


使用AddComponent添加BoxCollider,与在检视面板中手动添加碰撞器效果一致,Unity会自动调整碰撞器大小直至与3D网格边框匹配。它会为游戏对象生成包围盒,并且适用于大部分情况。

第三步  自定义编辑器

该方法最大的问题是每次启动游戏时都会执行代码,也可以在游戏启动之前就执行,以减少游戏加载时间。实现该功能需要在编辑器中执行脚本,而非游戏启动后执行。Unity支持使用自定义脚本来扩展编辑器的功能及外观,可以创建自定义编辑器脚本实现该功能。在函数前定义MenuItem属性,以便在运行游戏之前就可以直接从编辑器调用。


这个新的设置可以生成碰撞器且不影响最终的玩家体验。如果有多个模型,可以将它们放在同一个游戏对象下,并从该游戏对象上调用此脚本。



第四步 改进

删除之前的碰撞器。多次运行CreateCollidersRecursively 函数会反复添加多次碰撞器。这会导致许多问题。因此,应该确保脚本在创建新的碰撞器之前删除所有已存在的碰撞器。


初始化预制件。使用该技术可以自动初始化那些SketchUp无法原生支持的对象。灯光、音源、收集物、敌人等等,它们都可以在函数递归步骤中创建。例如,下面的代码在找到名称前缀为“Light”的组时,就从预制件创建光源。


总结

本教程简单介绍了如何在Unity中循环遍历3D模型的组件,用于自动添加碰撞器并初始化一些预制件,例如:光源、音源及收集物等等。


本文来源于:alanzucconi.com

原作者:Alan Zucconi


相关阅读

Unity小技巧:粒子系统性能-剔除

Unity 2D教程 | 相机系统

Unity 2D教程 | 平台游戏

Unity教程|3D无尽跑酷游戏

Unity教程|制作一款3D射击游戏


点击“阅读原文”查看文中代码!

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存