Видимость игрового объекта Unity — невозможно отобразить игровой объект более одного раза

#c# #unity3d #gameobject

#c# #unity3d #gameobject

Вопрос:

У меня есть холст с изображением и TextMeshPro (TMP) в качестве дочернего элемента, а для компонента canvas диалогового окна в методе Start() установлено значение false, чтобы скрыть его в главном холсте. TMP отображается поверх изображения (как текст внутри диалогового окна). У меня есть игрок и монетный спрайт в 2D-среде. Когда игрок поднимает монету, я пытаюсь отобразить диалоговое окно и TMP, как показано ниже.

 public class PlayerMovement : MonoBehaviour {

    public GameObject suggestion;
    public GameObject dialogBox;

    private bool wasSuggestionShown; //to check if dialog was shown

    private void Start()
    {
        wasSuggestionShown = false;
        suggestionTimer = 0;
        dialogBox.GetComponent<Canvas>().enabled = false; //To hide the dialog box
    }

    void Update () {

        //horizontalMove = Input.GetAxisRaw("Horizontal") * runSpeed; // for pc keys
        horizontalMove = CrossPlatformInputManager.GetAxis("Horizontal") * runSpeed; //for smartphone input

        if (wasSuggestionShown)
        {
            suggestionTimer  = Time.deltaTime;
            if (suggestionTimer > 5)
            {
                wasSuggestionShown = false;
                dialogBox.GetComponent<Canvas>().enabled = false; //TO hide dialog box after displaying it
            }
        }
    }

    void FixedUpdate ()
    {
        // Move the character
        controller.Move(horizontalMove * Time.fixedDeltaTime, crouch, jump);
        jump = false;
    }


    //For destroying coin object on collision with player
    private void OnTriggerEnter2D(Collider2D col)
    {
        
        if (col.gameObject.CompareTag("coin"))
        {

            //For destroying coin and to recude player movement speed.

            Destroy(col.gameObject); //Coin Disappears

            isRunSpeedReduced = true;
            runSpeed = 10f;

            //For Showing dialog box

            dialogBox.GetComponent<Canvas>().enabled = true;
            wasSuggestionShown = true;
        }
    }
}
  

В OnTriggerEnter2D() методе я проверяю, касается ли персонаж игрока монеты, и если да, я уничтожаю объект и отображаю диалоговое окно и TMP и скрываю их через 5 секунд. Проблема в том, что

«Когда я включаю другую монету, то же диалоговое окно и TMP не отображаются, когда игрок выбирает вторую монету. Обе монеты имеют одинаковый тег «монета» «

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

Кроме того, способ переключения диалогового окна не имеет значения. Будь то он dialogBox.GetComponent<Canvas>().enabled = true; или dialogBox.SetActive(true) любой из них отображается только один раз, и это первое событие.

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

Иерархия сцен:

введите описание изображения здесь

Комментарии:

1. Пожалуйста, покажите свою иерархию сцен. 🙂

2. @ Погружение выполнено. Диалоговое окно имеет TMP в качестве дочернего элемента.

3.Пожалуйста, убедитесь, что используете правильные теги. Ваш код находится c# не в unityscript том, который является или лучше был похож на язык JavaScript, используемый в предыдущих версиях Unity, и к настоящему времени давно устарел.

Ответ №1:

Проблема заключается в Update() том, что вы отключаете холст после suggestionTimer того, как тики закончились:

 void Update () {

    //horizontalMove = Input.GetAxisRaw("Horizontal") * runSpeed; // for pc keys
    horizontalMove = CrossPlatformInputManager.GetAxis("Horizontal") * runSpeed; //for smartphone input

    if (wasSuggestionShown)
    {
        suggestionTimer  = Time.deltaTime;
        if (suggestionTimer > 5)
        {
            wasSuggestionShown = false;
            dialogBox.GetComponent<Canvas>().enabled = false; //TO hide dialog box after displaying it
        }
    }
}
  

Причина в том, что вы никогда не сбрасываете значение suggestionTimer при выпадении новой монеты. Сделайте это:

 private void OnTriggerEnter2D(Collider2D col)
{
    
    if (col.gameObject.CompareTag("coin"))
    {

        //For destroying coin and to recude player movement speed.

        Destroy(col.gameObject); //Coin Disappears

        isRunSpeedReduced = true;
        runSpeed = 10f;

        //For Showing dialog box

        dialogBox.GetComponent<Canvas>().enabled = true;
        wasSuggestionShown = true;

        //  !!! ADD THIS
        suggestionTimer = 0;
    }
}
  

Комментарии:

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

Ответ №2:

Проблема в том OnTriggerEnter2D , что вы включаете, устанавливаете wasSuggestionShown = true , а затем в самом следующем методе обновления проверяете wasSuggestionShown , видите, что это правда, и сразу же отключаете canvas.

Это может помочь. Это всего лишь один из дюжины способов, которые могут помочь:

 private bool _showSuggestion = true;
public bool showSuggestion
{
  get { return _showSuggestion; }
  set   
  {
    if ( !value amp;amp; _showSuggestion )
    {
      dialogBox.SetActive ( false );
      _showSuggestion = value;
    }
  }
}


void Update () {

    //horizontalMove = Input.GetAxisRaw("Horizontal") * runSpeed; // for pc keys
    horizontalMove = CrossPlatformInputManager.GetAxis("Horizontal") * runSpeed; //for smartphone input

    if ( showSuggestion )
    {
        suggestionTimer  = Time.deltaTime;
        if ( suggestionTimer > 5f ) showSuggestion = false;
    }
}
  

Приведенный выше код будет ждать, пока в первый раз вы не установите showSuggestion значение false, а затем после этого игнорируйте любые дальнейшие попытки включить предложения. Я подозреваю, что это то, чего вы хотели бы? Если я неправильно понимаю ситуацию, код можно немного изменить, чтобы получить правильное поведение.

Комментарии:

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