首页 >Unity3D频道 >【Unity杂文】 > Unity3D研究院之脚本自动添加tag和Layer
2014
09-04

Unity3D研究院之脚本自动添加tag和Layer

有朋友问我他做了一个unity游戏插件,但是它的插件里面自定义了自己的tag和layer。这样用户在导入他的unitypackage的时候如果项目里没有写入它的tag或者layer那么就会有错误,所以他希望在导入unitypackage的时候自定把它的tag或者layer写进用户的项目里。

把下面这条脚本,随着你的资源一起打包,这样当你的unitypackage被别人导入的时候,程序就会调用AddTag和AddLayer来添加。因为有可能你的项目里已经添加了这个tag或者layer所以在添加之前我做了一个判断,判断项目是否已经存在了这个tag。

using System;
using System.Collections;
using System.Reflection;
using UnityEditor;
using UnityEngine;

public class NewBehaviourScript :AssetPostprocessor
{

	static void OnPostprocessAllAssets (string[] importedAssets, string[] deletedAssets,string[] movedAssets, string[] movedFromAssetPaths) 
	{
		foreach(string s in importedAssets)
		{
			if (s.Equals("Assets/NewBehaviourScript.cs"))
			{
				//增加一个叫momo的tag
				AddTag("momo");
				//增加一个叫ruoruo的layer
				AddLayer("ruoruo");
				return ;
			}
		}   
	}

	static void AddTag(string tag)
	{
		if(!isHasTag(tag))
		{
			SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
			SerializedProperty it = tagManager.GetIterator();
			while (it.NextVisible(true))
			{
				if(it.name == "tags")
				{
					for (int i = 0; i < it.arraySize; i++) 
					{ 
						SerializedProperty dataPoint = it.GetArrayElementAtIndex(i);
						if(string.IsNullOrEmpty(dataPoint.stringValue)){
							dataPoint.stringValue = tag;
							tagManager.ApplyModifiedProperties();
							return;
						}
					}
				}
			}
		}
	}

	static void AddLayer(string layer)
	{
		if(!isHasLayer(layer))
		{
			SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
			SerializedProperty it = tagManager.GetIterator();
			while (it.NextVisible(true))
			{
				if(it.name.StartsWith("User Layer"))
				{
					if(it.type == "string" )
					{
						if(string.IsNullOrEmpty(it.stringValue)){
							it.stringValue  = layer;
							tagManager.ApplyModifiedProperties();
							return;
						}
					}
				}
			}
		}
	}

	static bool isHasTag(string tag)
	{
		for (int i = 0; i < UnityEditorInternal.InternalEditorUtility.tags.Length; i++) {
			if (UnityEditorInternal.InternalEditorUtility.tags[i].Contains(tag))
				return true;
		}
		return false;
	}

	static bool isHasLayer(string layer)
	{
		for (int i = 0; i < UnityEditorInternal.InternalEditorUtility.layers.Length; i++) {
			if (UnityEditorInternal.InternalEditorUtility.layers[i].Contains(layer))
				return true;
		}
		return false;
	}
}

OK然后就是导入你的unitypackage

Snip20140904_6

倒入完毕后,新增加的tag和layer就都保存进去了。

Snip20140904_5

 

代码其实不难,如果你想同时导入多个tag或者layer,简单的拓展一下方法传入不固定参数即可。最近MOMO好累呀!希望痛苦的日子赶快过去。。555555555

最后编辑:
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!

Unity3D研究院之脚本自动添加tag和Layer》有 23 条评论

  1. 刘洋说:

    if(it.name == “tags”)和if(it.name.StartsWith(“User Layer”))和if(it.type == “string” )
    这三个后面是否加入return;

    另外我这里这样才好用:
    if (it.name == “tags”)
    {
    bool bFindTag = false;
    int i = 0;
    // 先找空的
    for (i = 0; i < it.arraySize; i++)
    {
    SerializedProperty property = it.GetArrayElementAtIndex(i);
    if (string.IsNullOrEmpty(property.stringValue))
    {
    property.stringValue = _sTag;
    TagManager.ApplyModifiedProperties();
    bFindTag = true;
    return;
    }
    }
    if (!bFindTag)
    {
    // 其次插入
    it.InsertArrayElementAtIndex(i);
    SerializedProperty property = it.GetArrayElementAtIndex(i);
    property.stringValue = _sTag;
    TagManager.ApplyModifiedProperties();
    return;
    }
    return;
    }

    一直关注您,非常感谢

  2. xfc说:

    AssetPostprocessor.OnPostprocessAllAssets 当导入的资源超过65个的时候(文件夹也算),该方法会重新执行一遍。有什么办法解决这个问题呢

  3. x682510说:

    请问有什么方法可以获得某一层的所有物体?

  4. 请问怎么添加的SortingLayer

  5. forTy说:

    MOMO你好,这个是静态添加tag和layer的方法,看起来很方便。那么有木有办法能让我在脚本运行的过程中,动态添加tag呢?

  6. 王致远说:

    是不是应该用Equals而不是Contains?

  7. 很有用啊~~~~~~~说:

    很有用啊~~~~~~~

  8. 时念阳c说:

    大爱!!!!!我是你编写的Unity 3D学习者! 我要想你一样! 奋斗ing!

留下一个回复

你的email不会被公开。 必填项已用 * 标注。