Search code examples
c#unity-game-engine2d-gamestopdown

Animation keeps getting triggered when I step on the tiles


I'm developing a TopDown 2D game on Unity with some RPG elements and I did as so, when the player steps on a set of tiles placed on the map, it triggers an animation with a UI showing some text. However, the animation gets called multiple times while the player keeps stepping on the tiles and even when he exits the trigger area. What I need help with is how to make the animation only trigger once and, while the UI is in on the screen, the player is not allowed to move until the player presses the button in the UI (already programmed and working). Here is the code I used to make the trigger function:

public class TriggerScript : MonoBehaviour
{
    public string popUp;
    public Animator animator;

    void Start()
    {
        animator = GetComponent<Animator>();
        
    }
    private void OnTriggerEnter2D(Collider2D collision)
    {       
            PopUpSystem pop = GameObject.FindGameObjectWithTag("GameManager").GetComponent<PopUpSystem>();
            pop.PopUp(popUp);
            Debug.Log("trigger");
            animator.SetTrigger("pop");

    }
}

And here is the PopUpSystem that sets the text:

public class PopUpSystem : MonoBehaviour
{
    public GameObject popUpBox;
    public Animator popupanimation;
    public TMP_Text popUpText;
   

    public void PopUp(string text)
    {
        
        
            popUpBox.SetActive(true);
            popUpText.text = text;
            popupanimation.SetTrigger("pop");
            
        
    }
}

If, in order to help me, you need more information and details, please ask me in the comment section.

Note that I am new to Unity and have zero experience with it so, if you can be patient and explain things in a simple way, I would enjoy that!

Thank you for reading.

Edit: this is the animator window:

enter image description here

Edit 2: The code that I use for the movement of the player:

public class PLayerController : MonoBehaviour
{
    private Rigidbody2D MyRB;
    private Animator myAnim;
    public string popUp;

    [SerializeField]
    private float speed;
    // Start is called before the first frame update
    void Start()
    {
        MyRB = GetComponent<Rigidbody2D>();
        myAnim = GetComponent<Animator>();
    }

    private void Move()
    {
        myAnim.SetTrigger("popUp");
    }
    // Update is called once per frame
    void Update()
    {
        MyRB.velocity = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical")) * speed * Time.deltaTime;
        
        myAnim.SetFloat("moveX", MyRB.velocity.x);
        myAnim.SetFloat("moveY", MyRB.velocity.y);
        if ((Input.GetAxisRaw("Horizontal")==1) ||(Input.GetAxisRaw("Horizontal") == -1)||(Input.GetAxisRaw("Vertical") == 1)||(Input.GetAxisRaw("Vertical") == -1))
        {
            myAnim.SetFloat("LastMoveX", Input.GetAxisRaw("Horizontal"));
            myAnim.SetFloat("LastMoveY", Input.GetAxisRaw("Vertical"));
        }
    }
    
}

Edit 3: Code with boolean:

public class TriggerScript : MonoBehaviour
{
    public string popUp;
    public Animator animator;
    bool condition = false;

    void Start()
    {
        animator = GetComponent<Animator>();
        
    }
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (condition == false)
        {
            PopUpSystem pop = GameObject.FindGameObjectWithTag("GameManager").GetComponent<PopUpSystem>();
            pop.PopUp(popUp);
            Debug.Log("trigger");
            animator.SetTrigger("pop");
            condition = true;
        }
            
    }
    private void OnTriggerExit2D(Collider2D collision)
    {
        animator.SetTrigger("close");
    }

Solution

  • All you have to do is to set your TriggerScript to something like this:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class TriggerScript : MonoBehaviour
    {
        public string popUp;
    
        private void OnTriggerEnter2D(Collider2D collision)
        {
            PopUpSystem pop = GameObject.FindGameObjectWithTag("GameManager").GetComponent<PopUpSystem>();
            if (collision.gameObject.tag == "Player")
            {
                pop.PopUp(popUp);
            }
                
        }
        private void OnTriggerExit2D(Collider2D collision)
        {
            PopUpSystem pop = GameObject.FindGameObjectWithTag("GameManager").GetComponent<PopUpSystem>();
            pop.closeBox();
        }
    }
    

    and then set your PopUpSystemScript to something like this:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using TMPro;
    
    public class PopUpSystem : MonoBehaviour
    {
        public GameObject popUpBox;
        public Animator popupanimation;
        public TMP_Text popUpText;
    
        public void PopUp(string text)
        {                
            popUpBox.SetActive(true);
            popUpText.text = text;
            popupanimation.SetTrigger("pop");         
        }
    
        public void closeBox()
        {
            popupanimation.SetTrigger("close"); 
        }
    }
    

    Now click on the popUp and close animation clips (in Animations folder) and remove the Loop Time check mark. and you should be all set to see the animation appears and disappears.

    To stop the player, you can either use Time.timeScale. or set the rigidbody to isKenimatic.