Мой счет очков в Unity продолжает случайным образом снижаться

У меня есть игра, в которой каждый раз, когда вы убиваете зомби, вы получаете одно очко. Это работает, однако по какой-то причине иногда, когда я убиваю зомби, счет снижается случайным образом, хотя я никогда не кодировал это так, чтобы счет мог уменьшаться. Вот сценарий столкновения, в котором подсчитывается счет. Я готов ответить на любые ваши вопросы, ребята. Спасибо! Нажмите здесь, чтобы увидеть Видеоматериалы из игры

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

public class CollisionScript : MonoBehaviour
{
    private int killCount;
    public Text scoreCount;

    private void OnCollisionEnter2D(Collision2D other)
    {
        if (other.gameObject.CompareTag("zombie"))
        {
            Destroy(other.gameObject);
            killCount += 1;
            scoreCount.text = "Kill Count: " + killCount.ToString();
        }
    }
}

Я попытался увидеть, есть ли какая-то конкретная закономерность в снижении счета, но это оказалось совершенно случайным.

Вы должны использовать другой экземпляр класса или вы вызываете конструктор с «новым». Опубликованный код позволяет только увеличивать количество убийств.

jdweng 15.04.2023 19:11

К сожалению, здесь недостаточно, чтобы воспроизвести проблему

BugFinder 15.04.2023 19:17

Я редактировал некоторые игровые процессы, так что посмотрите, поможет ли это вообще. Спасибо!

user21491858 17.04.2023 00:29
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
54
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Настоящий код не уменьшает значение счетчика. Как прокомментировал @jdweng, вы, вероятно, видите вывод разных экземпляров этих вызовов.

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

public class CollisionScript : MonoBehaviour
{
    private static _globalCounter;       // <===
    private _number;                     // <===

    private int killCount;
    public Text scoreCount;

    public CollisionScript()             // <===
    {
        _number= ++_globalCounter;      // <===
    }

    private void OnCollisionEnter2D(Collision2D other)
    {
        if (other.gameObject.CompareTag("zombie"))
        {
            Destroy(other.gameObject);
            killCount += 1;
            scoreCount.text = $"#{_number}: Kill Count: {killCount}";   // <===
        }
    }
}

Обратите внимание, что Unity вызывает конструкцию чаще, чем вы ожидаете, так что не беспокойтесь о пропущенных числах.

Спасибо за ответ! Однако это, похоже, не сработало. Я загрузил немного геймплея, так что если вы хотите, вы можете посмотреть, поможет ли это.

user21491858 17.04.2023 00:28
Ответ принят как подходящий

Другие уже указали на проблему. Вы запускаете два экземпляра CollisionScript на каждом мече. В зависимости от того, какой меч сталкивается с зомби во время физического тика, отображается различный внутренний счетчик убийств. Вот почему оценка иногда отскакивает на несколько значений назад, а затем внезапно возвращается к высокому значению.

Вы можете превратить killCount в статический или сделать KillManager, который вместо этого отслеживает killCount.

public class KillManager : MonoBehaviour
{
  private int killCount;
  public Text scoreCount;

  public void AddPoint()
  {
    killCount++;
    scoreCount.text = "Kill Count: " + killCount.ToString();
  }
}

public class CollisionScript : MonoBehaviour
{
  public KillManager manager;

  private void OnCollisionEnter2D(Collision2D other)
  {
    if (other.gameObject.CompareTag("zombie"))
    {
      Destroy(other.gameObject);
      manager.AddPoint();
    }
  }
}

Таким образом, вы никогда не увидите уменьшение счета, но вы заметите еще одну ошибку. Если на одной и той же физике оба меча коснутся одного и того же зомби, вы получите два очка. Чтобы решить эту проблему, у вас есть несколько вариантов.

1. Используйте коллайдер с одним ящиком

В вашем случае мечи держатся в форме коробки. Нет веской причины подгонять два отдельных коллайдера к каждому мечу. Подойдет приближение с одной коробкой, и игроку все равно. Одна коробка означает одно столкновение и один счетчик убийств. Дисплей не используется совместно с другим ресурсом.

2. Добавьте убитого булла к своему Зомби.

Вы можете добавить общедоступное логическое значение к сценарию, который запускает ваш зомби. Когда меч встречается с плотью нежити, вы можете быстро проверить логическое значение, чтобы увидеть, был ли зомби уже убит чем-то другим. Если это не так, вы увеличиваете счет и отмечаете зомби как убитого.

public class Zombie : MonoBehaviour
{
  public bool killed = false;
}

public class CollisionScript : MonoBehaviour
{
  public KillManager manager;

  private void OnCollisionEnter2D(Collision2D other)
  {
    if (other.gameObject.CompareTag("zombie"))
    {
      Zombie zombie = other.gameObject.GetComponent<Zombie>();
      if (!zombie.killed)
      {
        Destroy(other.gameObject);
        manager.AddPoint();
        zombie.killed = true;
      }
    }
  }
}

Большое спасибо. Все это имеет большой смысл. Я думаю, что я выберу подход с одним коллайдером. Ваш спасатель жизни!

user21491858 18.04.2023 21:41

Другие вопросы по теме