首页 > 解决方案 > 如何统一使用脚本创建新图层

问题描述

我需要遍历所有现有图层名称并查找我的图层是否存在的函数,如果没有,则代码需要将给定图层添加到图层列表

我在这个统一论坛上试过这个代码

    void CreateLayer()
{
    SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);

    SerializedProperty layers = tagManager.FindProperty("layers");
    if (layers == null || !layers.isArray)
    {
        Debug.LogWarning("Can't set up the layers.  It's possible the format of the layers and tags data has changed in this version of Unity.");
        Debug.LogWarning("Layers is null: " + (layers == null));
        return;
    }

    for (int i = 8; i < 31; i++)
    {
        SerializedProperty layerSP = layers.GetArrayElementAtIndex(i);
        if (layerSP.stringValue == "MyLayer")
        {
            return;
        }
    }

    for (int i = 8; i < 31; i++)
    {
        SerializedProperty layerSP = layers.GetArrayElementAtIndex(i);
        if (layerSP.stringValue != "")
        {
            layerSP.stringValue = "MyLayer";
            break;
        }
    }

    tagManager.ApplyModifiedProperties();
}

但这对我不起作用

顺便说一句,我正在使用统一 5.6.3

如果有人知道答案,请分享

标签: c#unity3d

解决方案


我在这里发现了这个这个答案只在编辑器中有效,在构建中无效

创建一个新的 c# 脚本,将此代码添加到其中

using UnityEngine;
using System.Collections;

public class Layers
{
private static int maxTags = 10000;
private static int maxLayers = 31;

/////////////////////////////////////////////////////////////////////

public void AddNewLayer(string name)
{
    CreateLayer(name);
}

public void DeleteLayer(string name)
{
    RemoveLayer(name);
}


////////////////////////////////////////////////////////////////////


/// <summary>
/// Adds the layer.
/// </summary>
/// <returns><c>true</c>, if layer was added, <c>false</c> otherwise.</returns>
/// <param name="layerName">Layer name.</param>
public static bool CreateLayer(string layerName)
{
    // Open tag manager
    SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
    // Layers Property
    SerializedProperty layersProp = tagManager.FindProperty("layers");
    if (!PropertyExists(layersProp, 0, maxLayers, layerName))
    {
        SerializedProperty sp;
        // Start at layer 9th index -> 8 (zero based) => first 8 reserved for unity / greyed out
        for (int i = 8, j = maxLayers; i < j; i++)
        {
            sp = layersProp.GetArrayElementAtIndex(i);
            if (sp.stringValue == "")
            {
                // Assign string value to layer
                sp.stringValue = layerName;
                Debug.Log("Layer: " + layerName + " has been added");
                // Save settings
                tagManager.ApplyModifiedProperties();
                return true;
            }
            if (i == j)
                Debug.Log("All allowed layers have been filled");
        }
    }
    else
    {
        //Debug.Log ("Layer: " + layerName + " already exists");
    }
    return false;
}

public static string NewLayer(string name)
{
    if (name != null || name != "")
    {
        CreateLayer(name);
    }

    return name;
}

/// <summary>
/// Removes the layer.
/// </summary>
/// <returns><c>true</c>, if layer was removed, <c>false</c> otherwise.</returns>
/// <param name="layerName">Layer name.</param>
public static bool RemoveLayer(string layerName)
{

    // Open tag manager
    SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);

    // Tags Property
    SerializedProperty layersProp = tagManager.FindProperty("layers");

    if (PropertyExists(layersProp, 0, layersProp.arraySize, layerName))
    {
        SerializedProperty sp;

        for (int i = 0, j = layersProp.arraySize; i < j; i++)
        {

            sp = layersProp.GetArrayElementAtIndex(i);

            if (sp.stringValue == layerName)
            {
                sp.stringValue = "";
                Debug.Log("Layer: " + layerName + " has been removed");
                // Save settings
                tagManager.ApplyModifiedProperties();
                return true;
            }

        }
    }

    return false;

}
/// <summary>
/// Checks to see if layer exists.
/// </summary>
/// <returns><c>true</c>, if layer exists, <c>false</c> otherwise.</returns>
/// <param name="layerName">Layer name.</param>
public static bool LayerExists(string layerName)
{
    // Open tag manager
    SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);

    // Layers Property
    SerializedProperty layersProp = tagManager.FindProperty("layers");
    return PropertyExists(layersProp, 0, maxLayers, layerName);
}
/// <summary>
/// Checks if the value exists in the property.
/// </summary>
/// <returns><c>true</c>, if exists was propertyed, <c>false</c> otherwise.</returns>
/// <param name="property">Property.</param>
/// <param name="start">Start.</param>
/// <param name="end">End.</param>
/// <param name="value">Value.</param>
private static bool PropertyExists(SerializedProperty property, int start, int end, string value)
{
    for (int i = start; i < end; i++)
    {
        SerializedProperty t = property.GetArrayElementAtIndex(i);
        if (t.stringValue.Equals(value))
        {
            return true;
        }
    }
    return false;
}
}

并创建一个图层

new Layers().AddNewLayer("PP");

推荐阅读