【问题标题】:decrease variable by button click C#通过按钮单击C#减少变量
【发布时间】:2021-05-15 06:38:21
【问题描述】:

我想通过单击一个按钮来减少一个值,但是它没有停留在并返回到开头的值, 这是我的代码,我应该添加或更改什么可以帮助我吗?

非常感谢

public class LifeShow : MonoBehaviour
{
    public GameObject Life; //where the variable will be decreased from
        
    public int Lifevalue;
    public string text;
    public Button returns;
    // Start is called before the first frame update
    void Start()
    {
        Lifevalue = 1;

        Life.GetComponent<Text>().text = "Life : " + Lifevalue;
    }

    // Update is called once per frame
    // clicking the button and the lifevalue variable decreases
    void Update()
    {
        Button btn = returns.GetComponent<Button>();
        btn.onClick.AddListener(TaskOnClick);



        void TaskOnClick()
        {
            Lifevalue-- ;

            Life.GetComponent<Text>().text = "Life : " + Lifevalue;

            
            

        }
    }
}

【问题讨论】:

  • 我试图在代码中的变量附近添加描述,但我不确定它应该如何,因为我是 csharp 和论坛的新手:/
  • 你确定要btn.onClick.AddListener(TaskOnClick) 每一帧吗?通常你会注册事件处理程序一次
  • 您应该将 TaskOnClick 函数移到更新函数之外。除此之外,您不需要仅针对此功能进行更新。单独创建 TaskOnClick 函数,更新函数的前 2 行应该在 start 函数内部。那应该可以。
  • 我希望每次如果生命值大于 0,在按钮点击时减少,我应该使用其他东西来点击按钮吗?
  • 是的,我对 Csharp 很陌生,我正在努力学习。感谢您的帮助

标签: c# unity3d user-interface


【解决方案1】:

您可以做的是将本地方法 void TaskOnClick() 更改为公共方法,方法是将其放在更新之外并使用 public 关键字,您可以统一添加 OnClick

现在点击“+​​”按钮并拖放脚本附加到的对象。然后你可以像这样找到

选择你的功能,你就准备好了。您不需要通过脚本执行此操作。 如果你想限制它不低于 0,你可以在脚本中添加 If 条件

if(LifeValue > 0)
{
  LifeValue--;
  // showing text
}

它将防止低于 0。

【讨论】:

  • 非常感谢您的回答,它确实有效,但我的问题是当我回到开始场景时,生命值返回 1 而不是 0,我认为我应该更新它。
  • 我希望整数在按下按钮时保持不变,当我按下按钮时它会更改整数但随后它会返回到开头的值,因此它不会减少。
  • 它可能会导致您重新启动场景或重新加载。是的,如果你重新启动它会被重置,因为它没有保存
【解决方案2】:
  • OnClick + 添加监听器
  • 将侦听器对象拖到插槽 (Life)
  • 生活脚本中的选择功能(修改)
  • 设置参数值1/-1/-99

[DisallowMultipleComponent]

public class Life : MonoBehaviour {

    public event System.Action<int> Changed; // event with INT attribute
    private int _amouth;

    public int Amouth { // this in property
        get => _amouth;
        // when you set Amouth, then change _amouth and invoke "Changed" event
        set {
            if (_amouth != value) {
                _amouth = value;
                Changed?.Invoke(_amouth);
            }
        }
    }

    private void Start () {
        Amouth = 1;
    }

    public void Modify (int number) {
        Amouth += number;
    }
}

[DisallowMultipleComponent]
[RequireComponent(typeof(Text))]

public class LifeView : MonoBehaviour { // Add Component to text object

    [SerializeField] private Life _life; // set on inspector window
    private Text _text;

    public int LineAmouth { get; private set; }

    private void OnEnable () {
        _text = GetComponent<Text>();
        UpdateText(_life.Amouth);
        _life.Changed += UpdateText; // subscribes to Life event 
    }

    private void OnDisable () {
        _life.Changed -= UpdateText;
    }

    private void UpdateText (int amouth) {
        _text.text = "Life : "+amouth;
    }
}

【讨论】:

    【解决方案3】:

    并不是真正的 Mono 专家,但首先,您似乎在每一帧都附加了一个事件处理程序,这并不好。代码应该是:

    public class LifeShow : MonoBehaviour
    {
        public GameObject Life; //where the variable will be decreased from
            
        public int Lifevalue;
        public string text;
        public Button returns;
        // Start is called before the first frame update
        void Start()
        {
            Lifevalue = 1;
    
            Life.GetComponent<Text>().text = "Life : " + Lifevalue;
            Button btn = returns.GetComponent<Button>();
            btn.onClick.AddListener(TaskOnClick);
        }
    
        // Update is called once per frame
        void Update()
        {
            
        }
    
        void TaskOnClick()
        {
            Lifevalue-- ;
            Life.GetComponent<Text>().text = "Life : " + Lifevalue;
        }
    }
    

    其次,Lifevalue 和 Life GameObject 之间的区别是什么,你能说清楚吗?

    编辑:正如 cmets 中有人所说,此代码不足以提供良好的提示,您能否展示 Life 对象的代码?那会很有帮助。

    【讨论】:

    • 非常感谢,我会努力的,life gameobject 是一个文本对象,lifevalue 是我希望出现在下一个附近的变量
    • Lifevalue 是一个整数,Life 是一个游戏对象。
    • 简单,我想我现在明白了。同样,不是 Mono 专家,但“returns”字段在哪里初始化?你调用returns.GetComponent
    • @I-am-developer-9 嗯,这很清楚 :) 我只是不知道 Life 对象有什么作用/在那里
    • 他用它来改变Life对象@Pit的Text组件的文本
    猜你喜欢
    • 2019-08-03
    • 2018-11-05
    • 1970-01-01
    • 1970-01-01
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    • 1970-01-01
    相关资源
    最近更新 更多