I'm making a typing game where the user types in words that fall down the screen, and I have buttons at the top that act as powerups (nuke, freeze, etc...) when the user presses them.
Now, when the user clicks one of the powerup buttons at the top of the screen, the keyboard will momentarily close before ButtonClicked re-opens it and it looks quite buggy. How do I make it so that when the user clicks one of the buttons at the top the keyboard stays open the whole time?
Currently, I have added a listener on the button that will re-open the keyboard.
myButton.onClick.AddListener(ButtonClicked);
void ButtonClicked()
{
//DoStuff();
inputField.ActivateInputField();
}
This is what it looks like now. I have to click once to get rid of the keyboard, and then once again on the button.
https://imgur.com/a/WTLLYEX
I tried overriding some InputField functions with a custom class but to no avail.
public class CustomInputField: InputField
{
public override void OnDeselect(BaseEventData eventData)
{
Debug.Log ("Overrides InputField.Deselect");
}
public override void DeactivateInputField()
{
Debug.Log ("Overrides InputField.DeactivateInputField");
}
}
The first method doesn't accomplish what I want, and the second method DeactivateInputField() gives me
error CS0506: CustomInputField.DeactivateInputField': cannot override inherited memberInputField.DeactivateInputField' because it is not marked virtual, abstract or override.
Any help would be greatly appreciated, thank you!
You could use the TouchScreenKeyboard.open Function to leave the Keyboard open over time (here the Link to the Unity Manual: https://docs.unity3d.com/ScriptReference/TouchScreenKeyboard.Open.html). I would then aswell try to not use Update for this there should be another way to do so in your script.
Your error Otherwise might be caused because you try to override a function that is like the error said not Virtual Abstract nor Override so you aren't allowed to do that. To this it is an Unity class so you won't be able to change this aswell.
Another Thing you could try would be LateUpdate that wouldn't be perfect but it may Help your case here an Example:
LateUpdate()
{
if(!TouchScreenKeyboard.visible)
TouchScreenKeyboard.Open()/inputField.ActivateInputField();
};
The input field opens the system keyboard and your control over it is limited. If I were you I would create UI keyboard in my app which could be customized in any way and would guarantee same results on different devices/systems.
Probably the dumbest code I've ever written, but it does the trick:
public class FocusInputField : TMP_InputField
{
protected override void OnDestroy()
{
this.StopAllCoroutines();
}
public override void OnDeselect(BaseEventData eventData)
{
base.OnDeselect(eventData);
this.StartCoroutine(ReselectCoroutine());
}
private IEnumerator ReselectCoroutine()
{
yield return null;
this.ActivateInputField();
this.Select();
}
}
Related
See when my player dies you can restart well that's what I wanted but I can't get it to work and I want it to where you have an option of either pressing r or the button to restart.
Can I please get a couple of tips for this probably some code too but that's up to you btw I am a beginner and need much help my game is just a basic learning game and I will love help from you fellow gamedevs
This is my old code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ResetManager : MonoBehaviour
{
public static ResetManager Instance { get; private set; }
public event System.Action ResetEvent = new delegate {};
public void Awake()
{
Instance = this;
}
public static void ResetScene()
{
Instance.ResetEvent();
}
}
I would like to know if I could make it without scene manager
Welcome to stack overflow, here I will show a brief tutorial on how to build the key in the UI as well as execute the reset code. To create a UI button, go to Hierarchy and right-click, you can create a Button from the UI menu as shown below.
After creating the button, attach the script to a Manager object, click the button and reference the reset command at the bottom of the event, as below, keeping in mind that the unity event does not support static method's.
public void ResetScene() => SceneManager.LoadScene(SceneManager.GetActiveScene().name);
After performing the above steps, your button will restart the scene when clicked.
You can also restart the scene when you press the R key by adding the following code.
private void Update()
{
if (Input.GetKeyDown(KeyCode.R)) ResetScene();
}
I have four GameObjects in the game I am making and when I click on each one a dialogue box opens.
My problem is that I am using OnMouseDown and the first one always need to be clicked twice. It happens just on the OnMouseDown, I have buttons on the game that work just fine.
public static GameObject selectedClient;
public bool isBuying;
private Manager manager;
private void Start()
{
manager = GameObject.FindObjectOfType(typeof(Manager)) as Manager;
}
private void OnMouseDown()
{
if (isBuying == true)
{
selectedClient = this.gameObject;
manager.Talk();
}
else if (isBuying == false)
{
manager.NotTalk();
}
}
The Talk() and NotTalk() are as follows:
public void Talk()
{
dialogueBox.SetActive(true);
Time.timeScale = 0f;
actualClient = Client.selectedClient;
}
public void NotTalk()
{
dialogueBox.SetActive(false);
Time.timeScale = 1f;
}
Someone knows why this happens?
Thanks in advance.
Assuming manager.Talk() opens the dialog, perhaps isBuying is false initially, and is toggled when you click once?
Edit: User updated question with Talk and NotTalk methods.
Since your say that initially, only the time stops, but the dialogueBox doesn't show, by any chance, is this because it isn't populated, or correctly initialized? Can you show is code of what your expect to show up?
It may just be that dialogueBox has nothing to display, and therefore, doesn't, however, by the second click, it somehow it's correctly populated and can display.
If I understand correctly, it seems that OnMouseDown() and Talk() is being called successfully on the first mouse click, but a second mouse click is required to get the dialogueBox to show.
If dialogueBox.SetActive(true) is being called successfully, you could take a look at the Unity Scene Hierarchy window to see if it became active like you expect after the first mouse click. If it did, then you can examine that object to see why it's not appearing on screen. (As another poster mentioned, it may be related to dialogueBox initialization.)
Also, these questions might help us debug and figure out the issue:
What error do you get when you "click on one object and then on other"?
What happens if you click the buttons in a different order? If there are 4 buttons, is it the first button that is always affected, or the first button that you click?
In general, as other posters have suggested, using Debug.Log and Debug.Assert should help you narrow down the issue. Similarly, you can set breakpoints in the code and step through to see if the code is running like you expect. And as I mentioned in this post, the Unity Scene Hierarchy window is useful for debugging as well.
Add a Debug.log(isBuying); above (isBuying == true).
Then you'll know if the OnMouseDown() is being called in the first place and if it proceeds like you expect it to. After that, you should probably be able to fix it yourself, otherwise, please let me know what you found.
I'm working on a mouse manager script. I want to be able to left click on the instantiated text object and have it do one thing, and do something else when right clicked. Trouble is you can't send a parameter to an event trigger OnCLick and to send the base event data doesn't give you which button was clicked. I can't simply use Update because I only want them to right click on the text object not anywhere, especially since I want the right click to delete the object. I've looked and looked, one would think this were a common enough problem to find a solution, but alas.
I already have an OnEnter and OnExit, which changes the colors of the text.
Anyone have a solution?
Thanks!
In case anyone else has been pulling out their hair over this kind of issue. I finally found a solution and it works very well. So I will share it.
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
public class RightClick : MonoBehaviour, IPointerClickHandler
{
public UnityEvent leftClick;
public UnityEvent middleClick;
public UnityEvent rightClick;
public void OnPointerClick(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Left)
leftClick.Invoke ();
else if (eventData.button == PointerEventData.InputButton.Middle)
middleClick.Invoke ();
else if (eventData.button == PointerEventData.InputButton.Right)
rightClick.Invoke ();
}
}
Looking at some of the answers in the Unity forums and Q&A site, the answers for how to make an invisible button do not work because taking away the image affiliated with the button makes it not work.
How do you get around this and keep the invisible property while allowing the button to actually work?
This is one of those weird things about Unity...
100% of real-world projects need this, but Unity forgot to do it.
Short version:
You need Touchable.cs in every Unity project:
// file Touchable.cs
// Correctly backfills the missing Touchable concept in Unity.UI's OO chain.
using UnityEngine;
using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
[CustomEditor(typeof(Touchable))]
public class Touchable_Editor : Editor
{ public override void OnInspectorGUI(){} }
#endif
public class Touchable:Text
{ protected override void Awake() { base.Awake();} }
Use Unity's ordinary 'Create Button' editor function
As you know, the editor function adds two components for you automatically. One is a Text and one is an Image...
Simply delete them both
Drop the above script Touchable.cs on the Button
You are done. That's all there is to it.
It cannot "decay" with Unity upgrades.
You can actually "buttonize" anything in .UI by dropping Touchable on top of it.
Never again "add a transparent Image" to make a button.
Unity forgot to abstract a "touchable" concept in the OO chain.
So, us developers have to make our own Touchable class "from" Unity's classes.
This is a classic "backfilling" problem in OO.
When "backfilling" the only issue is that: it must be perfectly auto-maintaining. There is only one good solution, Touchable.cs, which everyone uses.
So in all real-world Unity projects a button looks like this:
ONE You have Unity's Button.cs
TWO you have to add Touchable.cs
Some teams make an editor function "Create Better Button" which simply makes a game object, with, Button.cs + Touchable.cs.
Important tip...
Say you may have a very complex UI panel. So it resizes or even has an animation.
In fact, you can just drop "Button+Touchable" on to anything like that, and it will work.
Just set the Button+Touchable so as to expand to fill the parent. That's all there is to it.
In this example image, "resume" and "quit" could be anything. (An animation, a complicated panel with many parts, text, sprites, something invisible, a stack - anything.)
In all cases, just drop a Button+Touchable underneath and you have a flawless button.
In fact: this approach is so simple, you'll probably use it for even simple cases.
Say your button is a trivial image. It's much easier to just have an image, and then drop a Button+Touchable on it. (Rather than use the confusing and problematic "Button" function in the editor.)
Understanding the situation...
1) Unity's Button.cs class is fantastic.
2) But the editor function "make a Button" is garbage...
3) It makes an "upside down" button,
4) i.e., it puts a text/image under Button.cs
5) "Button-ness" is something you should be able to add to anything at all. This is precisely how it works with Button+Touchable.
6) So - quite simply -
1. Have anything you want. Text, image, panel, invisible, animation - whatever.
2. Drop Button+Touchable on it - you're done.
That's how everyone does all buttons in Unity!
Historic credit: I believe Unity forum user "signalZak" was the first to think this out many, many years ago!
As a possible improvement to Fattie's answer, changing Touchable's base class to Graphic and overriding protected void UpdateGeometry() seems to work quite nicely white reducing the (admittedly minor) overhead associated with Text.
public class Touchable:Graphic
{
protected override void UpdateGeometry() { }
}
My first solution was to enable and disable the components like below:
void showButton(Button buttonToShow, bool show)
{
Image bImage = buttonToShow.GetComponent<Image>();
Text bText = buttonToShow.GetComponentInChildren<Text>(); //Text is a child of the Button
if (bImage != null)
{
bImage.enabled = show;
}
if (bText != null)
{
bText.enabled = show;
}
}
but that didn't work. If the button's image and text components are both disabled, the button click event will NOT fire. One of them MUST be enabled in able for click events to be sent.
The solution is to set the alpha of both the image and text components to 0 to hide and to 1 to show again. They will be hidden but not disabled and click events will work.
public Button button;
void Start()
{
//Show Button
showButton(button, true);
//Hide Button
//showButton(button, false);
}
void showButton(Button buttonToShow, bool show)
{
Image bImage = buttonToShow.GetComponent<Image>();
Text bText = buttonToShow.GetComponentInChildren<Text>(); //Text is a child of the Button
if (bImage != null)
{
Color tempColor = bImage.color;
if (show)
{
tempColor.a = 1f; //Show
bImage.color = tempColor;
}
else
{
tempColor.a = 0f; //Hide
bImage.color = tempColor;
}
}
if (bText != null)
{
Color tempColor = bText.color;
if (show)
{
tempColor.a = 1f; //Show
bText.color = tempColor;
}
else
{
tempColor.a = 0f; //Hide
bText.color = tempColor;
}
}
}
I fired up Gimp (that free coder graphic tool). Created new image (any size, I chose 10 pix x 10 pix), selected from advanced (in create dialog) that it's backgroud should be transparent. Saved the file. Exported it as png with save backgroud color selected. Dragged it into Unity as sprite. Put that to the button graphic. Disbaled the text-component of the button. No code required ... just don't draw anything while in Gimp (that was the hardest part).
I've been struggling with what appears to be a simple task for the past few hours. I have been successfully able to turn a GameObject's guiTexture on an off using GameObject.guiTexture.enabled as I have read in other similar questions. I do this in a script that is attached to the GameObject I wish to toggle.
The problem arises when I try to preform this same command from another script that is attached to an empty game object in my scene. When I interact with the button, simply nothing happens.
To give this some context, I am trying to create functionality to switch menus on the screen. When a user taps a certain UI button, I want to call unloadMenu() so I can wipe everything off the screen and draw the textures that belong to the appropriate menu.
//When the user lifts their finger
void OnTouchEnded ()
{
switch (this.gameObject.name)
{
//If they have selected the quiz button
case "QuizButton":
//this.guiTexture.enabled = false;
//Call the unloadMenu function which will clear the GUITextures
menuMgr.unloadMenu();
break;
The commented out section is what works fine. But now, I wish to perform this code in a function that is located in another script - menuMgr.unloadMenu()
This is what the MenuManager script looks like:
public GameObject quizButton;
void unloadMenu()
{
quizButton.guiTexture.enabled = false;
}
I have ensured to drag the quizButton gameobject from my scene into the inspector and connect it properly with the variable I have created yet nothing happens when this function is called. Does anyone have any idea why? Thanks in advanced.
How you declare MenuManager creates a new script while the reference to quizButton is in your MenuManager GameObject. That is why your menuMgr.UnloadMenu didn't do anything.
I have created something similar to yours and I found it worked fine :
Quizbutton Script:
public GameObject menuMgr; // reference to the empty game object (menu manager)
void OnMouseDown() // In your case, this is OnTouchEnded
{
// get the script of menu manager here
MenuMgrScript menuscript = menuMgr.GetComponent<MenuMgrScript>();
// and execute the function you want
menuscript.UnloadMenu();
}
Menu Manager Script:
// this script is exactly the same as yours, nothing's wrong here
// oh except add public to function UnloadMenu, so it can be called
// in the quizbutton script
public GameObject quizButton;
public void UnloadMenu() {
quizButton.guiTexture.enabled = false;
}