【Unity小知识】自动创建文件总结

        在新开发一个UI模块的时候,往往需要连带的创建包括Script、Prefab、Atlas等一系列的文件和目录。这些文件的目录结构、命名格式往往都比较统一,所以我们可以编写自定义程序一键生成,即可以快速高效的创建文件,也避免了手动创建过程中可以出现的命名不规范、单词拼写错误、目录路径创建错误等不必要的小麻烦。

        自动创建Script

using UnityEngine;
using UnityEditor;
using System.IO;
using System.Text;

public class GenerateScript : EditorWindow
{
    [MenuItem("EditorTools/GenerateScript")]
    public static void ShowCustomEditorWindow()
    {
        string directoryPath = Application.dataPath + "/Script";
        if (!Directory.Exists(directoryPath))
            Directory.CreateDirectory(directoryPath);

        string filePath = directoryPath + "/Script.cs";
        FileStream fileStream = File.Create(filePath);

        string content = @"
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CustomScript : MonoBehaviour
{
    public void Start()
    {
    }
}
";
        byte[] byteArray = Encoding.UTF8.GetBytes(content);
        fileStream.Write(byteArray, 0, byteArray.Length);
        fileStream.Close();

        AssetDatabase.Refresh();
    }
}

创建Script主要使用的是C#中的File类,本质就是用File类创建一个后缀名为.cs的文本文件。

上面是一个简单的示例,在项目工程Script目录下创建了一个Script.cs脚本。

Directory类用于创建文件目录,File.Create创建FileStream类,FileStream类负责具体的文件写入操作。这里需要注意的是content的编写,content所编写的内容就是最后生成的.cs文件中的代码。为了方便多行编写,这里使用了@符号。

相关文档连接:

Directory类文档连接:https://learn.microsoft.com/zh-cn/dotnet/api/system.io.directory?view=net-7.0

File类文档连接:https://learn.microsoft.com/zh-cn/dotnet/api/system.io.file?view=net-7.0

FileStream类文档连接:https://learn.microsoft.com/zh-cn/dotnet/api/system.io.filestream?view=net-7.0

        自动创建Prefab

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

public class GeneratePrefab : EditorWindow
{
    [MenuItem("EditorTools/GeneratePrefab")]
    public static void ShowCustomEditorWindow()
    {
        if (!EditorApplication.isCompiling)
            GeneratePrefabAsyn();
    }

    [UnityEditor.Callbacks.DidReloadScripts]
    private static void GeneratePrefabAsyn()
    {
        Assembly assembly = AppDomain.CurrentDomain.Load("Assembly-CSharp");
        Type type = assembly.GetType("CustomScript");
        if (type != null)
        {
            GameObject instanceGameObject = new GameObject("CustomPrefab");
            Component component = instanceGameObject.AddComponent(type);
            PrefabUtility.SaveAsPrefabAsset(instanceGameObject, "Assets/CustomPrefab.prefab");
            GameObject.DestroyImmediate(instanceGameObject, true);
        }
    }
}

这一部分是自动创建Prefab,并绑定之前自动创建的Script。

这里有两个坑是需要特别注意的。

第一个是项目脚本中的类是在Assembly-CSharp程序集下的,而编辑器脚本中的类是在Assembly-CSharp-Editor程序集下的。所以需要先通过AppDomain.CurrentDomain.Load("Assembly-CSharp")方法获取Assembly-CSharp程序集,然后在通过assembly.GetType("CustomScript")方法获取类型。

第二个是当新创建Script时Unity会重新编译Assembly-CSharp程序集,所以在Prefab上绑定新的Script需要等待Unity把程序集编译完成。EditorApplication.isCompiling可以判断当前编辑器是否在编译脚本。[UnityEditor.Callbacks.DidReloadScripts] 则用于指定Script加载完成后的回调,需要注意的是回调必须是静态方法。

最后的话则是使用 PrefabUtility.SaveAsPrefabAsset 方法将创建的Prefab保存到指定路径。

相关文档连接:

Assembly文档连接:https://learn.microsoft.com/zh-cn/dotnet/api/system.reflection.assembly?view=net-7.0

DidReloadScripts文档连接:https://docs.unity3d.com/cn/2022.2/ScriptReference/Callbacks.DidReloadScripts.html

PrefabUtility文档连接:https://docs.unity3d.com/cn/2022.2/ScriptReference/PrefabUtility.html

        自动生成SpriteAtlas

using UnityEngine;
using UnityEngine.U2D;
using UnityEditor;
using UnityEditor.U2D;
using System.IO;


public class GenerateScript : EditorWindow
{
    [MenuItem("EditorTools/GenerateSpriteAtlas")]
    public static void ShowCustomEditorWindow()
    {
        string directoryPath = Application.dataPath + "/SpriteAtlas";
        if (!Directory.Exists(directoryPath))
            Directory.CreateDirectory(directoryPath);

        SpriteAtlas spriteAtlas = new SpriteAtlas();
        SpriteAtlasPackingSettings packSetting = new SpriteAtlasPackingSettings()
        {
            blockOffset = 1,
            enableRotation = false,
            enableTightPacking = false,
            padding = 4,
        };
        spriteAtlas.SetPackingSettings(packSetting);

        string localPath = directoryPath + "/SpriteAtlasName.spriteatlas";
        AssetDatabase.CreateAsset(spriteAtlas, localPath);
        AssetDatabase.Refresh();
    }
}

首先还是使用new SpriteAtlas方法来创建对象。对于SpriteAtlas对象的参数设置需要用到SpriteAtlasPackingSettings类,上面的示例只进行了简单设置,更多参数设置可以查阅文档。参数设置完成之后通过AssetDatabase.CreateAsset方法保存SpriteAtlas对象。

SpriteAtlas文档连接:https://docs.unity3d.com/cn/2022.2/ScriptReference/U2D.SpriteAtlas.html

SpriteAtlasPackingSettings文档连接:https://docs.unity3d.com/cn/2022.2/ScriptReference/U2D.SpriteAtlasPackingSettings.html

你可能感兴趣的:(unity,c#,游戏引擎)