Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unity3d 我能在没有项目设置的c代码中定义一个常量解决方案吗?_Unity3d_C Preprocessor_Constants_Global_Conditional Compilation - Fatal编程技术网

Unity3d 我能在没有项目设置的c代码中定义一个常量解决方案吗?

Unity3d 我能在没有项目设置的c代码中定义一个常量解决方案吗?,unity3d,c-preprocessor,constants,global,conditional-compilation,Unity3d,C Preprocessor,Constants,Global,Conditional Compilation,我知道这是一个aksed,并回答了几次。 ,及 但就我而言,我不能使用任何建议的方法: 我正在为UnityProjects(一种提供特定功能的包)编写不同的“模块”(或者插件,如果您愿意的话)。其思想是,开发人员可以通过导入包含所有脚本和资源的UnityPackage,加载某个“模块”以在其项目中使用 但其中一些模块本身依赖于其他模块。因此,到目前为止,我尝试的是在每个模块中使用一个类Constants,该类具有独立的名称空间和预处理器定义 模块A #如果!模块A #定义模块_A//但我不仅在这

我知道这是一个aksed,并回答了几次。 ,及

但就我而言,我不能使用任何建议的方法:

我正在为UnityProjects(一种提供特定功能的包)编写不同的“模块”(或者插件,如果您愿意的话)。其思想是,开发人员可以通过导入包含所有脚本和资源的
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)(