Unity | Tag、Layer常量类生成工具

在项目开发中我们可以对诸如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";
}
相关推荐
技术小甜甜4 小时前
[Godot] 解决导出APK安装失败的常见问题:深入分析与调试方法
游戏引擎·godot·游戏开发
老朱佩琪!8 小时前
Unity桥接模式
unity·设计模式·c#·桥接模式
技术小甜甜8 小时前
[Godot][入门] 安装与版本选择:3.x 还是 4.x?(按项目类型一键决策)
游戏引擎·godot·游戏开发·2d
陈言必行8 小时前
Unity 之 物理引擎中三种刚体力施加方式详解
unity·游戏引擎
foreveryao1238 小时前
Unity渲染流程(底层逻辑)
unity·游戏引擎·图形渲染
small-pudding9 小时前
Unity中的PBR(基于物理的渲染)
unity·游戏引擎
CreasyChan9 小时前
3D游戏数学基础指南
游戏·3d·unity·数学基础
平行云1 天前
Enscape × Paraverse | 从设计到一键发布、网页分享、实时交互的全新体验
unity·ue5·xr·3dsmax·webgl·实时云渲染·云桌面
老朱佩琪!1 天前
Unity迭代器模式
unity·设计模式·迭代器模式
程序猿多布1 天前
Unity 多语言系统实现
unity·多语言