Unity Добавление очков пользователю только один раз после столкновения - PullRequest
0 голосов
/ 25 июня 2018

Итак, я готовлюсь к созданию своей первой игры, я только что закончил занятия на языке C #, поэтому я прошу прощения, если я использую такие вещи, как неправильные интерфейсы и все такое.Тем не менее, на мой вопрос;Я пробую разные вещи и смотрю, что работает.Я создал монету и игрока.Монета работает так, как должна, но иногда, когда я ее собираю, она дает мне вдвое больше очков, чем должна.Стоимость монеты 15, иногда, когда я собираю монету, она прибавляет 15 очков, а иногда - 30. Как я могу предотвратить это.

Вот мой код:

Контроллер монет класса:

public class CoinController : MonoBehaviour, IEconomy {
    private int MoneyValue;

    void Start () {
        MoneyValue = 15;
    }

    void Update () {

    }

    void OnTriggerEnter(Collider col) {
        if (col.CompareTag("Player")) {
            Destroy(transform.gameObject);
            Value();
        }
    }

    public int Value() {
        return EconomyController.Money += MoneyValue;
    }
}

Контроллер эконом-класса:

public class EconomyController : MonoBehaviour{
    public static int Money;

    void Start() {
        Money = 0;
    }
}

Интерфейс эконом-класса:

public interface IEconomy {
    int Value();
}

Ответы [ 3 ]

0 голосов
/ 25 июня 2018

Моя интуиция подсказывает мне, что вы, вероятно, собираете две монеты в то время.Я не уверен, как вы раскладываете монеты, но у меня раньше была похожая проблема.

Представьте себе игру змеи.Допустим, вы запрограммировали его, поэтому, съев квадрат, вы создаете новый в случайном месте.Есть вероятность, что новый квадрат появится внутри змеи, так что он будет немедленно съеден.Это может быть то, почему это происходит только иногда.

0 голосов
/ 26 июня 2018

Попробуйте отключить коллайдер, прежде чем уничтожить его. Уничтожение игрового объекта не происходит мгновенно, и довольно неприятно несколько раз запускать триггеры.

void OnTriggerEnter(Collider col) {
     if (col.CompareTag("Player")) {
         // Pseudo Code: GetComponent<TheColliderItIs>().Enabled = false;
         Value();
         Destroy(transform.gameObject);
     }
 }
0 голосов
/ 25 июня 2018

Я хотел бы указать кое-что о вашем коде:

Хорошей практикой при объявлении переменных является использование lowerCamelCase:

thisIsLowerCamelCase
ThisIsNot

Это соглашение об именах переменных, которое широко используется впрограммирование для дифференциации Methods and Classes от variables.

Еще одна вещь, которую я заметил, состоит в том, что ваша переменная "Money" равна static, и она все еще обновляется в вашей CoinController.Я бы установил эту переменную как частную переменную int и использовал бы ее для установки.Имея это в виду ... Вы пытались использовать Debug.Log, чтобы проверить, запускается ли OnTriggerEnter дважды, прежде чем объект будет уничтожен?

Просто напишите:

Debug.Log ("This should only happen once!");

И сыграйтеигра.Если ваша консоль показывает это сообщение два раза, этот триггер вызывается дважды.Еще одна вещь, которую вы можете заметить, это то, что вы вызываете метод Value () после того, как вы вызвали Destroy (transform.gameObject).

. Я бы сделал что-то вроде:

public class CoinController : MonoBehaviour{

    private int moneyValue = 15;
    private EconomyController economyController;

    void Start (){
        economyController = FindObjectOfType (typeof (EconomyController)) as EconomyController;
    }

    void OnTriggerEnter (Collider col) {
        if (col.CompareTag("Player")) {
            AddValue();
        }
    }

    public int AddValue() {
        EconomyController.money += moneyValue; //Option one.
        EconomyController.AddMoney (moneyValue) ; //Option two.
        DestroyGameObject ();
    }

    private void DestroyGameObject (){
        Destroy(transform.gameObject);
    }
}

Используя принципы чистого кодаопция 2 использует публичную функцию void, созданную внутри класса EconomyController, изменяя частную переменную.

...