unity快捷放置物体操做

最佳实践系列文章将探讨咱们在与客户合做时遇到的一些常见的问题。这些都是咱们的合做团队辛苦得出的经验和教训,咱们很自豪可以和你们分享他们的智慧。咱们已经为你们分享过如下内容:
 
 
 
 
 
 
这其中的不少问题只有在真正制做主机游戏、手机游戏、或者处理巨量游戏内容时才会出现。若是能在开发早期就将这些问题考虑进去,那么开发过程就会更轻松,而游戏也会更炫酷。
 
将对象放置到理想位置
 
尽管摆放对象是在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菜单项。
 
示例代码:PhysicsSettler.cs
 
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)模式的不一样,这样就能够知道什么模式更为适合。花费在布置虚拟对象的时间越少,那么在开发时获得的乐趣就越多。
相关文章
相关标签/搜索