Unity将默认命名空间添加到脚本模板?

时间:2016-09-13 03:31:14

标签: c# unity3d

我有一个问题。我刚刚找到了C#Scripts的Unitys Script模板。 要获取脚本名称,请编写#SCRIPTNAME#,使其看起来像这样:

using UnityEngine;
using System.Collections;

public class #SCRIPTNAME# : MonoBehaviour 
{
    void Start () 
    {

    }

    void Update () 
    {

    }
}

它会创建具有正确名称的脚本,但有没有像#FOLDERNAME那样的东西#所以我可以在创建脚本时直接将它放在正确的命名空间中?

4 个答案:

答案 0 :(得分:5)

没有内置的模板变量,例如 #FOLDERNAME#

根据this post,只有3个魔术变量。

  • “#NAME#”
  • “#SCRIPTNAME#”
  • “#SCRIPTNAME_LOWER#”

但是你总是可以挂钩脚本的创建过程并使用AssetModificationProcessor自己附加命名空间。

Here是一个向创建的脚本添加一些自定义数据的示例。

f :: Int -> Int
f x = x + 1

r = f

答案 1 :(得分:3)

我很清楚,这个问题已经得到了很棒的人(zwcloud,Darco18和Alexey)的回答。 但是,由于我的命名空间组织遵循项目中的文件夹结构,因此我对代码进行了一些小的修改,如果有人需要它并且具有与我相同的组织方法,我将在此处共享它。 m以下。

请记住,您需要在 C#项目生成部分项目设置中设置根命名空间。 编辑:我已经对代码进行了一些调整,使其可以放置在脚本,编辑器等的根文件夹中。

public class NamespaceResolver : UnityEditor.AssetModificationProcessor 
    {
        public static void OnWillCreateAsset(string metaFilePath)
        {
            var fileName = Path.GetFileNameWithoutExtension(metaFilePath);

            if (!fileName.EndsWith(".cs"))
                return;

            var actualFile = $"{Path.GetDirectoryName(metaFilePath)}\\{fileName}";
            var segmentedPath = $"{Path.GetDirectoryName(metaFilePath)}".Split(new[] { '\\' }, StringSplitOptions.None);

            var generatedNamespace = "";
            var finalNamespace = "";

            // In case of placing the class at the root of a folder such as (Editor, Scripts, etc...)  
            if (segmentedPath.Length <= 2)
                finalNamespace = EditorSettings.projectGenerationRootNamespace;
            else
            {
                // Skipping the Assets folder and a single subfolder (i.e. Scripts, Editor, Plugins, etc...)
                for (var i = 2; i < segmentedPath.Length; i++)
                {
                    generatedNamespace +=
                        i == segmentedPath.Length - 1
                            ? segmentedPath[i]
                            : segmentedPath[i] + "."; // Don't add '.' at the end of the namespace
                }
                
                finalNamespace = EditorSettings.projectGenerationRootNamespace + "." + generatedNamespace;
            }
            
            var content = File.ReadAllText(actualFile);
            var newContent = content.Replace("#NAMESPACE#", finalNamespace);

            if (content != newContent)
            {
                File.WriteAllText(actualFile, newContent);
                AssetDatabase.Refresh();
            }
        }
    }

答案 2 :(得分:1)

使用zwcloud的答案和some other resources,我可以在脚本文件中生成一个名称空间:

第一步,导航:

  

在Windows的Editor\Data\Resources\ScriptTemplates和OSX的/Contents/Resources/ScriptTemplates的Unity安装目录下可以找到Unity的默认模板。

并打开文件81-C# Script-NewBehaviourScript.cs.txt

并进行以下更改:

namespace #NAMESPACE# {

在顶部和

}

在底部。缩进其余部分,以便根据需要保留空白。暂时不要保存。如果需要,您可以对模板进行其他更改,例如删除默认注释,进行Update()Start() private,甚至完全删除它们。

再次,请不要保存此文件,否则Unity会在下一步中引发错误。如果已保存,只需按ctrl-Z撤消然后重新保存,然后按ctrl-Y重新应用更改。

现在,在Unity Assets目录内的Editor文件夹内创建一个新脚本,并将其命名为AddNameSpace。用以下内容替换内容:

using UnityEngine;
using UnityEditor;

public class AddNameSpace : UnityEditor.AssetModificationProcessor {

    public static void OnWillCreateAsset(string path) {
        path = path.Replace(".meta", "");
        int index = path.LastIndexOf(".");
        if(index < 0) return;
        string file = path.Substring(index);
        if(file != ".cs" && file != ".js" && file != ".boo") return;
        index = Application.dataPath.LastIndexOf("Assets");
        path = Application.dataPath.Substring(0, index) + path;
        file = System.IO.File.ReadAllText(path);

        string lastPart = path.Substring(path.IndexOf("Assets"));
        string _namespace = lastPart.Substring(0, lastPart.LastIndexOf('/'));
        _namespace = _namespace.Replace('/', '.');
        file = file.Replace("#NAMESPACE#", _namespace);

        System.IO.File.WriteAllText(path, file);
        AssetDatabase.Refresh();
    }
}

保存此脚本以及将更改保存到81-C# Script-NewBehaviourScript.cs.txt

您完成了!您可以通过在Assets中任何一系列文件夹中创建一个新的C#脚本来对其进行测试,它将生成我们创建的新名称空间定义。

答案 3 :(得分:0)

好的,所以这个问题已经由两个很棒的人zwcloud和Draco18s回答了,他们的解决方案起作用了,我只是在展示相同代码的另一个版本,希望在以下方面可以使您更加清楚:到底发生了什么。

快速笔记:

  • 是的,通过这种方法,我们得到的不是实际的文件路径, 但是其元文件的路径作为参数

  • 否,没有AssetModificationProcessor前缀的UnityEditor不能使用,已弃用

  • OnWillCreateAsset方法不会通过Ctrl + Shift + M,“覆盖”键入或基类元数据显示

_

using UnityEditor;
using System.IO;

public class ScriptTemplateKeywordReplacer : UnityEditor.AssetModificationProcessor
{
    //If there would be more than one keyword to replace, add a Dictionary

    public static void OnWillCreateAsset(string metaFilePath)
    {
        string fileName = Path.GetFileNameWithoutExtension(metaFilePath);

        if (!fileName.EndsWith(".cs"))
            return;


        string actualFilePath = $"{Path.GetDirectoryName(metaFilePath)}\\{fileName}";

        string content = File.ReadAllText(actualFilePath);
        string newcontent = content.Replace("#PROJECTNAME#", PlayerSettings.productName);

        if (content != newcontent)
        {
            File.WriteAllText(actualFilePath, newcontent);
            AssetDatabase.Refresh();
        }
    }
}

这是我文件c:\Program Files\Unity\Editor\Data\Resources\ScriptTemplates\81-C# Script-NewBehaviourScript.cs.txt

的内容
using UnityEngine;

namespace #PROJECTNAME#
{

    public class #SCRIPTNAME# : MonoBehaviour
    {
        // Start is called before the first frame update
        void Start()
        {

        }

        // Update is called once per frame
        void Update()
        {

        }
    }
}