unity脚本api_Unity 5:API更改和脚本自动更新

unity脚本api_Unity 5:API更改和脚本自动更新

unity脚本api

As the breadth of the Unity feature set keeps on growing, and as we build it with more and more engineers at the same time, the necessity for being able to split up the product in separate modules becomes bigger and bigger. Obviously because it is just sound engineering practice. (It’s nice that when you change something in the physics code, that your audio doesn’t break). It also gets us closer to a situation where we could ship updates to different modules at separate timelines. And it’s nice that it gets easier to work on the different components with different teams. There’s one additional reason that is much more user visible: the ability to ship a smaller game. Don’t use particle systems? Don’t pay for them. Don’t use 2d rendering, Don’t pay for it. If you take a look at the WebGL demos that we posted, you can see that the entire unity engine that is converted to javascript (not manually thankfully!) clocks in at about 3mb of compressed javascript. That’s already pretty good, but we know there’s more juice to squeeze out of that. The web is still a platform where size matters a lot, and we want to bring the minimal size of a Unity published WebGL project down further. This is also true for other platforms, but at the moment, WebGL is definitely one of our more size-conscious platforms. So, with many good reasons to modularise the way we write code, test code, and ship code, we’ve started work down that path. There is still a very very long way to go, but if you don’t start you’re not going to get there either, so we started. While doing mostly non-user-visible work on this, we hit some dependencies in our API that need to be cut in order for us to proceed further in our efforts. Let’s look at that API problem: Many moons ago, when we started building our API, the C# code required to do something with a renderer component looked like this

随着Unity功能集的广度不断增长,以及我们同时与越来越多的工程师一起构建它,将产品拆分为单独模块的必要性变得越来越大。 显然是因为这只是合理的工程实践。 (很高兴当您更改物理代码中的某些内容时,音频不会中断)。 这也使我们更接近可以在单独的时间表将更新发送到不同模块的情况。 很高兴与不同团队一起在不同组件上工作变得更加容易。 还有一个更多的用户可见性的原因:发行较小游戏的能力。 不使用粒子系统? 不要为他们付费。 不要使用2D渲染,不要为此付费。 如果您看一下我们发布WebGL演示 ,您会看到转换为javascript的整个unity引擎(不是手动地感谢!)的压缩javascript时钟约为3mb。 那已经很不错了,但是我们知道还有很多汁可以榨出来。 网络仍然是一个规模非常重要的平台,我们希望进一步降低Unity发布的WebGL项目的最小规模。 对于其他平台也是如此,但是目前,WebGL绝对是我们更注重大小的平台之一。 因此,出于很多充分的理由对我们编写代码,测试代码和发布代码的方式进行模块化,我们已经开始沿着这条道路开展工作。 还有很长的路要走,但是如果您不开始,也不会到达那里,因此我们开始了。 在进行大多数用户不可见的工作时,我们遇到了API中的一些依赖关系,需要对其进行裁剪,以使我们进一步努力。 让我们看一下API问题:许多月前,当我们开始构建API时,使用渲染器组件执行某些操作所需的C#代码看起来像这样

1
2
3
4
5
void Start()
{
  Rigidbody r = (Rigidbody)GetComponent(typeof(Rigidbody));
  r.velocity = Vector3.up;
}
1
2
3
4
5
void Start ( )
{
   Rigidbody r = ( Rigidbody ) GetComponent ( typeof ( Rigidbody ) ) ;
   r . velocity = Vector3 . up ;
}

We disliked the verbosity of that so much, that (in addition to making a new .NET language unityscript-aka-javascript with much less boilerplate), we also added quick component property getters for commonly used components:

我们非常不喜欢这种冗长的冗长(除了使新的.NET语言unityscript-aka-javascript具有更少的样板之外),还为常用组件添加了快速的组件属性获取器:

1
2
3
4
void Start()
{
  rigidBody.velocity = Vector3.up; //"rigidBody" calls: UnityEngine.Rigidbody UnityEngine.Component.get_rigidBody()
}
1
2
3
4
void Start ( )
{
   rigidBody . velocity = Vector3 . up ; //"rigidBody" calls: UnityEngine.Rigidbody UnityEngine.Component.get_rigidBody()
}

Over time, we’ve been inconsistent in wether or not we added these quick accessors to the API for new components. For some we did, for others we didn’t, and by now it’s not clear why some components have them and others not. These accesors are also not nice for modularisation. When you modularise, you want to make sure that all the dependencies “point in one direction”. It’s okay for the physics module to talk to things in the core module, but it’s not okay for the core module to talk to the physics module directly, because it might not be there. Turns out that is exactly what we have here. We have the MonoBehaviour class, which is something that we want to put in a “core” module. but it has a property getter implementation for .rigidBody that returns a RigidBody object, which should obviously live in the physics module, that the core module shouldn’t be able to reference. For Unity5, we decided to bite the bullet, and remove all the quick component property getters with the exception of .transform (since that one belongs in the core module, there’s no need for it to go, and it’s also by far the most used one) [1][2]

随着时间的流逝,我们是否一直在将这些快速访问器添加到API中以获取新组件方面一直存在不一致之处。 对于某些我们已经做到了,对于另一些我们没有了,现在还不清楚为什么有些组件具有它们而另一些则没有。 这些附件也不适合模块化。 模块化时,您要确保所有依赖项都“指向一个方向”。 物理模块与核心模块中的事物进行对话是可以的,但是核心模块直接与物理模块进行对话是不可行的,因为它可能不存在。 事实证明,这正是我们在这里拥有的。 我们有MonoBehaviour类,我们希望将其放入“核心”模块中。 但它具有.rigidBody的属性获取器实现,该实现返回RigidBody对象,该对象显然应该存在于物理模块中,而核心模块不应该引用该对象。 对于Unity5,我们决定咬牙切齿,并删除.transform除外的所有快速组件属性获取器(由于其中一个属于核心模块,因此不需要这样做,而且它也是迄今为止使用最多的模块)一)[1] [2]

As I wrote in a previous post, one of the hardest things of making Unity is finding the balance between “making things better” and “not breaking projects that already work”. Since we feel that modularisation is very important in the long run, we decided to remove the .rigidBody style accessors, but we were not comfortable with the amount of pain that would bring our users. So we embarked on a project to reduce the user pain introduced by this work: Automatic Script Updating

正如我在上一篇文章中所写,使Unity变得最困难的事情之一就是在“使事情变得更好”和“不破坏已经起作用的项目”之间找到平衡。 由于从长远来看,我们认为模块化非常重要,因此我们决定删除.rigidBody样式访问器,但对于让用户感到痛苦的方式,我们感到不满意。 因此,我们着手进行了一个减轻用户工作负担的项目: 自动脚本更新

Unity5 will ship with (unless something really bad happens) the ability to detect when your scripts use old API, and is able to, after asking for your permission, rewrite that code to use the new API. So if you have a script that does this:

Unity5将具有(除非发生真正的不好的情况)检测脚本何时使用旧API的功能,并且能够在征得您的许可后重写该代码以使用新API。 因此,如果您有执行此操作的脚本:

1
2
3
4
void Start()
{
  rigidBody.velocity = Vector3.up;
}
1
2
3
4
void Start ( )
{
   rigidBody . velocity = Vector3 . up ;
}

We will convert that for you to:

我们将为您将其转换为:

1
2
3
4
void Start()
{
  GetComponent<Rigidbody>().velocity = Vector3.up;
}
1
2
3
4
void Start ( )
{
   GetComponent & lt ; Rigidbody & gt ; ( ) . velocity = Vector3 . up ;
}

The script updaters work for C#, UnityScript-aka-Javascript, Boo, and prebuilt .dll assemblies. (We actually read the IL code inside the prebuilt assemblies using the wonderful Cecil library by Jb Evain of UnityVS fame, detect usages of deprecated API, and then rewrite the IL code to use the new API instead). Perhaps unsurprisingly the feedback from early Unity5 testers was “hey, there is a script updater now, and it fixed all my quick property accessors, but there are more API changes you guys did that it did not fix”, and we find ourselves in the kind of good problem to have situation where it looks like the updaters work well enough that it makes sense to look at the more minor API changes that we’ve done and see which ones of those we can update reliably, and which ones we cannot. Maybe one day we could even open this up to asset store vendors, and allow them to provide “rewrite rules”, so that they also gain increased flexibility in improving API, fixing old mistakes while keeping user pain at a minimum. Should you have become accustomed to the component accessors to the point that you really really want to keep them anyway, it’s trivial to write a MyMonoBehaviour class with all these properties in it, that you make all your scripts derive from. We hope this approach strikes a good balance between not putting too much work on the plate of our users, while still being able to improve API, fix mistakes, and make Unity better.

脚本更新程序适用于C#,UnityScript-aka-Javascript,Boo和预建的.dll程序集。 (事实上,我们读通过精彩的预建的组件内的IL代码塞西尔库JB EvainUnityVS成名,检测鼓励使用的API用法,然后重写IL代码使用新的API,而不是)。 出乎意料的是,早期Unity5测试人员的反馈是“嘿,现在有一个脚本更新程序,它修复了我所有的快速属性访问器,但是你们做了更多的API更改,使它无法修复”,我们发现自己在出现这样的好问题,即更新程序看起来运行良好,因此有必要查看我们所做的较小的API更改,看看哪些可以可靠地更新,哪些不能可靠地更新。 也许有一天我们甚至可以向资产商店供应商开放,并允许他们提供“重写规则”,以便他们在改进API方面也具有更大的灵活性,可以解决旧错误,同时将用户的痛苦降至最低。 如果您已经习惯了组件访问器,而实际上您真的想保留它们,那么编写一个包含所有这些属性的MyMonoBehaviour类是很简单的,您可以从中获取所有脚本。 我们希望这种方法能够在不给用户增加过多工作量的同时,仍能够改善API,修复错误以及使Unity更好地取得平衡。

Bye, Lucas (@lucasmeijer)

再见,卢卡斯( @lucasmeijer )

[1] An alternative approach would have been to introduce extension methods. This is basically the physics module being able to add additional methods to the MonoBehaviour class. This would mean user code would have to change from

[1]另一种方法是引入扩展方法 。 基本上,这是物理模块,可以向MonoBehaviour类添加其他方法。 这意味着用户代码必须从

1
.rigidBody
1
. rigidBody

to

1
.RigidBody()
1
. RigidBody ( )

We felt that was hard that was not a very attractive alternative. Hopefully one day C# gets extension properties. Should those have existed, we would have been able to keep source-level compatibility and still move the rigidBody code out into its own module.

我们感到很难,这不是一个非常有吸引力的选择。 希望有一天C#获得扩展属性。 如果这些已经存在,我们将能够保持源代码级的兼容性,并且仍将僵尸代码移至其自己的模块中。

[2] in Unity5 we also cache the transform component on the c# side, so there should no longer be a performance reason to cache the transform component yourself.

[2]在Unity5中,我们还在c#端缓存了转换组件,因此不再有性能上的原因可以自己缓存转换组件。

翻译自: https://blogs.unity3d.com/2014/06/23/unity5-api-changes-automatic-script-updating/

unity脚本api