获取gameObject的实例

时间:2019-05-07 16:06:40

标签: c# unity3d gameobject

希望获得该游戏对象的实例,以便我可以成功地使用.enabled将其隐藏在场景中。

PlayPortalLoginButton loginButton = gameObject.GetComponent<PlayPortalLoginButton>();

对C#来说还很陌生,我相信我已经接近实现上述目标的目标。什么需要改变?想了解如何正确执行此操作。

3 个答案:

答案 0 :(得分:0)

GameObject button;
void Start() {
    button = GameObject.Find ("yourButtom");
}
void SomeEvent() {
    button.SetActive(false);   
}

我认为您必须为您提供帮助

答案 1 :(得分:0)

有多种方法可以访问脚本中的gameObject,具体取决于您要获取的是哪个gameObject。

如果您试图在行为脚本中访问某个行为的GameObject,则只需使用gameObject就足够了,因为这就是该行为所附属的gameObject。

访问附加到另一个GameObject的脚本很棘手。对于诸如MainMenu之类的场景,将其公开引用作为示例没有错:

public PlayPortalLoginButton loginButton;

void setLoginState(bool activate) {
    loginButton.enabled = activate;
}

在此示例中,您只需将带有GamePortalLoginButton脚本的gameObject拖放到管理器脚本上即可,该脚本将控制是否启用它。

如果您需要一种更模块化的方法,例如在游戏场景中,在运行时填充对象,则可以采用以下方法:

PlayPortalLoginButton loginButton;

void setLoginState(bool activate) {
    if(loginButton == null)
    {
        loginButton = FindObjectOfType<PlayPortalLoginButton>();
    }
    // Requires the correct version of .net otherwise you can reuse the check above...
    loginButton?.enabled = activate;
}

在上面的脚本中,如果需要登录按钮的gameObject,现在可以通过loginButton.gameObject对其进行访问。

还有更多示例可以使用,其他方法也可以,但是我觉得上面对于菜单来说就足够了。

我还将提到我正在避免使用GameObject.FindGameObject.FindGameObjectsWithTag的示例,因为它们更容易出错。它们仅在正确标记了您的名称或标记后才起作用,如果由于任何原因重命名它们,则脚本将无法找到对象,这可能会导致故障排除问题。

使用FindObjectOfType,不太可能出现错误,并且如果删除该脚本类型,则这些脚本将填充一个错误,指示该脚本不再存在。重构时,如果右键单击行为名称并使用重命名选项,它将自动在整个代码中更新对脚本的引用。

答案 2 :(得分:0)

这是您可以在场景中的GameObject上找到组件的一种方法,其中“ PortalLoginButton”是GameObject的名称,如编辑器所示:

var loginButton = GameObject.Find("PortalLoginButton");
loginButton.enabled = false;

但是,GameObject.Find("...")会搜索场景中每个GameObject的名称,这通常不是引用GameObject的最佳方法,因为它效率不高。 因此请确保不要在GameObject.Find("...")函数中使用Update()或类似的函数调用,因为它将执行每一帧并降低游戏速度。如果在游戏运行时未实例化GameObject,通常最好对脚本中使用的任何GameObjectComponent进行全局引用,然后拖动并-将要查找的GameObjectComponent放到编辑器中的字段中。另外,您可以在GameObject.Find("...")Start()函数中使用Awake()来存储对您正在寻找的GameObject的引用,这样,搜索仅在游戏开始。

这里是如何在全局字段中存储引用的示例(它将显示在编辑器中,您可以将GameObject拖放到其中)。注释中说明了使用公共字段与私有字段之间的差异(您可以决定使用公共字段还是私有字段):

// By default, private fields are not viewable in the editor,
// but the [SerializeField] attribute, placed before
// the field declaration, allows them to be visible.
[SerializeField]
private GameObject loginButtonPrivateReference;
// If you need to access loginButton from another script, 
// you can make it a public field.
// Public fields are viewable in the editor by default.
public GameObject loginButtonPublicReference;

以下是如何在Awake()函数中使用GameObject.Find(“ ...”)的示例:

private GameObject loginButton;

private void Awake() {
    loginButton = GameObject.Find("PortalLoginButton");
}

如果您需要按类型或标记名称在场景中搜索GameObjects,请参阅GameObject文档here了解更多信息。按类型搜索比按名称搜索效率低,而按标签搜索比按名称搜索效率更高,这是因为类型搜索会检查每个GameObject上的每个组件,而标签搜索仅搜索有组织的GameObject子集。