最佳实践系列文章将探讨我们在与客户合作时遇到的一些常见的问题。这些都是我们的合作团队辛苦得出的经验和教训,我们很自豪能够和大家分享他们的智慧。我们已经为大家分享过以下内容:
这其中的很多问题只有在真正制作主机游戏、手机游戏、或者处理巨量游戏内容时才会出现。如果能在开发早期就将这些问题考虑进去,那么开发过程就会更轻松,而游戏也会更炫酷。
尽管摆放对象是在Unity中最为常见的任务之一,我们还是看到不少团队为了如何能更好地完成这项工作而苦恼。要把对象排列完美,不让角色跑出世界,不让寻路出现障碍,并让各个物理对象能够放置在理想的位置,这的确不是件轻松的事。
Unity提供了一些工具来方便处理这个问题,这些工具各自扮演着不同的角色。尤其是在我们想要制作大量重复使用的内容,或是制作一张放置了大量动态物理对象的场景,了解这些工具的使用方法则尤为重要。
Unity中提供了变换、旋转和缩放工具,在Unity 2017.3中还加入了能同时拥有这三个功能的通用工具。这些小工具能在3D环境下修改游戏对象的变换属性。除此之外,还有2D环境下处理对象的矩形变换工具(Rect Transform)。
所有这些辅助工具的运作方式都与其所处的工作模式直接相关。如果将模式设为中心(Center),辅助工具将使用根据对象边界计算得出的对象中心点。这个计算结果是个近似值,所以在处理复杂对象时或许会感觉该中心点偏移了真正的中心点。
如果将辅助工具模式设为轴心(Pivot),辅助工具将使用对象自身引用框的原点(0,0,0)。这个轴心点是由创建该资源的作者在制作时设定的。通常需要将对象按照彼此相对的位置进行摆放时,我们推荐使用轴心模式,而且在制作资源时要留意轴心点的位置。
第二个切换按钮,全局/局部(Global / Local)切换按钮,确定了操作对象时所处的空间。设为全局(Global)意味着辅助工具将会对齐世界(x,y,z)坐标轴,而设为局部(Local)将会对齐对象自身的(x,y,z)坐标轴。通常我们需要在局部空间下处理对象。但如果我们想要让多个对象互相对齐,则会切换到全局坐标系,并使用网格对齐工具来排列对象。
在Unity中,最为直接的定位工具是按下CTRL键(Windows系统)或是Command键(OSX系统)来吸附网格。在我们通过坐标轴手柄(也就是分别为蓝、红、绿的坐标轴辅助工具)来移动对象时,按下吸附键会让对象根据当前网格大小计算的增量而移动,这个增量可以自行修改。
自动吸附设置(Snap Settings)菜单能为网格大小设置每个轴的数值,让我们控制旋转角度和缩放大小的吸附,还能将所选对象的当前变换属性近似取其最近的网格线。
吸附所有坐标轴(Snap All Axes)按钮在排列任意对象时十分有用。我们可以选择一组对象,将它们在坐标轴上吸附到网格,然后重新定位,这样就能把他们排列好了。效果如下图所示:
这个方法在处理规则几何体、大型关卡布局和设置碰撞块时十分管用。如果我们需要处理更为复杂的放置情况,则需要下面这些工具。
在使用变换工具时按住V,变换辅助工具会切换为顶点吸附模式,显示为一个小方框。然后点击所选对象网格上的一个顶点,将其拖到光标下的任意顶点上。在处理任意网格的对齐时,尤其是要处理那些复杂的或是不存在碰撞的网格对齐时,这个方法很实用。
在上图中,不管是电线还是台灯都没有紧凑的碰撞网格,而且它们也都不是规则的立方体,所以它们不能用网格吸附或碰撞吸附处理。
如果需要这样放置多个游戏对象,我们也可以将顶点吸附模式保持在打开状态。按下Ctrl+Shift+V打开,按下Ctrl+V关闭。这样便不需要一直按住V就能顶点吸附多个对象了。
按下CTRL + SHIFT可以启用碰撞吸附。启用后,必须拖拽变换辅助工具中心的黄色小方框,而不是使用坐标轴控制工具。这样会让所选对象与光标下对象的碰撞体相对齐。
用顶点吸附或网格吸附来对齐网格在处理静态几何体时十分出色,但如果要处理动态对象,比如说互相穿透并在触碰后发射到空中的对象时,应该吸附到碰撞体而不是可见网格。
如果有大量动态物理对象,或是十分复杂的关节系统,利用碰撞吸附来放置对象也许就不太合适。幸运的是,现在Unity编辑器中可以运行PhysX。它能模拟几秒的游戏时间,完成物理效果,然后保存完成时对象的位置信息。
下方是示例代码,代码中不仅有大量注释,还包含了调试信息绘制和一个菜单项。只要将其放入项目中的任何一个Editor文件夹里,便能看到一个新的GameMenu->Settle Physics菜单项。
using UnityEngine; using UnityEditor; [InitializeOnLoad] class PhysicsSettler { static bool registered = false; static bool active = false; static Rigidbody[] workList; static bool cachedAutoSimulation; const float timeToSettle = 10f; static float activeTime = 0f; static PhysicsSettler() { if (!registered) { EditorApplication.update += Update; SceneView.onSceneGUIDelegate += OnSceneGUI; registered = true; } } [MenuItem("GameMenu/Settle Physics")] static void Activate() { if( !active ) { active = true; workList = Object.FindObjectsOfType<Rigidbody>(); cachedAutoSimulation = Physics.autoSimulation; activeTime = 0f; foreach( Rigidbody body in workList ) { body.WakeUp(); } } } [MenuItem("GameMenu/Settle Physics", true)] static bool checkMenu() { return !active; } static void Update() { if( active ) { activeTime += Time.deltaTime; Physics.autoSimulation = false; bool allSleeping = true; foreach( Rigidbody body in workList ) { if( body != null ) { allSleeping &= body.IsSleeping(); } } if( allSleeping || activeTime >= timeToSettle) { Physics.autoSimulation = cachedAutoSimulation; active = false; } else { Physics.Simulate(Time.deltaTime); } } } static void OnSceneGUI(SceneView sceneView) { if( active ) { Handles.BeginGUI(); Color cacheColor = GUI.color; GUI.color = Color.red; GUILayout.Label("Simulating Physics.", GUI.skin.box, GUILayout.Width(200)); GUILayout.Label(string.Format("Time Remaining: {0:F2}",(timeToSettle - activeTime)), GUI.skin.box, GUILayout.Width(200)); Handles.EndGUI(); foreach( Rigidbody body in workList ) { if( body != null ) { bool isSleeping = body.IsSleeping(); if( !isSleeping ) { GUI.color = Color.green; Handles.Label(body.transform.position, "SIMULATING"); } } } GUI.color = cacheColor; } } }
当了解了何时和为何使用网格、顶点吸附、碰撞吸附时,我们将在关卡设计工作流程获得更好的开发体验。推荐开发者们多多尝试这些工具,例如:对比轴心(Pivot)和中心(Center)模式的区别,或是比较全局(Global)和局部(Local)模式的不同,这样就可以知道什么模式更为适合。花费在布置虚拟对象的时间越少,那么在开发时得到的乐趣就越多。
- Unity查找子物体的方式-怎么查找GameObject
Unity动态查找物体 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享.心创 ...
- Unity 3d 实现物体跟随摄像机视野运动
https://blog.csdn.net/qq_31411825/article/details/61623857 Unity 3d 实现物体跟随摄像机视野运动Created by miccall ...
- 【Unity笔记】物体的Transform操作:速度、旋转、平移
例如,通过按键/摇杆来操作飞机在三维空间的飞行状态.包括速度(大小,方向).位移. public class ExampleClass : MonoBehaviour { public float s ...
- [Unity官方文档翻译]Primitive and Placeholder Objects Unity原生3D物体教程
Primitive and Placeholder Objects 原始的基础物体 Unity can work with 3D models of any shape that can be cre ...
- Unity(2) 脚本简单操作
生命周期(按顺序排列) Awake():脚本唤醒,系统执行的第一个方法,在脚本声明周期内只执行一次,初始化一般可以在这里 Start():Awake之后,Update之前,只执行一次,一般在awake ...
- Unity 通用透明物体漫反射Shader(双面渲染&多光源&光照衰减&法线贴图&凹凸透明度控制)
Shader "MyUnlit/AlphaBlendDiffuse" { Properties { _Color("Color Tint(贴图染色)",Colo ...
- 關於mac os系統的一些快捷鍵和操作
一.了解mac os 1.桌面的组成元素 2.认识“Dock栏” Dock是一个神奇的东西,可以把Dock理解为Windows的任务栏,在这个地方可以随意拖放你想常驻在你屏幕底部的应用. Dock在工 ...
- Unity 移动端触摸屏操作
Unity 触屏操作 当将Unity游戏运行到IOS或Android设备上时,桌面系统的鼠标左键可以自动变为手机屏幕上的触屏操作,但如多点触屏等操作却是无法利用鼠标操作进行的.Unity的Input类 ...
- Unity摄像机围绕物体旋转两种实现方式
第一种,使用Transform 函数 RotateAround. 代码如下: public Transform target;//获取旋转目标 private void camerarotate() ...
随机推荐
- --set-upstream新版本不在支持
--set-upstream最新版本貌似不在支持,使用--track和--set-uptream-to来替代 --set-upstream: git branch --set-upstream [本地 ...
- 调试python 程序的几种方法总结
程序能一次写完并正常运行的概率很小,基本不超过1%.总会有各种各样的bug需要修正.有的bug很简单,看看错误信息就知道,有的bug很复杂,我们需要知道出错时,哪些变量的值是正确的,哪些变量的值是错误 ...
- mysql绿色版的应用
一.首先下载mysql 1.进入 https://www.oracle.com/index.html 网址 2.拉倒页面的最下面 3. 4.把下好的压缩文件解压出来 二.在DOS命令里面配置 1.先进 ...
- Python 操作 MySQL 数据库Ⅳ
执行事务 事务机制可以确保数据一致性. 事务应该具有4个属性:原子性.一致性.隔离性.持久性.这四个属性通常称为ACID特性. 原子性(atomicity).一个事务是一个不可分割的工作单位,事务中包 ...
- IDEA+SpringBoot+Freemark 构造一个简单的页面
访问地址 http://localhost:8083/m2detail 1.在Controller中配置 /** * m2detail */ @RequestMapping(value = " ...
- unittest详解(二) 跳过用例的执行(skip)
在执行测试用例时,有时候有些用例是不需要执行的,那我们怎么办呢?难道删除这些用例?那下次执行时如果又需要执行这些用例时,又把它补回来?这样操作就太麻烦了. unittest提供了一些跳过指定用例的方法 ...
- [笔记]mongodb一
一.MongoDB介绍 MongoDB是一个由c++编写的基于分布式文件存储的数据库.MongoDB介于关系型数据库和非关系型数据库之间,是非关系型数据库中功能最丰富,最接近关系型数据库.具有高性能, ...
- ping不通服务器就邮件警告
ping不通服务器就发一封邮件 (单台) vim /root/scipt/1.sh #!/bin/bash ping -c 4 192.168.0.116 &> /dev/null #p ...
- HTML DOM的学习
请看下面的 HTML 片段: <html> <head> <title>DOM 教程</title> </head> <body> ...
- 解决新建Maven项目webapp-- index.jsp报错
现在,随着项目开发的不断增长,项目变得庞大,jar包管理起来也很费时.使用maven工程可以很轻松的帮助我们管理jar包,省时. 今天,我在公司电脑新建的maven工程,新建完后 index.jsp报 ...