在项目开发中我们可以对诸如Layer、Tag等编辑器数据进行常量生成,来代替在代码中通过输入字符串生成常量的形式以提高开发效率。
Layer的生成可以通过LayerMask.LayerToName获取层名称(也可以从TagManager.asset中获得 ),Tag的生成可以手动将预制Tag标签写入常量列表,其他的自定义Tag可以从TagManager.asset中获得。
一、基本知识
1.unity预制Tag标签

TagManager.asset
文件如下方所示。unity预制的Tag标签(如Respawn、Finish、EditorOnly等6个Tag)并没有在TagManager.asset
文件中。
cs
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!78 &1
TagManager:
serializedVersion: 2
tags:
- Test
layers:
- Default
- TransparentFX
- Ignore Raycast
-
- Water
- UI
- TestLayer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
m_SortingLayers:
- name: Default
uniqueID: 0
locked: 0
2.Layer层
在Unity中,Layer机制是固定的,最多只能有32个Layer。这是由Unity的底层设计决定的,因为Layer是用一个32位的整型来表示的,每一位表示一个Layer。
二、工具
cs
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
public class LayerManager : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
var sb = new StringBuilder(); //准备模板生成
sb.AppendLine("public class _Const");
sb.AppendLine("{");
for (int i = 0; i < 32; i++) //遍历所有Layer
{
var name = LayerMask.LayerToName(i); //通过Unity的接口拿到Layer名称
name = name
.Replace(" ", "_")
.Replace("&", "_")
.Replace("/", "_")
.Replace(".", "_")
.Replace(",", "_")
.Replace(";", "_")
.Replace("%", "_")
.Replace("-", "_"); //对常见的特殊字符进行过滤
Debug.Log(name);
if (!string.IsNullOrEmpty(name))
sb.AppendFormat("\tpublic const int LAYER_{0} = {1};\n", name.ToUpper(), i);
}
sb.AppendLine("\tpublic const string " + ("Tag_Untagged".ToUpper() + " = " + "\"Untagged\";"));
sb.AppendLine("\tpublic const string " + ("Tag_Respawn".ToUpper() + " = " + "\"Respawn\";"));
sb.AppendLine("\tpublic const string " + ("Tag_Finish".ToUpper() + " = " + "\"Finish\";"));
sb.AppendLine("\tpublic const string " + ("Tag_EditorOnly".ToUpper() + " = " + "\"EditorOnly\";"));
sb.AppendLine("\tpublic const string " + ("Tag_MainCamera".ToUpper() + " = " + "\"MainCamera\";"));
sb.AppendLine("\tpublic const string " + ("Tag_Player".ToUpper() + " = " + "\"Player\";"));
sb.AppendLine("\tpublic const string " + ("Tag_GameController".ToUpper() + " = " + "\"GameController\";")); //把一部分内置Tag先写死
var asset = UnityEditor.AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset"); //取得自定义Tag
if ((asset != null) && (asset.Length > 0))
{
Debug.Log(asset.Length);
for (int i = 0; i < asset.Length; i++)
{
//创建序列化对象
var so = new UnityEditor.SerializedObject(asset[i]);
var tags = so.FindProperty("tags"); //读取具体字段
for (int j = 0; j < tags.arraySize; ++j)
{
var item = tags.GetArrayElementAtIndex(j).stringValue;
sb.AppendFormat("\tpublic const string TAG_{0} = \"{1}\";\n", item.ToUpper(), item);
} //添加到模板
//获取Layer的方法二
// var layers = so.FindProperty("layers");
// for (int j = 0; j < layers.arraySize; ++j)
// {
// var item = layers.GetArrayElementAtIndex(j).stringValue;
// if (!string.IsNullOrEmpty(item))
// sb.AppendFormat("\tpublic const int LAYER_{0} = {1};\n", item.ToUpper(), j);
// }
}
}
sb.AppendLine("}");
File.WriteAllText("Assets/GeneratedConst.cs", sb.ToString()); //写入硬盘
UnityEditor.AssetDatabase.Refresh(); //通知Unity刷新
}
}
三、生成的代码
cs
public class _Const
{
public const int LAYER_DEFAULT = 0;
public const int LAYER_TRANSPARENTFX = 1;
public const int LAYER_IGNORE_RAYCAST = 2;
public const int LAYER_WATER = 4;
public const int LAYER_UI = 5;
public const int LAYER_TESTLAYER = 6;
public const string TAG_UNTAGGED = "Untagged";
public const string TAG_RESPAWN = "Respawn";
public const string TAG_FINISH = "Finish";
public const string TAG_EDITORONLY = "EditorOnly";
public const string TAG_MAINCAMERA = "MainCamera";
public const string TAG_PLAYER = "Player";
public const string TAG_GAMECONTROLLER = "GameController";
public const string TAG_TEST = "Test";
}