Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

Stopping Character Movement through a Function/Trigger help

Discussion in 'Editor & General Support' started by Howelly123, Jan 18, 2018.

  1. Howelly123

    Howelly123

    Joined:
    Jan 18, 2018
    Posts:
    5
    So my one level game to test BCI applications on is complete, but if the player produces a 'Game Over', they can still move the character (just a ball) around for the duration of the 3 second respawn timer. I don't even need the ball to vanish upon death - just removing player input for the 3 seconds would be enough.

    This is the code for the movement:
    Code (csharp):
    1.  
    2. private Rigidbody rb;
    3.  
    Code (csharp):
    1.  
    2. rb = GetComponent<RigidBody>();
    3.  
    Code (csharp):
    1.  
    2. void FixedUpdate () //Using Physics to move the ball (applying forces to the Rigidbody)
    3.     {
    4.         float moveHorizontal = Input.GetAxis ("Horizontal"); //This is the x value (left to right movement).
    5.         float moveVertical = Input.GetAxis ("Vertical"); //This is the z value (forwards and backwards movement).
    6.  
    7.         Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical); //These x, y ,z values determine the direction of the force added to the ball.
    8.  
    9.         rb.AddForce (movement * speed); //Default force mode by ommitting it from the code, using vector 3, a simple RigidBody AddForce. We can control this value from inside the editor with 'speed' added.
    10.     }
    11.  
    12.     public void  GameOver(){
    13.         StartCoroutine("Wait");
    14.     }
    15.  

    This is the restart level function:

    Code (csharp):
    1.  
    2. IEnumerator RestartLevel() {
    3.         yield return new WaitForSeconds(3f);
    4.         int scene = SceneManager.GetActiveScene().buildIndex;
    5.         SceneManager.LoadScene(scene, LoadSceneMode.Single);
    6.     }
    7.  
    Which is called here:
    Code (csharp):
    1.  
    2. void SetHealthText ()
    3.     {
    4.         healthText.text = "Health: " + health.ToString ();
    5.         if (health <= 0)
    6.         {
    7.         loseText.text = "Game Over";
    8.         StartCoroutine(RestartLevel());
    9.         }
    10.    
    11.     }
    12.  
    In addition, upon building the game and playing it, the application is meant to close 5 seconds after the objective is met, but it doesn't. The code is:

    Code (csharp):
    1.  
    2. IEnumerator CloseGame(){
    3.         yield return new WaitForSeconds(5f);
    4.         Application.Quit();
    5.     }
    6.  
    Which is called in:

    Code (csharp):
    1.  
    2.     void SetCountText ()
    3.     {
    4.         countText.text = "Cubes Collected: " + count.ToString () + "/10"; // Adds the value of count to the countText property e.g. "Count: 1".
    5.         if (count >= 10) //If the player has collected all of the cubes
    6.         {
    7.                 winText.text = "You Win!";
    8.                 CloseGame ();
    9.         }
    10.            
    11.     }
    12.  
    I've looked around for ages and the results I'm finding don't seem to solve the issue, any help would be greatly appreciated!
     
  2. apushak

    apushak

    Joined:
    Jan 13, 2015
    Posts:
    5
    Calling a coroutine from your GameOver method isn't going to block the FixUpdate from running. You'll want a bool that gets set when you GameOver that prevents the FixedUpdate from applying user input. You can do that like this:
    Code (CSharp):
    1. private bool inputEnabled = true;
    2.  
    3. void FixedUpdate () //Using Physics to move the ball (applying forces to the Rigidbody)
    4. {
    5.     if (!inputEnabled)
    6.         return;
    7.     float moveHorizontal = Input.GetAxis ("Horizontal"); //This is the x value (left to right movement).
    8.     float moveVertical = Input.GetAxis ("Vertical"); //This is the z value (forwards and backwards movement).
    9.     Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical); //These x, y ,z values determine the direction of the force added to the ball.
    10.     rb.AddForce (movement * speed); //Default force mode by ommitting it from the code, using vector 3, a simple RigidBody AddForce. We can control this value from inside the editor with 'speed' added.
    11. }
    12. public void  GameOver()
    13. {
    14.     inputEnabled = false;
    15. }
    If you reuse the same ball when you restart the level rather than creating a new one, you'll need to set inputEnabled back to true to get inputs working again.

    The game isn't closing when you complete the objective because you're calling CloseGame directly instead of calling it as a coroutine. You should call it like this:
    Code (CSharp):
    1. StartCoroutine(CloseGame());
     
    Howelly123 likes this.
  3. Howelly123

    Howelly123

    Joined:
    Jan 18, 2018
    Posts:
    5

    Thank you very much, both of your suggestions worked!