官方Blog:http://blogs.unity3d.com/2015/02/03/renaming-serialized-fields/
RENAMING SERIALIZED FIELDS
As some of you may know, we built most of the new UI System as user scripts. That means we were subject to most of the limitations our users face when developing systems in Unity and extending the editor. Throughout the development we’ve been fixing the issues we came across. Today we would like to highlight one of them.
One of the problems we faced was how could we rename fields without having our users lose data. During our beta period, we wanted to refactor our code without breaking our beta users projects, so they could continue testing each new version without having to worry about data loss and project breakage. To solve that we introduced the [FormerlySerializedAs] attribute.
WHAT CAN YOU DO WITH IT? LET’S LOOK AT SOME USE CASES FOR IT!
Variable renaming
Let’s say you have the following class:
1
2
3
4
5
6
|
using
UnityEngine;
class
MyClass : MonoBehaviour
{
[SerializeField]
private
string
m_MyVariable;
}
|
But you would like to rename m_MyVariable to something else like m_ABetterName, but you don’t want your users to have to re-populate the data for this MonoBehaviour in all of their scenes and/or prefabs. You can now accomplish that like this:
1
2
3
4
5
6
7
8
|
using
UnityEngine;
using
UnityEngine.Serialization;
class
MyClass : MonoBehaviour
{
[FormerlySerializedAs(
"m_MyVariable"
)]
[SerializeField]
private
string
m_ABetterName;
}
|
Encapsulating public API
In this case, you have a public field that is part of your API, but would like to encapsulate it in an accessor. So let’s assume we have a class MyClass like this:
1
2
3
4
5
|
using
UnityEngine;
class
MyClass : MonoBehaviour
{
public
string
myValue;
}
|
To encapsulate this value in an accessor without losing any existing data in your assets you can do something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
using
UnityEngine;
using
UnityEngine.Serialization;
class
MyClass : MonoBehaviour
{
[FormerlySerializedAs(
"myValue"
)]
[SerializeField]
private
string
m_Value;
public
string
myValue
{
get
{
return
m_Value; }
set
{ m_Value = value; }
}
}
|
Multiple Renames
Renaming fields multiple times is supported, just add the attribute multiple times, one for each name of the previous names of the field:
1
2
3
4
5
6
7
8
9
|
using
UnityEngine;
using
UnityEngine.Serialization;
class
MyClass : MonoBehaviour
{
[FormerlySerializedAs(
"m_MyVariable"
)]
[FormerlySerializedAs(
"m_ABetterName"
)]
[SerializeField]
private
string
m_EvenBetterName;
}
|
WHEN CAN I REMOVE THE ATTRIBUTE?
You can remove the attributes after you have re-saved all of your scenes and assets, after the rename. Of course this implies you have ‘control’ of your users. For some, like the Asset Store publishers for instance, this ‘control’ is impossible. So in this case you will have to keep it as long as you want to make sure people with any version of your code can upgrade to your new code without losing data.
Hope you find this new little feature helpful!
其他相关信息:
A Summary of Unity Attributes(标签集合)
http://www.tallior.com/unity-attributes/
获取所有Attributes方法:
var
unityEngineAttributes =
typeof
(MonoBehaviour).Assembly.GetExportedTypes().Where(t => IncludeType(t)).ToArray();
var
unityEditorAttributes =
typeof
(CustomEditor).Assembly.GetExportedTypes().Where(t => IncludeType(t)).ToArray();
private
bool
IncludeType(Type t)
{
return
t.IsPublic
&& !t.IsDefined(
typeof
(ObsoleteAttribute))
&&
typeof
(Attribute).IsAssignableFrom(t);
}