Unity3d 我能在没有项目设置的c代码中定义一个常量解决方案吗?
我知道这是一个aksed,并回答了几次。 ,及 但就我而言,我不能使用任何建议的方法: 我正在为UnityProjects(一种提供特定功能的包)编写不同的“模块”(或者插件,如果您愿意的话)。其思想是,开发人员可以通过导入包含所有脚本和资源的Unity3d 我能在没有项目设置的c代码中定义一个常量解决方案吗?,unity3d,c-preprocessor,constants,global,conditional-compilation,Unity3d,C Preprocessor,Constants,Global,Conditional Compilation,我知道这是一个aksed,并回答了几次。 ,及 但就我而言,我不能使用任何建议的方法: 我正在为UnityProjects(一种提供特定功能的包)编写不同的“模块”(或者插件,如果您愿意的话)。其思想是,开发人员可以通过导入包含所有脚本和资源的UnityPackage,加载某个“模块”以在其项目中使用 但其中一些模块本身依赖于其他模块。因此,到目前为止,我尝试的是在每个模块中使用一个类Constants,该类具有独立的名称空间和预处理器定义 模块A #如果!模块A #定义模块_A//但我不仅在这
UnityPackage
,加载某个“模块”以在其项目中使用
但其中一些模块本身依赖于其他模块。因此,到目前为止,我尝试的是在每个模块中使用一个类Constants
,该类具有独立的名称空间和预处理器定义
模块A
#如果!模块A
#定义模块_A//但我不仅在这里需要这个全局
#恩迪夫
名称空间模块
{
公共静态类常量
{
//此处是此命名空间的一些常量
}
}
模块B
#如果!模块B
#定义模块_B//但我不仅在这里需要这个全局
#恩迪夫
#如果!模块A//当然不会被定义,因为#define不是全局的
#错误模块A丢失!
#否则
名称空间模块
{
公共静态类常量
{
//此处是此命名空间的一些常量
}
//以及其他可能需要模块A的代码
}
#恩迪夫
但当然,这不能像这样工作,因为#define
不是全局的,而是仅在当前文件中
问题
对于模块的整个概念和简单的“加载您的模块”,我不能要求用户首先对项目或解决方案设置进行更改(例如建议),而是必须仅使用随UnityPackage导入的(c#)资源(至少使用我目前的专有技术)
是否有任何方法可以通过仅导入模块的UnityPackage来为整个Unity项目设置/定义这些常量?
编辑:
我可以使用Unity找到1定义的解决方案。但这仍然不适用于多个模块,因为它们必须写入同一个文件。一般来说,我在C#中解决这个问题的方法是定义一组所有模块都将包含的通用接口。我认为您可以通过Unity将每个模块中的文件放在相同的位置,从而允许以后的安装覆盖这些相同的文件(显然,内容相同)。然后,您将放置一些编辑器控件,这些控件公开属性以保存这些接口的实例,然后将它们连接到UI中。您将测试这些属性的值
null
,以确定缺少哪些属性
Common.cs:
public interface IModuleA {}
public interface IModuleB {}
模数a.cs
public class ModuleA : IModuleA {}
模块B.cs
public class ModuleB : IModuleB
{
public IModuleA ModuleAInstance {get; set;}
private bool IsModuleAPresent()
{
return !ModuleAInstance == null;
}
}
解决这一问题的理想方法是使用包管理器和适当的依赖项注入,但使用Unity实现这一点并不简单。一般来说,我在C#中解决这一问题的方法是定义一组所有模块都将包含的通用接口。我认为您可以通过Unity将每个模块中的文件放在相同的位置,从而允许以后的安装覆盖这些相同的文件(显然,内容相同)。然后,您将放置一些编辑器控件,这些控件公开属性以保存这些接口的实例,然后将它们连接到UI中。您将测试这些属性的值
null
,以确定缺少哪些属性
Common.cs:
public interface IModuleA {}
public interface IModuleB {}
模数a.cs
public class ModuleA : IModuleA {}
模块B.cs
public class ModuleB : IModuleB
{
public IModuleA ModuleAInstance {get; set;}
private bool IsModuleAPresent()
{
return !ModuleAInstance == null;
}
}
解决这个问题的理想方法是使用包管理器和适当的依赖项注入,但使用Unity实现这一点并不简单。经过大量搜索,我终于找到了一个非常简单的解决方案,我想与大家分享:
初始化加载 统一是有属性的。它告诉Unity尽快根据类初始化
- 团结开始了
- 在重新编译脚本=>之后,也在导入带有脚本的新unitypackage之后
静态构造函数 在他们的示例中,他们展示了如何将其与
静态构造函数相结合
发件人:
在创建第一个实例或引用任何静态成员之前,会自动调用静态构造函数来初始化类
虽然通常您仍然需要创建类的实例,但在初始化类时,静态构造函数会立即“实例化/执行”,这是我们使用[initializenload]
属性强制执行的
脚本定义符号
进一步的统一实际上在玩家设置中定义了项目范围的定义
好的方面是:我们还可以通过脚本API访问它们:
所以我现在做的是
模块A
此模块没有依赖项,只是在PlayerSettings中定义了一个“全局定义”。我把这个脚本放在某个地方,例如Assets/ModuleA/Editor
(重要的是最后一个文件夹的名称)
使用System.Linq;
使用UnityEditor;
名称空间模块
{
//将在加载或重新编译时初始化
[初始化加载]
公共静态类启动
{
//一旦类初始化,就调用静态构造函数
静态启动()
{
#区域添加编译器定义
//获取当前定义
//返回类似“DEFINE_1;DEFINE_2;DEFINE_3”的字符串
var defines=PlayerSettings.GetScriptingDefinesSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
//拆分为列表以检查我的定义是否已经存在
var define=defines.Split(“;”).ToList();
如果(!define.Contains)(