65.9K
CodeProject 正在变化。 阅读更多。
Home

Unity3D架构 – 令人头疼的“.”

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2014年5月10日

CPOL

3分钟阅读

viewsIcon

26008

Unity 5 即将发布,带来了一大堆新特性,有些显而易见,有些则不那么明显。如果你还没有看过 Unity 5 公开展示的新特性,可以查看在 Unite 2014 上展示的功能预览。然而,有一些幕后变化…

“.” 到底意味着什么?

当你在 Unity3D 项目中使用组件和脚本,然后想在代码中访问它们时,很容易就开始编写

this.renderer.collider.attachedRigidbody.angularDrag = 0.2f;

(是的,这有点极端,但目的是为了说明问题。)

在这段简单的代码中,你实际上调用或访问了附加到你正在运行脚本的 GameObject 的 3 个单独的组件。

在后台,Unity3D 会将其转换为

var renderer = this.GetComponent<Renderer>();
var collider = renderer.GetComponent<Collider>();
var ridgedBody = collider.GetComponent<Rigidbody>();
ridgedBody.angularDrag = 0.2f;

现在看起来不那么简单了,不是吗?这个过程本质上是缓慢的,有时会涉及大量的反射(在内存中解构代码的过程,例如任何 Function(string) 方法都会这样做)。

将此乘以每一帧,你就可以开始理解为什么这是一个问题了。最初这只是编写更简单代码的一种方式,但随着它日益普及,Unity 已经表示“够了”,并正在进行破坏性更改。

据我所知,这种行为也会影响 JavaScript 和 Boo。

Unity3D 的最佳实践

使用 DOT 符号在代码中更改组件的行为确实有效,但就像很多事情一样,“仅仅因为你可以做某事并不意味着你应该这样做”,那么你可以做些什么来改进你的代码?

第一部分是理解你的代码并使其更好,这样你就会考虑

  • 我真的需要在每一帧中都引用一个组件吗?
  • 如果需要,则将该组件作为脚本中的引用来访问,而不是每次都调用 GetComponent
  • 如果你愿意,仍然可以在每一帧中调用 GetComponent (不建议),你现在可以控制它了。

因此,我会将上面的脚本转换为

Rigidbody myScriptBody;
void Awake()
{     var renderer = this.GetComponent<Renderer>();     
      var collider = renderer.GetComponent<Collider>();
      myScriptBody = collider.GetComponent<Rigidbody>();
}
void Update()
{     myScriptBody.angularDrag = 0.2f * Time.deltaTime;
}

这样只在脚本第一次运行时使用 GetComponent 并存储运行时需要的引用(或引用),然后使用内存中的引用而不是尝试每一帧都发现它。

这些只是你使用和访问 Unity3D 系统中组件的简单更改。

最好的建议

你现在已经知道了新的知识,并做好了准备,使用这些知识来更改你当前的实践,如果你一直在代码中使用“.” 方法。

在观看每一个视频教程或从库或维基导入脚本时,请记住这一点,并提前进行调整。

如果你目前在你的代码中大量使用这种方法,并且认为这对于代码的模块化来说是一个很大的改变,那么请关注 Unity5,仍然有很多惊喜等待着你,包括一些帮助解决这种行为的问题。

未来是光明的,未来是 Unity5

Unity 5 即将发布,带来了一大堆新特性,有些显而易见,有些则不那么明显。

如果你还没有看过 Unity 5 公开展示的新特性,可以查看在 Unite 2014 上展示的功能预览。

© . All rights reserved.