简体   繁体   English

Unity 游戏对象可见性 - 无法多次显示游戏对象

[英]Unity Game Object Visibility - Unable to display Game Object more than once

I have a Canvas with an Image and a TextMeshPro (TMP) as a child, and the dialog's canvas component is set to false in the Start() method so as to hide it in the main Canvas.我有一个带有 Image 和 TextMeshPro (TMP) 的 Canvas 作为子项,并且对话框的 canvas 组件在 Start() 方法中设置为 false 以便将其隐藏在主 Canvas 中。 The TMP appears over the image (like a text inside a dialog box). TMP 出现在图像上(就像对话框中的文本)。 I have a player and a coin sprite in a 2D environment.我在 2D 环境中有一个播放器和一个硬币精灵。 When the player picks up the coin, I try to display the dialog box and the TMP as shown below.当玩家拿起硬币时,我尝试显示如下所示的对话框和 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;
        }
    }
}

In the OnTriggerEnter2D() method, I check if the player character touches the coin and if so, I destroy the object and display the dialog box and TMP and hide them after 5 seconds.OnTriggerEnter2D()方法中,我检查玩家角色是否接触硬币,如果是,我销毁对象并显示对话框和 TMP 并在 5 秒后隐藏它们。 The problem is that问题是

"When I include another coin, the same dialog box and TMP, do not show up when the player picks the second coin. Both the coins have the same tag 'coin' " “当我包含另一个硬币时,相同的对话框和 TMP,在玩家选择第二个硬币时不会出现。两个硬币都有相同的标签“硬币””

One may argue that if the script is in the same object which was destroyed or is inactive, then it is impossible.有人可能会争辩说,如果脚本在同一个被销毁或不活动的对象中,那么这是不可能的。 But I am doing all of this in the Player's movement script which is attached to the player Object.但是我是在附加到玩家对象的玩家移动脚本中完成所有这些操作的。

Also, the way that I toggle the dialog box does not make a difference.此外,我切换对话框的方式没有任何区别。 Be it dialogBox.GetComponent<Canvas>().enabled = true;dialogBox.GetComponent<Canvas>().enabled = true; or dialogBox.SetActive(true) Either of these display only once and that is the first occurence.dialogBox.SetActive(true)任何一个只显示一次,并且是第一次出现。

Even if I want to instantiate it, I don't know the exact transforms to position it properly in the canvas.即使我想实例化它,我也不知道在画布中正确定位它的确切变换。 (I want it in the bottom middle part, like how it can be anchored) (我想要它在底部中间部分,就像它可以锚定一样)

Scene Hierarchy:场景层次:

在此处输入图片说明

The issue is in your Update() , where you turn off the canvas after suggestionTimer ticks over:问题出在您的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
        }
    }
}

The cause is that you never reset the suggestionTimer when you hit a new coin.原因是您在击中新硬币时从未重置过suggestionTimer计时器。 Do this:做这个:

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;
    }
}

The problem is that on OnTriggerEnter2D , you set wasSuggestionShown = true , and then in the very next Update method, you're checking wasSuggestionShown , seeing that it's true, and turning the canvas off again straight away.问题是在OnTriggerEnter2D ,您设置wasSuggestionShown = true ,然后在下一个 Update 方法中,您正在检查wasSuggestionShown ,看到它是真的,然后立即再次关闭画布。

This might help.这可能会有所帮助。 It's just one, of a dozen ways, that could help:这只是十几种方法中的一种,可以提供帮助:

private bool _showSuggestion = true;
public bool showSuggestion
{
  get { return _showSuggestion; }
  set   
  {
    if ( !value && _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;
    }
}

The code above will wait until the first time you set showSuggestion to false, and then after that, ignore any further attempt to turn the suggestions on.上面的代码将等到您第一次将showSuggestion设置为 false,然后忽略任何进一步打开建议的尝试。 Which I suspect that's what you'd like?我怀疑这就是你想要的? If I'm reading the situation wrong, the code can be jiggled a little to get the right behaviour.如果我读错了情况,可以稍微调整代码以获得正确的行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM