Изменение параметров при нажатие кнопки на unity

Рейтинг: 1Ответов: 1Опубликовано: 22.08.2023

У меня возникла задача изменения значения набора очков с помощью кнопок, причем каждая кнопка должна иметь свою скорость набора очков. Другими словами, каждая кнопка будет являться своего рода "апгрейдом" для параметра, определяющего скорость набора очков.

Вот первый скрипт:

using System;
using UnityEngine.UI;

[Serializable]
public class Score
{
    public Text text;
    public int score;

    // Если просто изменять score, то у нас не изменится Text
    // Поэтому добавляем метод для изменения 
    // (P.S.: Рекомендую изучить getter и setter)
    public void SetScore(int score)
    {
        this.score = score;
        text.text = score.ToString();
    }
}

Вот второй скрипт

public class Game : MonoBehaviour
{
    public Score sub;
    public Score money;
    public Score top;

    private void Start()
    {
        StartCoroutine(CountPoints(sub, 10000)); // Добавляем 10000 очков
        StartCoroutine(CountPoints(money, 10000)); // Добавляем 10000 монет
        StartCoroutine(CountPoints(top, -1000)); // убираем 1000 очков
    }

    IEnumerator CountPoints(Score scoreObject, int increase)
    {
        // Чем больше количество очков, тем меньше задержа
        // Таким образом очки будут накапливаться всегда за increaseTimeInSeconds секунд
        float delay = 1f / increase * increaseTimeInSeconds; 

        for (var i = 0; i < increase; i++)
        {
            scoreObject.SetScore(scoreObject.score+1); // Добавляем очки
            yield return new WaitForSeconds(delay); // Ждём
        }
    }

Ответы

▲ 3Принят

В скрипте вначале разобраться надо было, позапускать там его, что бы такие пустяковые вопросы не задавать)

Первым делом заменим score и SetScore на getter/setter как я тебе говорил.

Обновляем скрипт Score.cs:

[Serializable]
public class Score
{
    [SerializeField] Text text;
    int points;
    public int Points
    {
        get => points;
        set
        {
            points = value;
            // Если элемент Text сущетсвует, то обновляем его
            if (text != null)
                text.text = points.ToString();
        }
    }
}

И соответственно заменим

scoreObject.SetScore(scoreObject.score+1);

на

scoreObject.Points++;

А метод CountPoints() переименуем в IncreaseScorePointsBy() для простоты понимания

Напомню, что этот метод добавляет указанное количество к текущему количеству очков

А вот теперь переходим к вопросу

Если тебе надо изменить общую скорость изменения очков, то ты можешь просто изменить переменную increaseTimeInSeconds, однако в таком случае надо убрать у неё свойство const

Но как я понял ты хочешь, что бы у тебя постоянно накапливались очки (а не на определённое количество)

Давай напишем для этого метод в Score.cs:

public float IncreaseDelayInSeconds;
public IEnumerable StartIncrease()
{
    while (true)
    {
        Points++;
        yield return new WaitForSeconds(IncreaseDelayInSeconds);
    }
}

Теперь запустив каротину StartIncrease() каждые IncreaseDelayInSeconds секунд будет добавляться 1 очко в счёт Score

Примерно так это будет использоваться:

StartCoroutine(money.StartIncrease()); // Запускаем увеличение количества очков (1 раз в секунду)
public void OnButtonPressed() 
{
    // Увеличиваем скорость добавления очков в 2 раза
    // Уменьшая задержку между добавлением очков в 2 раза
    money.IncreaseDelayInSeconds /= 2; 
}

Теперь переходим к кнопкам

У кнопки в инспекторе есть событие OnClick()

OnClick

Мы добавляем новый элемент и перетаскиваем мышкой объект с нашим скриптом

Object

И выбираем функцию, которую мы хотим вызывать при нажатии на кнопку

Select function

Готово! Можно проверять

А вообще, если ты делаешь кликер, то лучше не изменять скорость добавления и уменьшения очков, а вынести Score.IncreaseDelayInSeconds как параметр в метод StartIncrease(float delay)

Полный код:

Score.cs:

using System;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;

[Serializable]
public class Score
{
    [SerializeField] Text text;
    int points;
    public int Points
    {
        get => points;
        set
        {
            points = value;
            // Если элемент Text сущетсвует, то обновляем его
            if (text != null)
                text.text = points.ToString();
        }
    }

    public float IncreaseDelayInSeconds = 1f;
    public IEnumerator StartIncrease()
    {
        while (true)
        {
            Points++;
            yield return new WaitForSeconds(IncreaseDelayInSeconds);
        }
    }
}

Game.cs:

using System.Collections;
using UnityEngine;

public class Game : MonoBehaviour
{
    float increaseTimeInSeconds = 1f;

    public Score sub;
    public Score money;
    public Score top;

    private void Start()
    {
        StartCoroutine(IncreaseScorePointsBy(sub, 100)); // Добавляем 10000 очков
        StartCoroutine(IncreaseScorePointsBy(money, 200)); // Добавляем 10000 монет
        StartCoroutine(IncreaseScorePointsBy(top, -100)); // убираем 1000 очков
        StartCoroutine(money.StartIncrease()); // Запускаем увеличение количества очков (1 раз в секунду)
    }

    public void OnButtonPressed()
    {
        // Увеличиваем скорость добавления очков в 2 раза
        // Уменьшая задержку между добавлением очков в 2 раза
        money.IncreaseDelayInSeconds /= 2f;  
        
    }

    IEnumerator IncreaseScorePointsBy(Score scoreObject, int increase)
    {
        // Чем больше количество очков, тем меньше задержа
        // Таким образом очки будут накапливаться всегда за increaseTimeInSeconds секунд
        float delay = 1f / increase * increaseTimeInSeconds;

        for (var i = 0; i < increase; i++)
        {
            scoreObject.Points++;
            yield return new WaitForSeconds(delay); // Ждём
        }
    }
}