繁体   English   中英

Unity / C#-在另一个对象上引用方法

[英]Unity/C# - Referencing a method on another object

几天前,我决定与Unity一起玩游戏,尽管在编程方面起了很大的作用,但Unity和C#对我来说都是全新的。 我正在2D模式下工作。

我创建了一个小游戏来尝试学习引擎,该引擎(唯一)涉及向外星人发射子弹。 我正在使用bullet对象来检测它何时击中某些东西(并摧毁自身),以及在其击中需要做出反应的东西的情况下-目标对象来决定其响应。

这是BulletController的相关部分,它附加在子弹的每个实例上:

    // Check to see if the bullet is colliding with anything.
void OnCollisionEnter2D(Collision2D col)
{
    if (col.gameObject.tag == "Terrain") {
        this.audio.Play ();
        int smokeIndex = 0;
        GameObject smoke = (GameObject) Instantiate(bulletSmoke[smokeIndex],transform.position,transform.rotation); 
        Destroy (smoke, 5f);
        Destroy (gameObject,0.05f);
    }

    if (col.gameObject.tag == "Enemy") { 
        col.gameObject.GetComponent<BasicAlienController>().TakeHit (1,1);
    }

}

为了完整起见,来自BasicAlienController的(占位符)部分:

public void TakeHit(int damageType, int damageAmount) {
    print ("Taking hits");
}

我最初在如何在外星人的脚本上调用TakeHit时打了一个大问题,但是经过一番尝试和错误之后,发现上面的内容很有效,但是我对它的编写方式并不满意。 盲目相信每个敌人上都有一个BasicAlienController似乎是不对的,因为稍后,我可能会使用特定于外星人的控制器来扩展它,以便它们可以以不同的方式做出反应。 盲目相信标记为“外星人”的所有内容上也都可以使用TakeHit()方法,这似乎也不对,我的意思是,我想应该有,但并非总是如此。

所以这是一个多部分的问题:

  1. 如果我有(例如) FlightingAlienControllerWalkingAlienController,而不必专门查询对象名称,然后进行潜在的大切换,如何确定自己根据敌人的类型调用相关的控制器? 如果我只能在一个GameObject上附加一个脚本,那么无论我叫什么名字,为什么我不能只引用“脚本”?

  2. 如何检查是否有TakeHit()方法可用,还是要确保我始终在标记为“ Alien”的任何内容上公开该方法?

  3. 额外的问题是,控制器名称周围的<>有什么用,我是C#的新手,以前没有看过这种语法,为什么不只是使用gameObject.GetComponent(“ BasicAlienController”)或类似名称呢?

1.如果我有(例如)FlyingAlienController和WalkingAlienController,而不必专门查询对象名称,然后进行潜在的大切换,如何确定我根据敌人的类型调用相关的控制器? 如果我只能在一个GameObject上附加一个脚本,那么无论我叫什么名字,为什么我不能只引用“脚本”?

实际上,您可以在GameObject上拥有任意数量的脚本。 我的建议是为每个控制器实现一个接口,然后使用“ SendMessage”。 SendMessage会对性能产生影响,但是对于这种情况,我认为这是正确的选择。

http://docs.unity3d.com/ScriptReference/GameObject.SendMessage.html

不幸的是,您不能严格键入该调用,但是可以。 您的代码可能看起来像这样:

BasicAlienController:

public class BasicAlienController : MonoBehavior, ITakeHit
{
    // It can only take a single input
    public void TakeHit(object args) 
    {
        // Logic here
        print ("Taking hits in BasicAlienController ");
    }
}

FlyingAlienController:

public class FlyingAlienController : MonoBehavior, ITakeHit
{
    // It can only take a single input
    public void TakeHit(object args) 
    {
        // Logic here
        print ("Taking hits in FlyingAlienController ");
    }
}

BulletController:

// Check to see if the bullet is colliding with anything.
void OnCollisionEnter2D(Collision2D col)
{
    if (col.gameObject.tag == "Terrain") 
    {
        this.audio.Play ();
        int smokeIndex = 0;
        GameObject smoke = (GameObject) Instantiate(bulletSmoke[smokeIndex],transform.position,transform.rotation); 
        Destroy (smoke, 5f);
        Destroy (gameObject,0.05f);
    }

    if (col.gameObject.tag == "Enemy") 
    { 
        int[] hit = new int[] {1, 1};
        col.gameObject.SendMessage("TakeHit", hit);
        // If you don't want to require a receiver
        // col.gameObject.SendMessage("TakeHit", hit, SendMessageOptions.DontRequireReceiver);
    }
}

3.奖励问题,控制器名称周围的<>有什么用,我是C#的新手,以前没有看过这种语法,为什么不只是使用gameObject.GetComponent(“ BasicAlienController”)或类似的名称? C#通用。 参见安迪的链接。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM