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.