GetComponent<Image> ().enabled 和 .SetActive(false) 有什么区别?统一

What is the difference between GetComponent<Image> ().enabled and .SetActive (false); in unity

我一直在尝试使用 SetActive () 打开和关闭游戏对象。

我想不通,最后使用了:

 GameObject.Find ("ObjectName").GetComponent<Image> ().enabled = false;

关闭图像。

我并没有尝试使用相同的脚本来关闭其中嵌套有多个动画的游戏对象。

GameObject.Find ("ObjectName").GetComponent<???> ().enabled = false;
GameObject.Find ("ObjectName").SetActive (false);

我不确定 <> 中的内容,但我读过我可以用 SetActive () 做到这一点,但这似乎不起作用并给了我一个 "Object Reference not set to object" 错误。

那么这两者有什么区别,我该如何正确使用它们呢?

设置.enabled打开或关闭游戏对象上的一个组件,例如一个图像。使用 SetActive() 打开或关闭整个游戏对象。

选择使用哪个应与您要禁用的内容相对应。

使用 GetComponent 允许您 enable/disable 并与 GameObject 上的特定组件进行交互。

例如,您可能需要在某个时候禁用游戏对象的刚体,但您仍然希望该对象及其上的所有其他内容处于活动状态。所以你可以简单地说:

GameObject.Find("MyObject").GetComponent<Rigidbody>().enabled = false;

请注意,“<>”中的内容是您要与之交互的组件的 class 名称。

例如,如果您有一个脚本是您自己在一个名为 MyScript 的游戏对象上编写的,您可以像这样抓住它:

MyScript script = GamesObject.Find("MyObject").GetComponent<MyScript>().enabled = true;

此外,GetComponent 的另一个很好的用途是从对象的脚本中读取信息。

例如,如果您有一个名为 Health 的脚本,并且对象上有一个 public 变量 HitPoints,则另一个脚本可以使用 GetComponent 访问该信息.

if( enemyGameObject.GetComponent<Health>().HitPoints < 0 )
{
    enemyGameObject.SetActive(false);
}

使用SetActive 将完全启用和禁用游戏对象。这比删除/创建新对象的成本更低,因此经常用于 Object Pooling 等技术。

例如,如果您有一个需要禁用的 GameObject,但您知道您很快就会再次需要它,那么只需调用

MyGameObject.SetActive(false);

...

MyGameObject.SetActive(true);

而不是完全删除该对象,然后在您准备好再次创建一个新对象时创建一个新对象。

综合其他答案,禁用组件意味着不再调用 MonoBehaviour 回调。所以没有Update、FixedUpdate、OnCollisionXXX等等。

创建对象时会调用 Awake,因此显然在该阶段默认启用。在 Awake 之后的第一个 运行 调用 Start。因此,如果您在 Awake 中关闭该组件,Start 将等待您从其他地方将其重新打开。

OnEnable/OnDisable 在您修改启用的 属性 时被调用。

SetActive 在 GO 上运行,几乎是一次禁用所有组件的快捷方式。

gameObject.SetActive(false);
foreach(var comp in GetComponentsInChildren<MonoBehaviour>()){
    comp.enabled = false;
}

它们的结果非常相似(可能效率不高)。实际上,当您设置一个游戏对象 on/off 时,每个组件的 OnEnable/OnDisable 都会被调用。如果您关闭该对象,将不再调用所有 MonoBehaviour 回调。

因此,如果您希望禁用移动但仍能看到对象和其他动作,则选择取决于您的需求:

 GetComponent<Movement>().enabled = false;

如果你想杀死一个敌人:

 enemy.gameObject.SetActive(false);

请注意,即使某个组件被禁用,并不意味着您不能与其交互。您仍然可以手动调用它的任何方法。考虑一下:

AnyComponent ac = gameObject.GetComponent<AnyComponent>();
ac.enabled = false;
ac.AnyMethod(); 

考虑到它不需要更新或 FixedUpdate(物理操作),有效并且会做它应该做的事情。

无法使用 GetComponent 找到停用的组件,您可以使用 GetComponentInChildren(true) 获取它,因为它还会搜索游戏对象及其子对象。我不确定它 returns 是第一个找到的还是第一个活跃的。

myGameObject.SetActive(假); AnyComponent ac = myGameObject.GetComponent(); AnyComponent acic = myGameObject.GetComponentInChildren(true);

即使 GO 附加了 AnyComponent,ac 为 null,acic 却不是(尽管似乎是 5.3 的功能)。 http://docs.unity3d.com/ScriptReference/Component.GetComponentInChildren.html

最后,要让一个组件暴露tick,它需要在脚本中有一个Start方法(不要问为什么...)。