在触发/碰撞时定位GameObjects属性的最简单方法是? [英] Simplest way to target GameObjects properties when it triggers/collides?

查看:70
本文介绍了在触发/碰撞时定位GameObjects属性的最简单方法是?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果有触发器或碰撞,我想定位该游戏对象,并可以访问每个附带脚本的属性.我设法做到了这一点,但我知道必须有更好的方法对吗?

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.

在游戏过程中使用Collider2DBoxManager实例化并销毁游戏对象时,更新此词典.

Update this Dictionary when you instantiate and destroy GameObjects with Collider2D and BoxManager during game-play.

类似这样的东西:

Dictionary<Collider2D, BoxManager> scriptID = new Dictionary<Collider2D, BoxManager>();

然后在碰撞函数中,使用TryGetValuetarget变量作为获取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];简化了代码,因此您不必使用TryGetValueContainsKey函数.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆