Unity 3.5 到 4.0升级指南

http://game.ceeger.com/Manual/UpgradeGuide3540.html

游戏对象激活状态

Unity 4.0改变了游戏对象激活状态的处理方式。游戏对象的激活状态现在是从子游戏对象继承而来的,因此任何未激活的游戏对象也会导致其子游戏对象未激活。我们相信新的行为一直会比旧的行为更有意义。此外,即将到来的新GUI系统在很大程度上依赖于Unity4.0的行为,并且没有4.0是不可能的。不幸的是,这可能需要费些功夫修改现有的框架来适应Unity 4.0的新行为,变化在这里:

旧版行为:

  • 一个游戏对象是否是激活的是通过其active属性来确定的。
  • 通过检查.active属性来查询和设置。
  • 一个游戏对象的激活状态对于子游戏对象的激活状态是没有影响的。如果你想激活或不激活一个游戏对象和其所有的子对象,你需要调用游戏对象.SetActiveRecursively
  • 当在一个游戏对象上使用SetActiveRecursively,先前的子游戏对象的激活状态将会丢失。当你停用然后使用SetActiveRecursively激活一个游戏对象和其子对象,在调用SetActiveRecursively之前任何一个未激活的子游戏对象将被激活,如果你想恢复原来的状态,你必须手动跟踪子对象的活动状态。
  • 预置不包含任何激活状态,并在预置实例化后一直是激活的。

新版行为:

  • 一个游戏对象是否是激活的是通过其自身的active属性来确定的,其所有的源父对象也是如此。游戏对象是激活的如果其自身及父对象的.activeSelf属性是真实的。如果它们中的任何一个属性为假,游戏对象就是未激活的。
  • 通过.activeInHierarchy属性来查询。
  • 一个游戏对象的状态可以通过调用游戏对象.SetActive来改变。当在先前激活的游戏对象上调用SetActive(false)时,游戏对象及其所有的子对象将会取消激活。当在先前未激活的游戏对象上调用SetActive(true)时,如果所有的父对象是激活的,游戏对象将激活。当其所有父对象是激活的时,子对象将被激活。(例如,当所有父对象把.activeSelf设置为true).
  • 这意味着SetActiveRecursively不再需要,因为游戏对象的激活状态是从其父对象继承而来的。这同时也意味着当通过调用SetActive来取消激活或激活部分层级时,先前任何一个子游戏对象的激活状态将会被保护。
  • 预制可以包含激活状态,被保留在预制的实例中。

Example: 举例:

你有三个游戏对象,A,B和C,B和C是A的子对象。

  • 通过调用C.SetActive(false)来取消激活C
  • 现在,A.activeInHierarchy == trueB.activeInHierarchy == true 以及 C.activeInHierarchy == false
  • 同样,A.activeSelf == trueB.activeSelf == true 以及 C.activeSelf == false
  • 现在我们通过调用A.SetActive(false)来取消激活父对象A
  • 现在, A.activeInHierarchy == falseB.activeInHierarchy == false 以及 C.activeInHierarchy == false
  • 同样,A.activeSelf == falseB.activeSelf == true 以及 C.activeSelf == false
  • 现在我们通过调用A.SetActive(true)再次激活父对象A
  • 现在,有返回到A.activeInHierarchy == trueB.activeInHierarchy == true 以及 C.activeInHierarchy == false
  • 同样,A.activeSelf == trueB.activeSelf == true 以及 C.activeSelf == false

在编辑器新的激活状态

为了在Unity 4.0编辑器上看到这些变化,任何未激活的游戏对象(或是因为其自身的.activeSelf属性被设置为false,或是其父对象的.activeSelf属性被设置为false)在层级面板上将显示为灰色,并在监视面板中的图标也变为灰色。游戏对象自身的.activeSelf属性是通过激活的复选框来反映的,无论父对象处于什么状态它都可以切换(但是它将仅仅激活游戏对象如果所有父对象都是激活的)。

这是如何影响现有项目的:

  • 为了让你知道可能会影响到你的代码的位置,GameObject.active和GameObject.SetActiveRecursively()功能会被停用。
  • 他们仍然是有功能的。读GameObject.active的值与读GameObject.activeInHierarchy是相等的,设置GameObject.active与调用GameObject.SetActive()也是相等的。 调用GameObject.SetActiveRecursively()等于调用在游戏对象上调用GameObject.SetActive()及其子对象。
  • 导入3.5场景通过设置场景任何游戏对象之前的active属性到的selfActive属性。
  • 因此,任何从Unity先前版本为导入的项目仍应按预期工作(尽管编辑器发出警告),只要它不依赖于未激活但具有激活子对象的游戏对象(这在Unity 4.0中不再可能)。
  • 如果你的项目依赖于未激活游戏对象但具有激活子对象时,你需要在Unity 4.0改变这个模型的逻辑。

资源处理管线的变化:

在Unity4.0的发展期间,为了提高性能,我们的资源导入管线在内部一些重要方面已经发生了改变,如内存使用率和确定性。这些变化绝大部分对用户是没有影响的,但有一个例外:在导入管线最后和任何导入资源版本被完全替代之前,资源中的对象将不会持久。

第一部分的意味着,在后处理期间,你在资源中得不到正确的引用对象,第二部分意味着如果你在后处理期间使用先前导入版本的资源作为引用对象来做储存修改,那些修改将会丢失。

实例引用会丢失因为它们不是持久的

 考虑这个小例子:

public class ModelPostprocessor : AssetPostprocessor { public void OnPostprocessModel(GameObject go) { PrefabUtility.CreatePrefab("Prefabs/" + go.name, go); } }

在Unity 3.5这将创建一个具有所有正确引用到网格的预制,以为所有网格都已变得持久化,但在Unity 4.0不是这样的情况,同样的后处理将创建一个所有到网格的引用都丢失的预制,是因为Unity 4.0仍不知道如何解决在原始模型预制引用到对象。要正确复制一个modelprefab到预制,你应该使用OnPostProcessAllAssets检查所有导入到资源,找到modelprefab并创建新的预制,如上例。

先前导入资源丢弃的参考实例

第二个例子更复杂一点但实际3.5的例子在4.0上是坏的。下面是一个简单的ScriptableObject引用mesh的例子。

public class Referencer : ScriptableObject { public Mesh myMesh; }

我们使用这个ScriptableObject去创造一个通过在模型中引用mesh的资源,然后在我们的后处理器中我们采用那个引用并取一个不同的名字,最终的结果是当我们重新导入模型的名字将会重新处理。

public class Postprocess : AssetPostprocessor { public void OnPostprocessModel(GameObject go) { Referencer myRef = (Referencer)AssetDatabase.LoadAssetAtPath("Assets/MyRef.asset", typeof(Referencer)); myRef.myMesh.name = "AwesomeMesh"; } }

这在Unity 3.5中工作得很好但是在Unity 4.0中已经导入的模型将完全被取代,因此在先前的导入中改变mesh名字将没有作用。这里的解决办法就是通过其它方法寻找mesh并改变其名字。最要重视的是在Unity 4.0中,你应该只修改后处理器中给定的输入数据而不是依赖于与先前导入的相同的资源。

网格读/写选项

Unity 4.0在Mesh的导入设置中加入了"Read/Write Enabled"选项。当这个选项处于关闭状态时,这样可以节省内存,因为Unity可以在游戏卸载网格数据的副本。

然而,如果你在运行时使用非等比缩放或实例化网格,你必须在导入设置中启用"Read/Write Enabled"。原因是非等比缩放需要网格数据保存在内存中。一般来说我们在构建期间发现这种情况,但是当在运行期间mesh被缩放或实例化你需要进行手工设置。否则,他们在游戏构建中可能不会正确渲染。

网格优化

Unity 4.0中的 Model Importer在Mesh优化方面变得更好了。Unity 4.0中Model Importer的Mesh Optimization复选框默认是开启的,并且为了最优化操作,Mesh Optimization将会重排序顶点。你在你的项目中有一些后处理代码和效果,这取决于你的mesh中的顶点顺序,并且这些通过更改过后可能会坏掉。在这种情况下,在Mesh importer中关闭Mesh Optimization。尤其是,如果你使用SkinnedCloth组件,Mesh的优化将会引起你的顶点权重映射的改变。因此如果你正在一个项目中使用从3.5中导入的SkinnedCloth,你需要为受到影响的mesh关闭Mesh Optimization,或是重新配置你的顶点权重去匹配你的顶点顺序。

移动输入

使用Unity4.0移动传感器输入得到了更好地平台间协调,这就意味着你在处理移动平台上典型输入时可以写更少的代码。现在在IOS和Android平台上加速度计和陀螺仪输入都将遵循以同样的方式遵循屏幕的定位。为了充分利用这种变化,在处理加速度计和陀螺仪输入时,你应该重构输入代码并删除平台和屏幕方向特定代码。通过把Input.compensateSensors设置为false,你也可以在iOS上获取旧版的行为。



你可能感兴趣的:(unity)