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

sf6xfgos  于 2023-02-05  发布在  其他
关注(0)|答案(6)|浏览(382)

我刚刚找到了Unity的C#脚本模板。要获得脚本名称,请编写#SCRIPTNAME#,如下所示:

using UnityEngine;
using System.Collections;

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

然后,它将创建具有正确名称的脚本,但是否存在类似#FOLDERNAME#的名称,以便在创建脚本时可以直接将其放入正确的名称空间?

kqlmhetl

kqlmhetl1#

没有类似 #FOLDERNAME# 的内置模板变量。
根据this post,只有3个魔术变量。

  • “#姓名#”
  • “#脚本名称#”
  • “#脚本名称_下限#”

但是,您始终可以挂钩到脚本的创建过程,并使用AssetModificationProcessor自己附加名称空间。
下面是一个向创建的脚本添加一些自定义数据的示例。

//Assets/Editor/KeywordReplace.cs
using UnityEngine;
using UnityEditor;
using System.Collections;

public class KeywordReplace : UnityEditor.AssetModificationProcessor
{

   public static void OnWillCreateAsset ( string path )
   {
     path = path.Replace( ".meta", "" );
     int index = path.LastIndexOf( "." );
     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 );

     file = file.Replace( "#CREATIONDATE#", System.DateTime.Now + "" );
     file = file.Replace( "#PROJECTNAME#", PlayerSettings.productName );
     file = file.Replace( "#SMARTDEVELOPERS#", PlayerSettings.companyName );

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

xvw2m8pv2#

我知道这是一个老问题,但是在Unity的新版本中,你可以定义一个根命名空间来在项目中使用。你可以在编辑〉项目设置〉编辑器〉根命名空间中定义命名空间
这样做将在新创建的脚本上添加定义的命名空间。

mrphzbgm

mrphzbgm3#

使用zwcloud的答案和some other resources,我能够在脚本文件上生成一个名称空间:
第一步,导航:
Unity的默认模板可以在Unity安装目录下找到,Windows为Editor\Data\Resources\ScriptTemplates,OSX为/Contents/Resources/ScriptTemplates
然后打开文件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#脚本来测试它,它将生成我们创建的新名称空间定义。

prdp8dxp

prdp8dxp4#

我很清楚这个问题已经被一些很棒的人(zwcloud、Darco18和Alexey)回答了,但是,由于我的命名空间组织遵循项目中的文件夹结构,我很快就对代码做了一些小的修改,我在这里分享它,以防有人需要它,并且有与我相同的组织方法。
请记住,您需要在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();
            }
        }
    }
sqserrrh

sqserrrh5#

好了,这个问题已经被两个很棒的人回答了,zwcloud和Draco18s,他们的解决方案是有效的,我只是展示了相同代码的另一个版本,我希望,会更清楚地说明到底发生了什么。
快速注解:

  • 是的,在这个方法中,我们获取的不是实际的文件路径,而是其 meta文件的路径作为参数
  • 不可以,您不能使用没有UnityEditor前缀的AssetModificationProcessor,它已过时
  • 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)}{Path.DirectorySeparatorChar}{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()
        {
            
        }
    }
}
vd2z7a6w

vd2z7a6w6#

这是我的解决方案,在我的案例中,Unity在OnWillCreateAsset()之前添加了根名称空间,因此我必须用我想要的名称空间替换脚本中的根名称空间。
下面是代码

public class AddNameSpace : UnityEditor.AssetModificationProcessor
{
  public static void OnWillCreateAsset(string path)
  {
    var rootNamespace =        
  string.IsNullOrWhiteSpace(EditorSettings.projectGenerationRootNamespace) ?
        string.Empty : $"{EditorSettings.projectGenerationRootNamespace}";

    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;

    string formattedNamespace = GetNamespace(path, rootNamespace);
    file = System.IO.File.ReadAllText(path);
    if (file.Contains(formattedNamespace))
        return;

    file = file.Replace(rootNamespace, formattedNamespace);

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

  private static string GetNamespace(string filePath, string rootNamespace)
  {
    filePath = filePath.Replace("Assets/Scripts/", "/")
        .Replace('/', '.')
        .Replace(' '.ToString(), string.Empty);

    var splitPath = filePath.Split('.');
    string pathWithoutFileName = string.Empty;

    for (int i = 1; i < splitPath.Length - 2; i++)
    {
        if (i == splitPath.Length - 3)
        {
            pathWithoutFileName += splitPath[i];
        }
        else
        {
            pathWithoutFileName += splitPath[i] + '.';
        }
    }

    return $"{rootNamespace}.{pathWithoutFileName}";
  }

}

相关问题