【问题标题】:Unity Add Default Namespace to Script Template?Unity将默认命名空间添加到脚本模板?
【发布时间】:2016-09-13 03:31:13
【问题描述】:

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

using UnityEngine;
using System.Collections;

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

然后它会创建具有正确名称的脚本,但是有没有类似#FOLDERNAME# 这样我可以在创建脚本时直接将它放在正确的命名空间中?

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    没有像#FOLDERNAME#这样的内置模板变量。

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

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

    但您始终可以使用 AssetModificationProcessor 自行连接到脚本的创建过程并附加命名空间。

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

    //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();
       }
    }
    

    【讨论】:

    • 在 2017 Unity C# 模板中,还有#NOTRIM#。有什么用?
    • @AlanMattano #NOTRIM# 表示在使用模板时该行应保留为空行。 'No Trim',意思是不要修剪这个空白行。
    【解决方案2】:

    使用 zwcloud 的回答和 some other resources 我能够在我的脚本文件上生成一个命名空间:

    第一步,导航:

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

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

    并进行以下更改:

    namespace #NAMESPACE# {
    

    在顶部和

    }
    

    在底部。缩进其余部分,以便空格符合需要。暂时不要保存这个。如果您愿意,您可以对模板进行其他更改,例如删除默认的 cmets、制作 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】:

      我很清楚这个问题已经得到了很棒的人(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();
                  }
              }
          }
      

      【讨论】:

        【解决方案4】:

        我知道这是个老问题,但在较新版本的 Unity 中,您可以定义要在项目中使用的根命名空间。 您可以在 Edit > Project Settings > Editor > Root Namespace 中定义命名空间

        这样做会在新创建的脚本上添加定义的命名空间。

        【讨论】:

        • 你也可以将命名空间添加到你要使用的程序集中,这个程序集中所有新创建的文件都会有程序集命名空间
        【解决方案5】:

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

        快速笔记:

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

        • 不,你不能使用没有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()
                {
                    
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-07-18
          • 1970-01-01
          • 2011-03-15
          • 1970-01-01
          • 2016-11-25
          • 1970-01-01
          • 1970-01-01
          • 2013-03-02
          相关资源
          最近更新 更多