Disabling GUI Texture - c#

I have a gui texture that fit in my entire screen and a script attached to it. whenever i press on the screen (on the guitexture) , a projectile is launched based on the mouse position. The problem is that i put a pause button and when i press on it a projectile is launched before the game is paused. the script of the guitexture uses the OnMouseDown() method and the pause button uses the OnGui() method. Please Help ! I tried to use booleans but it didn't work. it seems like the two methods are being called at the same time.

I had a similar problem with my game, might not be the best solution, but worked very well for me.
The pause button was at the top of the screen on the left, so when touching/clicking on the screen, I tested the clicked area to the same as the button was, in the end it will only trigger the "click" effect if it is outside the pause button area.
It would get harder if you need more buttons, but this is just what worked for me, I hope it can help you.
Note: Input.GetMouseButtonDown(0) works for mouse clicks and touches (android/iphone).
C#:
if (Input.GetMouseButtonDown(0))
{
var buttonPos = new Rect(0, 0, 100, 100);
if (!buttonPos.Contains(new Vector2(Input.mousePosition.x, Screen.height - Input.mousePosition.y)))
{
Jump();
}
}

Related

Object following mouse using ScreenPointToRay lagging

I am building a 3d topdown shooter. The player controls the avatar with the keyboard and the reticule with the mouse.
I found a simple way to implement the reticule based on this article:
https://gamedevbeginner.com/how-to-convert-the-mouse-position-to-world-space-in-unity-2d-3d/
I defined an object which represents the reticule and attached this script:
public class Reticule : MonoBehaviour
{
Camera mainCamera;
Plane plane;
float distance;
Ray ray;
// Start is called before the first frame update
void Start()
{
mainCamera = Camera.main;
plane = new Plane(Vector3.up, 0);
// This would be turned off in the game. I set to on here, to allow me to see the cursor
Cursor.visible = true;
}
// Update is called once per frame
void Update()
{
ray = mainCamera.ScreenPointToRay(Input.mousePosition);
if (plane.Raycast(ray, out distance))
{
transform.position = ray.GetPoint(distance);
}
}
}
This works, but the issue is that the reticule is lagging behind the mouse cursor, and catches up when I stop moving the mouse.
Is this because this method is just slow. Is there another simple way to achieve the same result?
the issue is that the reticule is lagging behind the mouse cursor, and catches up when I stop moving the mouse
That's normal, your mouse cursor is drawn by the graphics driver (with the help of WDM) as fast as the mouse data information comes over the wire, while your game only renders at a fixed framerate (or slower). Your hardware mouse will always be ahead of where your game draws it or anything related to it.
Some things that can help with working around this:
Don't show the system cursor, instead show your own. That way the cursor you show will always be in the same place your game thinks it is (since it drew it) and you won't have this issue. Careful with this however, because if your game's frame rate starts dipping it will be VERY noticeable when your cursor movement isn't smooth anymore.
Don't tie objects to your cursor. The issue doesn't show with normal interactions, like clicking buttons. You will notice this in RTS games when drawing boxes around units, but I struggle to think of another example of this.
Like above, but less restrictive, you could lerp the objects tied to your cursor in place, so they're always and intentionally behind it. It makes it look more gamey, which isn't that bad for a, you know, game. Though I wouldn't do this for a twitchy shooter, of course.

Unity OnMouseDown too slow

I am coding a clicker game and I do not want my program to calculate whenever I press the UI. I have tried using OnMouseDown, OnPointerDown and !EventSystem.current.IsPointerOverGameObject() but all of them ruin the clicker-feel because you can't spam click. Are there any shorter alternatives? Thank you in advance!
Edit: I've done all the things you've commented and I've found the problem. Whenever I click my mouse button, text appears with the number of coins I get per tap. Therefore, it counts as a UI element, making it not possible to spam-click. I have now turned off the "Raycast Target" for the text and now it works as it should. Thank you for your help!
You can use Input class along with a check:
void Update()
{
// Check if the left mouse button was clicked
if (Input.GetMouseButtonDown(0))
{
// Check if the mouse was clicked over a UI element
if (EventSystem.current.IsPointerOverGameObject())
{
Debug.Log("Clicked on the UI");
}
}
}
Or you can use OnMouseDown on specific object where you want to detect the click but with a UI check:
void OnMouseDown()
{
// Check if the mouse was clicked over a UI element
if (EventSystem.current.IsPointerOverGameObject())
{
Debug.Log("Clicked on the UI");
}
}

Clicking anywhere triggers the button

In my scene, I have this set-up:
Game Controller
Level Controller
Main Camera
Event System
Canvas
Player
PlayerCanvas (Render Mode is World Space)
Button
I set the PlayerCanvas into the same width and height of the button. And both of them are just small. I put Debug.Log to check everytime I press the button. But somehow, it triggers the button even if I click way off the screen. Can help to explain why is this happening. Thanks!
Note: I'm trying to add a button beside the Player so that even if the Player moves, the button will just follow.
I think your hierarchy is wrong.
Try something like
Game Controller
Level Controller
Main Camera
Player
Event System
Canvas (Screen Space - Overlay)
Button
Not sure what Player is, but I'm sure on my hierarchy Event System and Canvas are on the same level. And every button is son of Canvas. Not sure you can make multiple Cavas (you should not need it anyway).

Why is my object not continuously rotating with button press?

I have a space ship that will rotate clockwise or counter-clockwise depending on if the left or right button is pressed. I was using a virtual joystick and it was working fine but decided to change to left and right buttons. Now if click a button it will rotate to a fix position and stop each time i press the button, I'd like for it to move continuously in one direction while button held down and stop when released.
I'm using the unity standard assets with the cross platform input ButtonHadler script in conjunction with my "move" script.
void Update()
{
if (CrossPlatformInputManager.GetButtonDown("turn"))
{
TurnShip();
}
}
public void TurnShip()
{
transform.Rotate(Vector3.up * 50f * Time.deltaTime);
}
You're using GetButtonDown, which returns true only once when you press the button, and remains false until you release the button and press it again. Use GetButton instead.
Changing to GetButton was part of what I was missing but I had also set up my buttons up incorrectly I had accidentally added one event type with two function a pointer down and pointer up in the same event type instead of separating them.

Using sprite as button in Unity

I'm makimg a game in Unity using C# developed for Android. I'm testing using Unity Remote 4. I was just wondering if a sprite can be used as a button in Unity rather than the button made in Component -> UI -> Button.
I've tried this:
private void Update()
{
if (Input.touchCount > 0)
Application.LoadLevel("startScene");
}
Which does work. The button is being used to switch from the main menu to an options menu.
Ideally, I want the button to be in the same place in the options menu to be used to go back to the main menu. The problem then is that because the scenes switch instantly, the scenes switch between each other over and over I guess because the next scene gets the touch input as well.
How can I delay the time between the scenes switching, or is there a better way to use sprites as a button??
You can create a menu system which is persistent in scenes. Have a look at This Tutorial Video for guide
Usually buttons perform their function once a tap has been performed. A tap is a press and release on the button. What you are doing is performing your function on a press which is causing your buttons to be triggered continuously while you hold your finger.
Pseudo code:
If a finger presses on the sprite
If the same finger is release on the sprite
The button has been pressed.
You can use ray casting to detect touch on the sprite
private void Update()
{
if (Input.touchCount != 1) return;
var wp = Camera.main.ScreenToWorldPoint(Input.GetTouch(0).position);
var touchPos = new Vector2(wp.x, wp.y);
if (collider2D == Physics2D.OverlapPoint(touchPos))
{
// Your code
}
}
This is one way that has worked for me:
Add the sprite that you will use as the background of the button to the stage.
Add a Collider and mark it as a trigger.
Assign a script where you add any of the following functions depending on your case.
private void OnMouseDown () {
// Runs by pressing the button
}
private void OnMouseUp () {
// Runs when button is released
}

Categories