【问题标题】:Disable instantiate and button click禁用实例化和按钮单击
【发布时间】:2015-12-12 22:50:47
【问题描述】:

我面临两个对象和一个按钮的问题。一个是立方体,第二个是地面,当我们单击按钮时立方体与地面碰撞并再次实例化。立方体碰撞分数是递减的。在层次结构中还有一个空游戏对象,它的名称是控制器,它具有文本分数的方法。分数工作正常,但我希望当分数为 0 时按钮单击不起作用并且立方体没有实例化。

立方体:

地面:

控制器:

立方体脚本:

public class Cube : MonoBehaviour {

    Rigidbody2D body;

    void Start () {
        body = GetComponent<Rigidbody2D>();
        body.isKinematic = true;
    }

}

基础脚本:

public class Ground : MonoBehaviour {

    private Button button;
    private BoxCollider2D collide;
    public GameObject object1Clone;

    void Start () {

        collide = GetComponent<BoxCollider2D>();

        collide.isTrigger = true;

        button = GameObject.FindGameObjectWithTag ("Button").GetComponent<Button> ();

        button.onClick.AddListener (() => Magnetic ());

    }

    void OnTriggerEnter2D(Collider2D target) {

            Destroy (target.gameObject);
            Instantiate (object1Clone, new Vector3 (0f, 4.12f, 0f), Quaternion.identity);

    }

    public void Magnetic(){

        GameObject.FindGameObjectWithTag ("Player").GetComponent<Rigidbody2D> ().isKinematic = false;

    }


}

评分脚本:

public class ScoreScript : MonoBehaviour {
    public static int Score=1;


    void OnTriggerEnter2D(Collider2D target) {

        if (Score <=0) {



        } else {
            Score--;
            Controller.instance.SetScore(Score);
        }


    }
}

控制器:

public class Controller : MonoBehaviour {
    public static Controller instance;
    public Text scoreText;

    void Start () {
        scoreText.text = ""+1;

        if(instance==null){

            instance=this;
        }

    }

    public void SetScore(int score){

        scoreText.text =""+score;

    }

}

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    首先将监听器注册改成这样:

     button.onClick.AddListener (Magnetic);
    

    这将使移除监听器变得更容易。

    我将向您展示两种方法,一种简单的方法,一种更难掌握的适当方法。因此,如果您不太明白,请使用第一个并了解第二个。

    每次降低分数时,检查它并呼吁采取适当的行动:

    public class ScoreScript : MonoBehaviour {
        public static int Score=1;
    
        void OnTriggerEnter2D(Collider2D target) 
        {
             Score--;
             Controller.instance.SetScore(Score);
             if(Score <= 0){
                GameObject.Find("ground").GetComponent<Ground>().ClearButtonListener();
             }
        }
    }
    

    在地面组件中:

    public void ClearButtonListener()
    {
        button.onClick.RemoveListener (Magnetic);
    }
    

    现在第二种更合适的方法是使用事件和监听器

    public class ScoreScript : MonoBehaviour, IScoreHandler {
        public static int Score=1;
        public event Action OnScoreZero = () => {};
        void OnTriggerEnter2D(Collider2D target) 
        {
             Score--;
             Controller.instance.SetScore(Score);
             if(Score <= 0){
                OnScoreZero();
             }
        }
    }
    public interface IScoreHandler{ event Action OnScoreZero; }
    

    你的听众会听。

    public class Ground : MonoBehaviour {
    
        private Button button;
        private BoxCollider2D collide;
        public GameObject object1Clone;
        private IScoreHandler scoreHandler = null;
        void Start () {
            scoreHandler = GameObject.Find("Score").GetComponent<IScoreHandler>();
            if(scoreHandler != null){
                 scoreHandler.OnScoreZero += ClearButtonListener;
            }
            collide = GetComponent<BoxCollider2D>();
    
            collide.isTrigger = true;
    
            button = GameObject.FindGameObjectWithTag ("Button").GetComponent<Button> ();
    
            button.onClick.AddListener (Magnetic);
        }
        void OnDestroy(){
             if(scoreHandler != null){
                  scoreHandler.OnScoreZero -= ClearButtonListener;
             }
        }
    }
    

    多亏了接口和事件,您的类不再依赖于另一个类,而是依赖于一个接口,这使得它更加灵活和可扩展。

    【讨论】:

    • 你的底线是底线,错字。我看到你走的是简单的路:)。
    • 其实由于 Ground 组件和 ScoreScript 组件在同一个对象上,所以可以跳过对象搜索,只使用 GetComponent
    • 如果我使用你的第一种方法然后得分停止在 0 而不是点击 0 得分
    • 为什么你把空间放在 Action OnScoreZero 编译器说错了
    • 这就是你声明一个动作的方式。您还需要 System 命名空间: using System;。我不太明白你的意思,它停在 0 而不是点击。请避免说“回复评论”之类的话,这听起来像是命令。你知道,我有权离开我的电脑一段时间,就像我在电脑之外过着自己的生活一样。
    【解决方案2】:

    需要将UnityEngine.UI.Button对象的interactable字段设置为false,见http://docs.unity3d.com/ScriptReference/UI.Button.html,即使用

    void OnTriggerEnter2D(Collider2D target) {
        if (Score <=0) {
            /* disable the button */
            GameObject.FindGameObjectWithTag ("Button").GetComponent<Button>().interactable = false;
        } 
    

    在您的ScoreScript.cs

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-03
      • 1970-01-01
      • 2012-04-07
      • 2011-01-20
      相关资源
      最近更新 更多