基本基本技能



美好的一天,亲爱的哈巴罗夫斯克!

每个开发人员都希望更快地创建自己的游戏,但是该怎么做呢? 本文讨论了减少Unity环境中的开发时间的基本技能。

技能1-处理项目结构


要维护项目中的顺序,您需要了解其结构。 它可以表示如下:

  1. 模型-存储项目中使用的所有模型
  2. 预制件-存储所有模型模板
  3. 纹理-存储所有纹理
  4. 材料-存储所有材料
  5. 脚本-存储所有脚本
  6. 声音-存储所有声音
  7. 动画-存储所有动画

如果您有复杂的对象(例如角色),则会为他创建一个单独的文件夹,重复上述结构。


字符文件夹结构

另一种方法是创建上述文件夹,并将对象的各个部分放置在每个文件夹中,也就是说,以下结构将用于角色动画。


动画文件夹结构

技能2-使用场景中的对象层次结构


为了简化使用相同对象集的操作,可以将它们组合为一组,其中空对象充当父对象。

这将有助于轻松关闭整个位置或室内的灯光。 找出所有对象的位置。

每个元素都相对于元素被调用,最后添加父对象的后缀。 例如,洞穴中的金条将被称为“ goldBar_cv1”,其中cv1表示Cave1,而森林中的树名为“ tree_frt1”,其中frt1表示forest1。 对于后缀,将采用单词的第一个字母,第二个音节的第一个字母和单词的最后一个字母。


场景中对象层次结构的示例

技能3-视觉呈现


Unity有3个主要光源:

  1. 定向光-太阳的类似物
  2. 点光源-灯泡的类似物
  3. 聚光灯-手电筒的类似物

如果有光,则必须有光源。 例如,在洞穴中,如果角色没有手电筒就不能点亮(对于手电筒,聚光灯比较合适)。

使用后处理应用效果。

图片
现场无需后期处理

图片
后处理场景

从那时起的 UPD

除了以视觉方式呈现的光源外,还存在全局光源设置:“ 窗口 ”顶部的选项卡,“ 照明”项,“ 设置”子项。 在那里,例如,您可以收紧环境的照明,安装天空盒,增加雾气。 实际上,您需要在这里查看是否问自己“是否删除了所有光源,但舞台上的光与白天一样”。 顺便说一句,当游戏在编辑器中运行时,您已经可以进入这些设置,以便您可以即时查看更改。 但是,关闭游戏模式后,设置将返回到游戏测试开始之前的状态。 因此,您必须再次爬入该窗口并调整值。 一个有用的细节-例如,如果您想更改照明的颜色(“照明环境”组中的环境颜色),则在带有调色板的面板上请注意“十六进制”项-当前颜色的编号显示在窗口中,您可以将其复制并粘贴到同一字段中当游戏模式关闭时。 相同的技巧对于调整雾的颜色等很有用。

同样,在游戏模式下运行时,您可以通过编辑器更改对象的某些参数-将变量脚本的值移到可见性区域,启用/禁用对象网格的渲染,等等。 最主要的是不要被带走,以免破坏东​​西。 关闭游戏模式后,将恢复更改的值。 这不适用于某些单独的元素,例如,如果您在附带的游戏模式下编辑了地形纹理,则其更改将被保存。


技能4-使用相机


需要在舞台上找到物体吗? 在层次结构中的对象名称上单击2次。

想从1个人飞过舞台吗? 按住RMB并使用WASD键(Shift加速)移动。

想从不同的角度看场景吗? 利用Gizmos(Gizmos)。


Gizmo地点

技能5-处理对象


想要在场景中添加角色吗? 添加RigidBody和CapsuleCollaider组件。 RigidBody告诉引擎,应该将固态物理应用于此对象。

是否要检查角色与物体的碰撞? 将MeshCollaider组件添加到对象,然后在OnCollisionEnter函数的字符脚本中检查字符遇到的对象的标记。

检查角色与对象碰撞的实现示例
private void OnCollisionEnter(Collision collision) { switch (collision.gameObject.tag) { case "Moneys": Destroy(collision.gameObject); // Do something break; case "TrapSpikes": hitPoints -= 5.5; break; } } 



从那时起的 UPD
角色不一定总是使用刚体;管理方法可能有所不同。 但是几乎总是需要角色对撞机,除非您要以更棘手的方式计算碰撞。 Unity还具有一些特定的控制器/对撞机-最好阅读文档以更详细地了解它们。 但是最好从YouTube上的简单示例开始。

至于角色遇到的那些对象。 Mesh Collider通常应该挂在那些复杂形状是考虑碰撞的一种或另一种重要方式的对象上。 如果只是一个按钮,最好与Box Collider等更简单的对撞机打交道。 此外,您可能必须为特别复杂的3D对象制作一个更简单,不可见的碰撞网格,并将Mesh Collider悬挂在其上,而不是悬挂在可见对象本身上。

关于按钮对撞机,值得记住的是,在对撞机的组件中,需要选中“ 触发”框,以便脚本可以处理click事件。 刚体部件必须分配给任何桶,盒子和其他必须对碰撞产生简单的物理反应并在重力作用下掉落的物体。


技能6-导入模型


以从Blender导入模型为例考虑该过程。 假定您已经进行了扫描,应用了纹理或选择了材质。

  1. 将模型置于零坐标(相对于轴的中心)
  2. 将比例设为1
  3. 去除不必要的物体(相机,光源)
  4. 以.fbx格式保存模型
  5. 将文件传输到Unity
  6. 拉入文件夹-模型到模型,材料到材料等
  7. 创建模型预制件
  8. 与预制件进一步合作


从那时起的 UPD

搅拌机


请注意,如果将搅拌器材料分配给模型,则它们将以简化形式进行传输,并且会使材料列表混乱。
您根本不需要在Blender中进行复杂的开发和纹理化-一种更简单的方法是遍历模型的所有元素,然后在右侧窗口中选择“ 数据”项。 这是一个三角形的图标,向下看,在修改器(扳手)和材料(粉红色球)项之间有三个点。 在其中,单击“ UV贴图”图旁边的+ ,将出现带有国际象棋球图标的自动扫描。 这需要对模型的每个元素进行,然后才导出。 然后在Unity中已经可以将具有平铺纹理的材料应用于此零件,如果不执行此操作,则该材料将仅以纯色绘制该零件。 (如果以后使模型元素变形,则丢弃扫掠并重新分配它,以使其不被拉伸)。

如果您的模型由不同的元素组成,那么您已经可以在Unity中移动模型的各个元素或禁用它们。 这在各种情况下都是有用的。

如何以简单的方式构造模型。


首先,您需要一些512到512瓦片纹理,并通过Import New Asset以3D模型相同的方式添加它(请记住,应该选择一个合适的文件夹)。 同时,在右侧的检查器中,在“ 默认”窗口中添加的纹理上,将“ 最大大小”参数设置为512。然后单击“ 应用” 。 现在可以准备将​​纹理添加到材质中,或者说可以将其绘制为Terrane。 注意第一个要点-纹理类型,现在它处于默认模式,但是当您需要加载法线贴图,半透明精灵的图像等等时,您需要在此处设置适当的设置。
接下来,我们需要创建材料。 我们再次转到上方的菜单- 资产 ,然后单击下拉列表创建材料 (同样,不要忘记将在当前选定的文件夹中创建材料)。 您以材料的名称驱动,并在检查器中打开Albedo项目(直到我们停止其他参数,但原理相似),然后在其中搜索并分配以前加载的纹理。 附近有一个可以额外着色您的纹理的彩色窗口,以及“金属”和“平滑度”滑块可增加眩光或暗淡度。 平铺大小参数也很有用,下面几行。
创建材料后,您可以抓住它并将其直接扔到模型或其元素上,不要错过它,否则就不用油漆了。

不要忘记相同的纹理可以用于不同的材料。 例如,带有不同颜色和/或不同瓷砖尺寸的杂质。

预制件。


通常,预制件是这样完成的-他们将对象拖到场景上,然后将其名称挂在层次结构窗口中,然后将其拖到文件夹中。 然后将出现一个基于该对象的预制件,在检查器中,该预制件将带有一个蓝色立方体图标,并且将在标签Prefab下方签名。
但是,您不需要立即进行所有预制工作。 您可以将对象扔到场景上,然后使用复制粘贴将其克隆并像这样进行测试。 如果一切都适合您,则将对象转换为预制件,如果不合适,例如,模型中出现错误,然后从场景中删除其副本,从文件夹中删除模型本身,将其固定在3D包中,然后再次导入。

您还可以在舞台上将一些新的子元素推入预制板中。 但是,它们不会成为其中的完整部分,也就是说,它们将不会影响此预制件的其他副本,除非您在名称为Prefab的行上单击检查器中的“应用”按钮。


技能7-实施逻辑


避免昂贵的操作。 一个示例是确定到物体的距离。

昂贵的操作示例
 using UnityEngine; using System.Collections; public class ExampleClass : MonoBehaviour { public Transform other; void Example() { if (other) { //       //         float dist = Vector3.Distance(other.position, transform.position); print("Distance to other: " + dist); } } } 


更快的实施示例
 using UnityEngine; using System.Collections; public class ExampleClass : MonoBehaviour { public Transform other; public float closeDistance = 5.0f; void Update() { if (other) { Vector3 offset = other.position - transform.position; //     float sqrLen = offset.sqrMagnitude; //    ,     if (sqrLen < closeDistance * closeDistance) { print("The other transform is close to me!"); } } } } 


在此处阅读有关昂贵操作的更多信息。

结论


以上技能将大大减少开发和项目支持期间的时间。

如果您认为某些主题是肤浅的,请在有关它们的评论中更详细地写。

Source: https://habr.com/ru/post/zh-CN459184/


All Articles