我有一个问题。我刚刚找到了C#Scripts的Unitys Script模板。
要获取脚本名称,请编写#SCRIPTNAME#
,使其看起来像这样:
using UnityEngine;
using System.Collections;
public class #SCRIPTNAME# : MonoBehaviour
{
void Start ()
{
}
void Update ()
{
}
}
它会创建具有正确名称的脚本,但有没有像#FOLDERNAME那样的东西#所以我可以在创建脚本时直接将它放在正确的命名空间中?
答案 0 :(得分:5)
没有内置的模板变量,例如 #FOLDERNAME#。
根据this post,只有3个魔术变量。
但是你总是可以挂钩脚本的创建过程并使用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()
{
}
}
}