Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Going crazy over this !! Jump on mouse release, not click !!

Discussion in 'Scripting' started by Jeezker, Apr 21, 2014.

  1. Jeezker

    Jeezker

    Joined:
    Sep 25, 2013
    Posts:
    51
    Allright I am making my first game, which is a stupid flappy bird clone.

    I am using this script, and the bee jumps when the mouse button is released, not clicked, therefore it gives the illusion of huge delay.

    How can I modify it to make it instant, when the button is pressed down, because I've been struggling for the past 2 hours.

    Here's the script, thanks a lot!!

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Bee : MonoBehaviour {
    5.    
    6.     public float jumpSpeed = 2; // The JumpSpeed
    7.     public float gravity = 3; // The Gravity
    8.     public AudioClip pipePassSound; // A sound played when the bee passes a pipe.
    9.    
    10.     public GUISkin flyGUISkin; // The GUISkin used for the game
    11.     public GUISkin _GUISkin;
    12.    
    13.     public Vector2 moveDir; // The direction.
    14.     private float vSpeed; // The vertical speed of the bee.
    15.     private Transform myTransform; // The bee's transform.
    16.     private Rigidbody2D _Rigidbody2D; // The bee's rigidbody2D.
    17.     private bool moveBee = true; // Bool used to check if the bee should be moved.
    18.    
    19.     private bool gameOver = false;
    20.     private Rect gameOverRect;
    21.     private int currentScore = 0;
    22.    
    23.     void Awake ()
    24.     {
    25.         //Set up some references.
    26.         myTransform = transform;
    27.         _Rigidbody2D = transform.rigidbody2D;
    28.     }
    29.    
    30.     void FixedUpdate()
    31.     {
    32.         //Rotate the player according to the move direction. (up or down) needs some fixing
    33.         myTransform.eulerAngles = new Vector3(myTransform.eulerAngles.x, myTransform.eulerAngles.y, myTransform.eulerAngles.z + vSpeed*50*Time.deltaTime);
    34.        
    35.         if(moveBee) // If it's true, move the bee.
    36.         {
    37.             if(_Rigidbody2D.velocity.y != moveDir.y)
    38.             {
    39.                 _Rigidbody2D.velocity = moveDir; // Set the velocity to the move direction
    40.             }
    41.         }
    42.        
    43.         vSpeed -= gravity*Time.deltaTime; // Set the correct gravity on the Bee.
    44.        
    45.         if(moveBee)
    46.         {
    47.             if(moveDir.y != vSpeed)
    48.             {
    49.                 moveDir.y = vSpeed;
    50.             }
    51.         }
    52.         else
    53.         {
    54.             if(moveDir.y != 0)
    55.             {
    56.                 moveDir.y = 0;
    57.             }
    58.         }
    59.     }
    60.    
    61.     void OnTriggerEnter2D(Collider2D other)
    62.     {
    63.         if(other.CompareTag("Enemy"))
    64.         {
    65.             moveBee = false;
    66.             moveDir.x = 0;
    67.             moveDir.y = 0;
    68.            
    69.             StartCoroutine(PauseLevelAfterTime(2.0f));
    70.         }
    71.        
    72.         if(other.CompareTag("Pass"))
    73.         {
    74.             currentScore += 1;
    75.             audio.PlayOneShot(pipePassSound);
    76.             other.enabled = false;
    77.         }
    78.     }
    79.    
    80.     void GameOverWindow(int windowID)
    81.     {
    82.         GUI.skin = _GUISkin;
    83.        
    84.         GUILayout.Space(Screen.height / 5);
    85.        
    86.         GUILayout.Label("GAME OVER");
    87.        
    88.         GUILayout.Space(Screen.height / 20);
    89.        
    90.         GUILayout.Label("Score: " + currentScore);
    91.        
    92.         GUILayout.Label("Best: " + PlayerPrefs.GetInt("Best"));
    93.        
    94.         GUILayout.BeginHorizontal();
    95.        
    96.         if(GUILayout.Button("Restart", GUILayout.Height(Screen.height / 8)))
    97.         {
    98.             Time.timeScale = 1.0F;
    99.             Application.LoadLevel(Application.loadedLevel);
    100.         }
    101.        
    102.         if(GUILayout.Button("Highscore", GUILayout.Height(Screen.height / 8)))
    103.         {
    104.             Debug.Log("Highscore");
    105.         }
    106.        
    107.         GUILayout.EndHorizontal();
    108.     }
    109.    
    110.     void OnGUI ()
    111.     {
    112.         if(gameOver == true)
    113.         {
    114.             GUI.skin = _GUISkin;
    115.            
    116.             gameOverRect = new Rect(0 , 0, Screen.width, Screen.height);
    117.            
    118.             gameOverRect = GUILayout.Window(1, gameOverRect, GameOverWindow, "");
    119.         }
    120.         else
    121.         {
    122.             GUI.skin = flyGUISkin;
    123.            
    124.             GUI.Label(new Rect(0, 0, Screen.width, Screen.height / 8), "" + currentScore);
    125.            
    126.             if (GUI.Button(new Rect(0, 0, Screen.width, Screen.height), ""))
    127.             {
    128.                 vSpeed = jumpSpeed;
    129.             }
    130.         }
    131.     }
    132.    
    133.     IEnumerator PauseLevelAfterTime(float delay)
    134.     {
    135.         yield return new WaitForSeconds(delay);
    136.         Time.timeScale = 0.0f;
    137.         gameOver = true;
    138.        
    139.         if(currentScore > PlayerPrefs.GetInt("Best"))
    140.         {
    141.             PlayerPrefs.SetInt("Best", currentScore);
    142.         }
    143.     }
    144. }
    145.  
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,773
    The root of your problem is that you're using OnGUI for main game controls, which it is not at all designed for.

    Put your control logic into Update() instead, using Input.GetMouseButtonDown (and if necessary Input.mousePosition) for your input.
     
  3. Jeezker

    Jeezker

    Joined:
    Sep 25, 2013
    Posts:
    51
    I'm sorry but I don't know how. Would you teach me?
     
  4. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Am I the only one that doesn't see any code for handling mouse clicks in the above snippet?

    Edit - Ah, it's based on a GUI button click. Yup no way around that if you want to use GUI. Otherwise, like the other poster said, write an Update method that checks Input.GetMouseButtonDown(0)
     
  5. Jeezker

    Jeezker

    Joined:
    Sep 25, 2013
    Posts:
    51
    Can you write it for me, please? I don't really know what to delete from there either. I started learning c# yesterday
     
  6. Erisat

    Erisat

    Joined:
    Jan 31, 2013
    Posts:
    88
    Try This
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. public class Bee : MonoBehaviour
    4. {
    5.     public float jumpSpeed = 2; // The JumpSpeed
    6.     public float gravity = 3; // The Gravity
    7.     public AudioClip pipePassSound; // A sound played when the bee passes a pipe.
    8.     public GUISkin flyGUISkin; // The GUISkin used for the game
    9.     public GUISkin _GUISkin;
    10.     public Vector2 moveDir; // The direction.
    11.     private float vSpeed; // The vertical speed of the bee.
    12.     private Transform myTransform; // The bee's transform.
    13.     private Rigidbody2D _Rigidbody2D; // The bee's rigidbody2D.
    14.     private bool moveBee = true; // Bool used to check if the bee should be moved.
    15.     private bool gameOver = false;
    16.     private Rect gameOverRect;
    17.     private int currentScore = 0;
    18.     void Awake ()
    19.     {
    20.         //Set up some references.
    21.         myTransform = transform;
    22.         _Rigidbody2D = transform.rigidbody2D;
    23.     }
    24.     void Update()
    25.     {
    26.         myTransform.eulerAngles = new Vector3(myTransform.eulerAngles.x, myTransform.eulerAngles.y, myTransform.eulerAngles.z + vSpeed*50*Time.deltaTime);
    27.         if(moveBee) // If it's true, move the bee.
    28.         {
    29.             if(_Rigidbody2D.velocity.y != moveDir.y)
    30.             {
    31.                 _Rigidbody2D.velocity = moveDir; // Set the velocity to the move direction
    32.             }
    33.         }
    34.        
    35.         vSpeed -= gravity*Time.deltaTime; // Set the correct gravity on the Bee.
    36.        
    37.        
    38.        
    39.         if (Input.GetButtonDown("Jump"))   //if user presses space
    40.                 vSpeed = jumpSpeed;         //set V speed to the predetermined jump speed
    41.                
    42.                
    43.                
    44.                
    45.         if(moveBee)
    46.         {
    47.             if(moveDir.y != vSpeed)
    48.             {
    49.                 moveDir.y = vSpeed;
    50.             }
    51.         }
    52.         else
    53.         {
    54.             if(moveDir.y != 0)
    55.             {
    56.                 moveDir.y = 0;
    57.             }
    58.         }
    59.     }
    60.     void OnTriggerEnter2D(Collider2D other)
    61.     {
    62.         if(other.CompareTag("Enemy"))
    63.         {
    64.             moveBee = false;
    65.             moveDir.x = 0;
    66.             moveDir.y = 0;
    67.             StartCoroutine(PauseLevelAfterTime(2.0f));
    68.         }
    69.         if(other.CompareTag("Pass"))
    70.         {
    71.             currentScore += 1;
    72.             audio.PlayOneShot(pipePassSound);
    73.             other.enabled = false;
    74.         }
    75.     }
    76.     void GameOverWindow(int windowID)
    77.     {
    78.         GUI.skin = _GUISkin;
    79.         GUILayout.Space(Screen.height / 5);
    80.         GUILayout.Label("GAME OVER");
    81.         GUILayout.Space(Screen.height / 20);
    82.         GUILayout.Label("Score: " + currentScore);
    83.         GUILayout.Label("Best: " + PlayerPrefs.GetInt("Best"));
    84.         GUILayout.BeginHorizontal();
    85.         if(GUILayout.Button("Restart", GUILayout.Height(Screen.height / 8)))
    86.         {
    87.             Time.timeScale = 1.0F;
    88.             Application.LoadLevel(Application.loadedLevel);
    89.         }
    90.         if(GUILayout.Button("Highscore", GUILayout.Height(Screen.height / 8)))
    91.         {
    92.             Debug.Log("Highscore");
    93.         }
    94.         GUILayout.EndHorizontal();
    95.     }
    96.     void OnGUI ()
    97.     {
    98.         if(gameOver == true)
    99.         {
    100.             GUI.skin = _GUISkin;
    101.             gameOverRect = new Rect(0 , 0, Screen.width, Screen.height);
    102.             gameOverRect = GUILayout.Window(1, gameOverRect, GameOverWindow, "");
    103.         }
    104.         else
    105.         {
    106.             GUI.skin = flyGUISkin;
    107.             GUI.Label(new Rect(0, 0, Screen.width, Screen.height / 8), "" + currentScore);
    108.         }
    109.     }
    110.     IEnumerator PauseLevelAfterTime(float delay)
    111.     {
    112.         yield return new WaitForSeconds(delay);
    113.         Time.timeScale = 0.0f;
    114.         gameOver = true;
    115.         if(currentScore > PlayerPrefs.GetInt("Best"))
    116.         {
    117.             PlayerPrefs.SetInt("Best", currentScore);
    118.         }
    119.     }
    120. }
     
  7. Erisat

    Erisat

    Joined:
    Jan 31, 2013
    Posts:
    88
    I would use either Input.GetButton or Input.GetButtonDown.
    They are both used in the Update() function as this is called every frame. Fixed Update is not frame dependent, and may not play well with using these as they return frame by frame.

    GetButtonDown returns true on the first frame of the user pressing a key. after the first frame, it returns false.
    GetButton returns true on the first frame of the user pressing a key, and continues to return true as long as the button is held
    GetButtonUp returns false until the user releases a key, where it returns true for one frame then returns false again. but that doesnt really help lol.

    More info here: http://docs.unity3d.com/Documentation/ScriptReference/Input.html
     
  8. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,773
    It's worth noting that, if you're targeting mobile, you'll have to handle touches as well as clicks. (Or at least, you'll have to handle touches; handling clicks is just nice to have in the editor for testing.) It's best to handle them separately but have them call one function. So something like this:

    Code (csharp):
    1.  
    2.  
    3. void Update() {
    4. if (Input.GetMouseButtonDown(0) ) Jump();
    5. if (Input.touchCount > 0) {
    6. foreach (Touch t in Input.touches) {
    7. if (t.phase == TouchPhase.Began) Jump();
    8. }
    9. }
    10. }
    11.  
    12. void Jump() {
    13. //change your velocity here
    14. }
    15.  
     
  9. Jeezker

    Jeezker

    Joined:
    Sep 25, 2013
    Posts:
    51
    I actually solved that by changing project's input settings, because somehow a mouse click is translated to a screen touch, so I changed jumping from spacebar to mouseclick. Thank you all for the help.