尝试访问自定义 Unity 组件脚本中的变量

Trying to access vars within Custom Unity Component Script

提问人:makeITwork 提问时间:9/20/2023 最后编辑:makeITwork 更新时间:9/20/2023 访问量:41

问:

我遇到了尝试访问存储在脚本组件中的变量的情况。

玩家可以对 gameObject 执行大约 8 个操作。 用户将这些操作脚本附加到控制操作方式的游戏对象。

在游戏过程中,我需要遍历 gameObject 的组件,并将选定的 Action 与附加的组件相匹配。我已经成功找到了附加到组件的相应操作脚本,但我无法找到其中包含的变量。

        // LOOP THROUGH THISEL COMPONENTS
        var thisElComps=thisEl.GetComponents<Component>();

        for(var i=0; i<thisElComps.Length; i++){
            var thisComp=thisElComps[i].GetType();

            // IF COMPONENT MATCHES ACTIVE SELECTED ACTION
            if(activeVerb.name == thisComp.ToString()){
                print("found");
                // need to access settings inside component here!
                // if(thisComp.myVar){};
           
            // SELECTED ACTION COMPONENT NOT FOUND
            }else{
                
                print("not found");
            }
        }

Found 和 Not Found 正在正确打印,但我尝试过的所有内容似乎都无法访问组件内的变量:/对不起,新手问题,但我是 C# 的新手,来自不同的语言。谢谢

更新:为了示例起见,这里是一个附加的组件脚本。

public class ActionClassName: MonoBehaviour {
    public string myVar;   
}

thisComp.myVar;(错误:没有 myVar 的定义)

print(thisElComps[i] 是 Component); 返回 true

更新:

typeName="myAction";

var myComp=thisEl.GetComponent("myAction");

发现!

var myComp=thisEl.GetComponent(System.Type.GetType(typeName));

错误:类型不能为 null

C# 循环 unity-game-engine 组件

评论

0赞 BugFinder 9/20/2023
好吧,您还没有分享相关的组件示例,但它永远不会是 thisComp.myvar,您需要获得 thisElComps[i].myvar 类型转换,因为您得到的是类型组件而不是特定类型。像往常一样,你做GetComponent<MyType>来访问该特定的东西及其变量
0赞 makeITwork 9/20/2023
thisComp 指向 thisElComps[i]....我来自JS,所以严格的vars让我发疯。我的类型需要是一个变量,我不确定如何以这种方式转换它。
0赞 makeITwork 9/20/2023
刚刚更新了一个示例组件脚本。在它们所附着的项目上,会有几个充当不同的“动作”。虽然我能够检测到是否有任何附加的东西,但我无法抓住其中的 myVar。
0赞 hijinxbassist 9/20/2023
基类型不会从扩展它的类继承变量。您需要将 Component 强制转换为声明变量的特定类型。例如。(MyDerivedComponent)thisElComps[i];
0赞 BugFinder 9/20/2023
其实这个|Comp 是 .getType,所以实际上它不是指向数组,而是指向数组中对象的类型

答:

0赞 derHugo 9/20/2023 #1

C# 不像 Javascript!C# 是强类型的,这意味着为了访问您的,您肯定需要一个类型的引用(o 派生自该引用)myVarwhatever

您投射并检查哪个没有/知道 .ComponentmyVar

实际上,如果您只对特定类型感兴趣,为什么还要遍历所有组件呢?

var thisElComps = thisEl.GetComponents<whatever>();

foreach(var thisComp in thisElComps)
{
    if(activeVerb.name == thisComp.ToString())
    {
        print("found");
        if(thisComp.myVar)
        {
            ...
        }
    }
}

您还可以加入一些对第一个匹配项感兴趣的 onl 或使用 Linq FirstOrDefaultbreak

*但是,进一步注意 return the same as which return same as that that arethisComp.ToString()thisComp.namethisComp.gameObject.namethisEl.name

=> 检查将始终同时通过或失败所有项目thisElComps

如果你想再次通过字符串找到特定类型的组件,你可以简单地使用字符串重载并执行

var theComp = thisEl.GetComponent(activVerb.name) as whatever;
if(theComp)
{
    print("found");
    print(theComp.myVar);
}
else
{
    print("not found");
}

评论

0赞 makeITwork 9/20/2023
感谢您的回复。我知道它是强类型的,这就是问题所在。whatever 是对可附加到组件的众多脚本之一的引用。我正在根据 activeVerb 变量搜索该脚本以进行匹配。所以。。。你的答案 var thisElComps = thisEl.GetComponents<whatever>();无济于事,因为类型应该是帖子中要求的变量。经过更多的研究,我相信仿制药是我正在寻找的?您最后一次尝试使用 var theComp = thisEl.GetComponent(activVerb.name) 作为任何内容;也不起作用,因为无论如何,再次,是一个 var
0赞 derHugo 9/20/2023
@makeITwork好吧,我的假设是,您正在寻找的所有组件实际上都是从中派生出来的,因为您正在寻找的变量仅在...否则,我们将需要更多关于您实际想要实现的目标的信息......也许一个通用的接口是你更想使用的(也可以传递给)?...我认为您的用例还不完全清楚whateverwhateverGetComponent(s)
0赞 makeITwork 9/20/2023
感谢您尝试提供帮助 - 我再次更新了问题。可能发生的每个操作都存储在单独的脚本文件中。这些文件作为组件附加到 obj。我只需要将 activeVerb 变量与组件的名称进行比较,并访问组件中的属性。似乎我实际遇到的主要障碍是当我所拥有的只是字符串值时获取类型。GetType 仅在字符串正确时返回 null
0赞 derHugo 9/20/2023
@makeITwork我认为拥有不止一个班级的例子真的很有帮助......我仍然不太明白你到底想(或想)通过它实现什么......例如,在您最近的尝试中,传递的字符串不应该是,而是......但总的来说,基于字符串看起来像一个设计缺陷......什么从一开始就反对强类型化方法?你的问题仍然感觉像是一个XY问题myActionActionClassName ;)
0赞 makeITwork 9/20/2023
我一直在兜圈子,试图找到一种方法来做这个强类型,但这更多的是为了后端的灵活性,而不是任何东西,不能。我已经重写了 3 次,但总是回到字符串格式的类型。ActionClassName 只是一个通用示例,因为不同脚本中将有多个操作。这些连接到 GO。当事件发生时 - 我检查附加了哪个操作并访问属性...