[FormerlySerializedAs] 防止更新变量后数据丢失

官方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);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值