在触发/碰撞时定位GameObjects属性的最简单方法是? [英] Simplest way to target GameObjects properties when it triggers/collides?
问题描述
如果有触发器或碰撞,我想定位该游戏对象,并可以访问每个附带脚本的属性.我设法做到了这一点,但我知道必须有更好的方法对吗?
If I have a trigger or collision I want to target that gameObject and have access to it's properties for each of the attached scripts. I managed to do it like this but I know there has to be a better method right?
在这里,我想定位附加到触发的游戏对象的脚本,该脚本标记为"BoxManager",然后是BoxManager的属性"isHeld".如果在与触发器/碰撞交互时像这样动态选择目标,则必须使用目标对象,但是还有其他更好的方法吗?
Here I wanted to target the script attached to the triggered game object labeled "BoxManager" and then BoxManager's property "isHeld" If the target is being selected dynamically like this when it interacts with the trigger/collision I have to use the target object, but is there a better way to do the rest?
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>();
之类的代码做得更糟.之所以这样做,是因为它们都附着在一个GameObject上.
First of all, target.attachedRigidbody.GetComponent<BoxManager>()
is totally unnecessary and redundant. I've seen people even do worse with code such as target.attachedRigidbody.gameObject.transform.GetComponent<BoxManager>();
. That's doing the-same thing because they are all attached to one GameObject.
您可以并且应该将其简单地添加到target.GetComponent<BoxManager>();
.
You can and should simply that to target.GetComponent<BoxManager>();
.
至于在碰撞期间一直使用GetComponent
函数来获取另一个脚本,这很好.这是在碰撞期间获取附加到GameObject的另一个脚本的最简单方法,然后才能访问该脚本中的变量.
As for using GetComponent
function all the time to get another script during collision, that's fine. It is the easiest way to get another Script that is attached to the GameObject during collision before you can access the variables in side that script.
尽管如此,我觉得很讨厌您必须为此而在OnTriggerStay2D
中执行GetComponent
.当您要检查的脚本太多时,这会变得更加烦人.
Although, I find it annoying that you must do GetComponent
in the OnTriggerStay2D
just for that. It get's more annoying when you have so many scripts to check.
这是您的碰撞功能:
void OnTriggerStay2D(Collider2D target){}
并且您需要在碰撞后从目标访问BoxManager
脚本....
And you need to access your BoxManager
script from target after collision....
一种棘手的方法是使用Dictionary
.在Start
函数中初始化Dictionary,并使用Collider2D
作为键,并使用BoxManager
作为值.
A tricky way would be to use a Dictionary
. In the Start
function initialize the Dictionary and use Collider2D
as the key and BoxManager
as the value.
在游戏过程中使用Collider2D
和BoxManager
实例化并销毁游戏对象时,更新此词典.
Update this Dictionary when you instantiate and destroy GameObjects with Collider2D
and BoxManager
during game-play.
类似这样的东西:
Dictionary<Collider2D, BoxManager> scriptID = new Dictionary<Collider2D, BoxManager>();
然后在碰撞函数中,使用TryGetValue
和target
变量作为获取BoxManager
组件的键.
Then inside your collision function, use TryGetValue
and the target
variable as the key to get the BoxManager
component.
void OnTriggerStay2D(Collider2D target)
{
if (target.CompareTag("Box"))
{
BoxManager result;
scriptID.TryGetValue(target, out result);
if (!result.isHeld)
{
}
}
}
实际上,如果您%100确保该对象具有附加的BoxManager
脚本,则可以在一行代码中执行此操作,而无需使用TryGetValue
函数:>
In fact, if you %100 sure that this object has the BoxManager
script attached to it, you can do that in one line of code with without the TryGetValue
function:
void OnTriggerStay2D(Collider2D target)
{
if (target.CompareTag("Box"))
{
BoxManager result = scriptID[target];
}
}
您可以使用上述target.CompareTag
来减少不使用BoxManager
脚本而检测到对象的机会.注意我如何将您的target.gameObject.tag
更改为target.CompareTag
.建议使用target.CompareTag
.
You can reduce the chances of detecting Object without the BoxManager
script by using target.CompareTag
like above. Notice how I changed your target.gameObject.tag
to target.CompareTag
. It recommended to use target.CompareTag
.
现在,在使用target.CompareTag("Box")
作为防护时,已使用 BoxManager result = scriptID[target];
简化了代码,因此您不必使用TryGetValue
或ContainsKey
函数.
Now the code has been simplified with BoxManager result = scriptID[target];
while using target.CompareTag("Box")
as a guard so that you don't have to use TryGetValue
or the ContainsKey
function.
下面是整个脚本的示例:
Below is what the example of the whole script should look like:
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);
}
}
}
这篇关于在触发/碰撞时定位GameObjects属性的最简单方法是?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!