Como renomear variáveis sem perder dados na Unity

Quando trabalhamos na Unity, podemos expor as variáveis que criamos em nossos componentes diretamente no editor. No entanto, a engine usa os nomes das variáveis para salvar seus valores em um arquivo e caso renomearmos a variável o dado que estava salvo no editor será perdido. Para evitar a perda de dados quando o nome de uma variável mudar, podemos usar o atributo FormerlySerializedAs.

Entendendo o problema

Quando programamos é inevitável que eventualmente teremos que refatorar nosso código fonte. E parte desse processo é renomear variáveis para nomes melhores. Com as ferramentas que as IDEs oferecem, esse é um processo relativamente simples, especialmente quando falamos de variáveis privadas.

Porém quando trabalhamos com a Unity, podemos expor essas variáveis no editor para que possamos editá-las sem ter que modificar diretamente o código. Fazemos isso criando uma variável pública ou com o atributo SerializeField em uma variável privada. Isso é ótimo porque nos permite testar diferentes valores de forma rápida. 

Agora imagina que após vários testes encontramos o valor ideal para o nosso componente. Se a variável for renomeada durante o processo de refatoração todo esse trabalho será perdido. Isso acontece porque durante o processo de serialização da Unity, ela usa o nome da variável para salvar o valor em um arquivo, que mais tarde é lido pela engine para preencher os campos no editor.

Para evitar que isso aconteça, podemos usar o atributo FormerlySerializedAs antes de renomear uma variável. Dessa forma, na próxima vez que a Unity fizer o processo de desserialização ela vai saber que essa nova variável deve ter o mesmo valor da variável antiga.

Como usar FormerlySerializedAs

Vamos ver um exemplo. Vamos supor que temos o seguinte código:

using UnityEngine;
using UnityEngine.Serialization;

public class Character : MonoBehaviour
{
    [SerializeField]
    private int maxLives;
}

Antes de podermos usar o atributo FormerlySerializedAs precisamos importar o namespace UnityEngine.Serialization. Com isso durante o processo de refatoração do código podemos usar o atributo para indicar à Unity que renomeamos a variável.

O código ficará assim:

using UnityEngine;
using UnityEngine.Serialization;

public class Character : MonoBehaviour
{
    [SerializeField]
    [FormerlySerializedAs("maxLives")]
    private int maxHealth;
}

Se você voltar ao editor após salva o script, verá que o campo no inspetor continua com o mesmo valor.

Também podemos usar o atributo várias vezes para a mesma variável.

using UnityEngine;
using UnityEngine.Serialization;

public class Character : MonoBehaviour
{
    [SerializeField]
    [FormerlySerializedAs("maxLives")]
    [FormerlySerializedAs("maxHealth")]
    private int maxHitPoints;
}

Como o valor no editor só é atualizado quando a Unity faz a desserialização, é importante manter a variável com o atributo para evitar perda de dados. Por exemplo, se adicionamos nosso script a dois GameObject em cenas diferentes. Então renomeamos a variável e usamos o atributo FormerlySerializedAs. Voltamos ao editor e na primeira cena o valor estará correto. Agora sem abrir a segunda cena, removemos o atributo da variável. Voltamos novamente ao editor e abrimos a segunda cena e o valor será o padrão.

Conclusão

Usamos o atributo FormerlySerializedAs para manter os dados que a Unity já tinha serializado quando renomeamos uma variável. Com isso podemos refatorar nosso código fonte sem medo de perder o trabalho que tivemos para configurar os componentes que criamos.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *