Unity消息系统

时间:2015-05-06 03:22:23

标签: c# unity3d

阅读Bellow。

子弹脚本

using UnityEngine;
using System.Collections;

public class Bullet : MonoBehaviour {
    public float bulletLifeTime = 5;

    // Use this for initialization
    void Start()
    {

    }

    void Update()
    {
        //If bullet life time exceeds 5 seconds destroy bullet
        bulletLifeTime -= Time.deltaTime;

        if (bulletLifeTime < 0)
        {
            CleanupBullet();
        }
    }

    void OnCollisionEnter2D(Collision2D collision)
    {
        NotifyHitTarget(collision.gameObject);
        CleanupBullet();
    }

    void OnTriggerEnter2D(Collider2D collider)
    {
        NotifyHitTarget(collider.gameObject);
        CleanupBullet();
    }

    /// <summary>
    /// Cleanup the bullet and remove it from the scene
    /// </summary>
    public void CleanupBullet()
    {
        //Destroy bullet
        GameObject.Destroy(gameObject);
    }

    /// <summary>
    /// Notiffy a given game object that it has been hit by this bullet
    /// </summary>
    /// <param name="gameObject">The game object that has been hit by this bullet</param>
    public void NotifyHitTarget(GameObject gameObject)
    {
        //Need to use the Unity Messaging System here to send a message to GoalPickup to notify it that it has been hit
        Debug.Log("Collision");
    }
}

取件脚本

using UnityEngine;
using System.Collections;

public abstract class Pickup : MonoBehaviour {

    /// <summary>
    /// Unity will send this message when a collider has entered the pickup trigger zone
    /// </summary>
    /// <param name="collider">The collider that entered the trigger zone</param>
    void OnTriggerEnter2D(Collider2D collider)
    {
        if (collider.GetComponent<Rigidbody2D>() != null) 
        { //check if the collider has a rigid body attached
            PlayerController player = collider.GetComponent<Rigidbody2D>().gameObject.GetComponent<PlayerController>();

            if (player != null) 
            { //the rigid body that collided with this pickup was a player
                onPlayerCollect(player);
                GameObject.Destroy(gameObject);
            }
        }
    }

    /// <summary>
    /// Notify the player has collected this pickup
    /// </summary>
    /// <param name="player">The player that collected the pickup</param>
    protected abstract void onPlayerCollect(PlayerController player);
}

GoalPickup脚本

using UnityEngine;
using System.Collections;

public class GoalPickup : Pickup
{

    // Use this for initialization
    void Start()
    {
        GameController.SpawnGoal();
    }

    // Update is called once per frame
    void Update()
    {

    }

    protected override void onPlayerCollect(PlayerController player)
    {
        Collect();
    }

    void Collect()
    {
        GameController.PlayerCollectGoal();
    }
}

我一直在尝试使用统一消息系统来通知我的子弹击中的GoalPickup。我不得不使用我的public void NotifyHitTarget(GameObject gameObject)方法在我的Bullet脚本中完成这个脚本。 GoalPickup脚本继承自分拣脚本,因此我将两个脚本与项目符号脚本一起附加。任何帮助表示赞赏,感谢您的时间。我已经尝试了很多不同的方法,广泛研究谷歌的解决方案,似乎仍然无法找到通知GoalPickup的方法,他们使用统一消息系统被击中请帮助我并抱歉我不确定的长脚本将需要哪些部分的脚本。 谢谢-Joz

1 个答案:

答案 0 :(得分:0)

要在项目符号与其发生碰撞时通知另一个对象,您需要创建另一个脚本并将其附加到该对象。让我们举一个例子,例如,假设这是一个名为Enemy的GameObject。创建一个名为EnemyScript的脚本并将其附加到该对象。创建一个名为bulletHitMe的简单公共函数,在该函数内部,当子弹与此敌人发生碰撞时,您可以执行任何操作。

以下代码是一个工作示例,

在你的EnemyScript:

public class EnemyScript: MonoBehaviour {

public void bulletHitMe(){
  Debug.Log("I was hit by the bullet");
  //Do other stuff here
 }
}

在Bullet附带的BulletScript中

void OnCollisionEnter2D (Collision2D collision)
    {

        //Get the referene of the EnemyScript attached to the GameObject that the bullet collided with.
        EnemyScript hitEnemy = collision.collider.gameObject.GetComponent<EnemyScript> ();

        //Call the function
        hitEnemy.bulletHitMe();
        CleanupBullet();
    }

你也可以使用像这个

这样的内置sendMessage的Unity来做到这一点

collision.collider.gameObject.SendMessage("bulletHitMe",SendMessageOptions.RequireReceiver);

void OnCollisionEnter2D (Collision2D collision){}

修改

您将获得NullReferenceException,因为该对象正在与未附加EneyScript的其他对象发生冲突。使用if语句来确定子弹与之碰撞的对象是否是敌人。你可以通过名字检查敌人,但我推荐的方法是标记所有敌人,然后只有当标签是敌人时才调用脚本功能。例如,我们只要说你的敌人被标记为广告“jozza710”,将此代码放在oncoll中

 void OnCollisionEnter2D (Collision2D collision){
//Check if this is an enemy before calling script
      if (collision.collider.gameObject.CompareTag("jozza710")) {
        //then you can call the script function attached to the enemy
         EnemyScript hitEnemy = collision.collider.gameObject.GetComponent<EnemyScript> ();

                //Call the function
                hitEnemy.bulletHitMe();
          } 
        CleanupBullet();
        }