triggers/collides 时定位 GameObjects 属性的最简单方法?
Simplest way to target GameObjects properties when it triggers/collides?
如果我有触发器或碰撞,我想以该 gameObject 为目标并访问它的每个附加脚本的属性。我设法这样做了,但我知道必须有更好的方法,对吗?
在这里,我想将附加到标记为 "BoxManager" 的触发游戏对象的脚本作为目标,然后是 BoxManager 的 属性 "isHeld" 如果在与trigger/collision 我必须使用目标对象,但有没有更好的方法来完成其余的工作?
void OnTriggerStay2D(Collider2D target)
{
if (target.gameObject.tag == "Box")
{
if (target.attachedRigidbody.GetComponent<BoxManager>().isHeld == false)
{
target.attachedRigidbody.AddForce(transform.right * thrust);
}
}
}
首先,target.attachedRigidbody.GetComponent<BoxManager>()
完全没有必要和多余。我见过有人用 target.attachedRigidbody.gameObject.transform.GetComponent<BoxManager>();
这样的代码做得更糟。这是在做同样的事情,因为它们都附加到一个游戏对象上。
你可以而且应该简单地做到 target.GetComponent<BoxManager>();
。
至于一直用GetComponent
函数在碰撞时获取另一个脚本,那很好。在您可以访问该脚本中的变量之前,获取在碰撞期间附加到游戏对象的另一个脚本是最简单的方法。
尽管如此,我觉得很烦人,因为您必须在 OnTriggerStay2D
中执行 GetComponent
。当你有这么多脚本要检查时,它会变得更烦人。
这是你的碰撞函数:
void OnTriggerStay2D(Collider2D target){}
并且您需要在碰撞后从目标访问您的 BoxManager
脚本....
一个棘手的方法是使用 Dictionary
。在 Start
函数中初始化 Dictionary 并使用 Collider2D
作为键和 BoxManager
作为值。
在游戏过程中使用 Collider2D
和 BoxManager
实例化和销毁 GameObjects 时更新此字典。
像这样:
Dictionary<Collider2D, BoxManager> scriptID = new Dictionary<Collider2D, BoxManager>();
然后在您的碰撞函数中,使用 TryGetValue
和 target
变量作为获取 BoxManager
组件的键。
void OnTriggerStay2D(Collider2D target)
{
if (target.CompareTag("Box"))
{
BoxManager result;
scriptID.TryGetValue(target, out result);
if (!result.isHeld)
{
}
}
}
事实上,如果您 %100 确定 该对象附加了 BoxManager
脚本,您可以在一行代码中完成,而无需TryGetValue
函数:
void OnTriggerStay2D(Collider2D target)
{
if (target.CompareTag("Box"))
{
BoxManager result = scriptID[target];
}
}
您可以像上面那样使用 target.CompareTag
来减少在没有 BoxManager
脚本的情况下检测到对象的机会。请注意我是如何将您的 target.gameObject.tag
更改为 target.CompareTag
的。推荐使用target.CompareTag
.
现在代码已经简化为 BoxManager result = scriptID[target];
,同时使用target.CompareTag("Box")
作为守卫,这样你就不必使用TryGetValue
或 ContainsKey
函数。
下面是整个脚本的示例:
Dictionary<Collider2D, BoxManager> scriptID = new Dictionary<Collider2D, BoxManager>();
public BoxManager boxManagerPrefab;
void Start()
{
//Register your BoxManager instances to the Dictionary
for (int i = 0; i < 5; i++)
{
BoxManager bc = Instantiate(boxManagerPrefab) as BoxManager;
//Use Isntance ID of the Script as id
Collider2D cld2D = boxManagerPrefab.GetComponent<Collider2D>();
scriptID.Add(cld2D, bc);
}
}
void OnTriggerStay2D(Collider2D target)
{
if (target.CompareTag("Box"))
{
BoxManager result = scriptID[target];
if (!result.isHeld)
{
target.attachedRigidbody.AddForce(transform.right * thrust);
}
}
}
如果我有触发器或碰撞,我想以该 gameObject 为目标并访问它的每个附加脚本的属性。我设法这样做了,但我知道必须有更好的方法,对吗?
在这里,我想将附加到标记为 "BoxManager" 的触发游戏对象的脚本作为目标,然后是 BoxManager 的 属性 "isHeld" 如果在与trigger/collision 我必须使用目标对象,但有没有更好的方法来完成其余的工作?
void OnTriggerStay2D(Collider2D target)
{
if (target.gameObject.tag == "Box")
{
if (target.attachedRigidbody.GetComponent<BoxManager>().isHeld == false)
{
target.attachedRigidbody.AddForce(transform.right * thrust);
}
}
}
首先,target.attachedRigidbody.GetComponent<BoxManager>()
完全没有必要和多余。我见过有人用 target.attachedRigidbody.gameObject.transform.GetComponent<BoxManager>();
这样的代码做得更糟。这是在做同样的事情,因为它们都附加到一个游戏对象上。
你可以而且应该简单地做到 target.GetComponent<BoxManager>();
。
至于一直用GetComponent
函数在碰撞时获取另一个脚本,那很好。在您可以访问该脚本中的变量之前,获取在碰撞期间附加到游戏对象的另一个脚本是最简单的方法。
尽管如此,我觉得很烦人,因为您必须在 OnTriggerStay2D
中执行 GetComponent
。当你有这么多脚本要检查时,它会变得更烦人。
这是你的碰撞函数:
void OnTriggerStay2D(Collider2D target){}
并且您需要在碰撞后从目标访问您的 BoxManager
脚本....
一个棘手的方法是使用 Dictionary
。在 Start
函数中初始化 Dictionary 并使用 Collider2D
作为键和 BoxManager
作为值。
在游戏过程中使用 Collider2D
和 BoxManager
实例化和销毁 GameObjects 时更新此字典。
像这样:
Dictionary<Collider2D, BoxManager> scriptID = new Dictionary<Collider2D, BoxManager>();
然后在您的碰撞函数中,使用 TryGetValue
和 target
变量作为获取 BoxManager
组件的键。
void OnTriggerStay2D(Collider2D target)
{
if (target.CompareTag("Box"))
{
BoxManager result;
scriptID.TryGetValue(target, out result);
if (!result.isHeld)
{
}
}
}
事实上,如果您 %100 确定 该对象附加了 BoxManager
脚本,您可以在一行代码中完成,而无需TryGetValue
函数:
void OnTriggerStay2D(Collider2D target)
{
if (target.CompareTag("Box"))
{
BoxManager result = scriptID[target];
}
}
您可以像上面那样使用 target.CompareTag
来减少在没有 BoxManager
脚本的情况下检测到对象的机会。请注意我是如何将您的 target.gameObject.tag
更改为 target.CompareTag
的。推荐使用target.CompareTag
.
现在代码已经简化为 BoxManager result = scriptID[target];
,同时使用target.CompareTag("Box")
作为守卫,这样你就不必使用TryGetValue
或 ContainsKey
函数。
下面是整个脚本的示例:
Dictionary<Collider2D, BoxManager> scriptID = new Dictionary<Collider2D, BoxManager>();
public BoxManager boxManagerPrefab;
void Start()
{
//Register your BoxManager instances to the Dictionary
for (int i = 0; i < 5; i++)
{
BoxManager bc = Instantiate(boxManagerPrefab) as BoxManager;
//Use Isntance ID of the Script as id
Collider2D cld2D = boxManagerPrefab.GetComponent<Collider2D>();
scriptID.Add(cld2D, bc);
}
}
void OnTriggerStay2D(Collider2D target)
{
if (target.CompareTag("Box"))
{
BoxManager result = scriptID[target];
if (!result.isHeld)
{
target.attachedRigidbody.AddForce(transform.right * thrust);
}
}
}