I have a MainButton object with a Button component. A component has a property (or what it is) On Click (). This property can have an object and a method that will be executed by pressing a button. I tried to set these values in the inspector, but these values are not saved in the prefab, because they are assigned from Assets, and not from Scene. How to assign this method and object through programming? Who didn't understood - I need to change properties (object, method) of the event "OnClick()" by the script.
You're looking for the Unity.OnClick UnityEvent.
public class Example : MonoBehaviour
{
//Make sure to attach these Buttons in the Inspector
public Button m_YourFirstButton, m_YourSecondButton, m_YourThirdButton;
void Start()
{
//Calls the TaskOnClick/TaskWithParameters/ButtonClicked method when you click the Button
m_YourFirstButton.onClick.AddListener(TaskOnClick);
m_YourSecondButton.onClick.AddListener(delegate {TaskWithParameters("Hello"); });
m_YourThirdButton.onClick.AddListener(() => ButtonClicked(42));
m_YourThirdButton.onClick.AddListener(TaskOnClick);
}
void TaskOnClick()
{
//Output this to console when Button1 or Button3 is clicked
Debug.Log("You have clicked the button!");
}
void TaskWithParameters(string message)
{
//Output this to console when the Button2 is clicked
Debug.Log(message);
}
void ButtonClicked(int buttonNo)
{
//Output this to console when the Button3 is clicked
Debug.Log("Button clicked = " + buttonNo);
}
}
Related
In my Unity project I have a InputField that a user can type into and click a button to trigger an action preformed based on what they entered. When I type into the InputField and then press the button, the text that was entered empties before I am able to grab it using inputtedFieldName.text
I have a InputField with the button as a child. The InputField has a component that attaches the script. Attached to the button is a method is called when the button is pressed. It appears when the button is pressed the text that was in the inputField disappears.
What can I do to fix this?
Method the button is calling
public void EnterTextToConsole() {
if (textInputted.text == "" ) {
ConsoleLog.addToConsole("NOTHING??");
} else {
ConsoleLog.addToConsole(textInputted.text);
}
I have next issue, I am working on small c#-wpf application,
and on load I am disabling button which is ussualy used to do some action on click, and it looks like this:
public MainWindow()
{
InitializeComponent();
this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
if (String.IsNullOrEmpty(password.Password))
{
btnActivate.IsEnabled=false;
}
}
and somewhere I am checking my password field, for example:
private void password_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key.Equals(Key.Enter))
{
if (password.Password == "drag0n")
{
btnActivate.IsEnabled = true;
}
else
{
btnActivate.IsEnabled = false;
}
}
}
And my problem is next, when user enter "drag0n" and press enter, button should be just enabled, but its not only enabled, its calling automatic his event _Click, I don't know why does that happening, because in that case, if my button is just enabled event _Click is also called, and if user clicks on that button, event is called again, so actually my event onclick is called twice.
My question is how can I stop calling my Click event if I set IsEnabled=true. When I set IsEnabled=true I just want it to be enabled for pressing and I don't want execute event _Click.
I want to execute event _Click only when my button is pressed as it should work and not on IsEnabled=true.
Thanks guys,
Cheers
On click event occurs when you press Enter key, because this button is the default control in a form.
If you don't want click event on Enter key, you should either make this button not default or not process Enter key pressing in your button click (e.Handled = true -> when Enter is pressed).
Or try to change your code:
private void password_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key.Equals(Key.Enter))
{
if (password.Password == "drag0n")
{
e.Handled = true; // add this line
btnActivate.IsEnabled = true;
}
else
{
btnActivate.IsEnabled = false;
}
}
}
I have a scroll view with lots of buttons on it. when i press one button, that button needs to change the sprite and stay like that. if any other button (or same one) is pressed previous button needs to revert back to original sprite..
here is some example
button 2 was pressed and changed sprite, it stays like that untill it is pressed again or any other (in this case button 3) is pressed
Here's a draft of a possible solution. Create a manager script for the "buttons group" and attach the script on the scrollview
public class ButtonsGroupController : MonoBehaviour
{
// List of all children buttons
private readonly List<Button> _buttons;
// Last pressed button index
private int _lastId = -1;
void Start(){
// Look for all buttons (children of this GO - scrollview)
_buttons = GetComponentsInChildren<Button>();
// Add event listener for buttons
for(var i = 0; i < _buttons.Count; i++){
var index = i;
_buttons[index].onClick.AddListener(() => ButtonPressed(index));
}
}
// Resolve buttons press event
private void ButtonPressed(int index){
// The same button has been pressed
if(_lastId == index)
return;
// Update the last selected button sprite - to normal state
// _buttons[_lastId]....
// Update the last id
_lastId = index;
// Update the sprite of newly pressed button
// _buttons[_lastId]....
}
}
I have a button2 which has a lot of code to execute when is clicked.
At some point, I need to wait until a boolean is set to true, and that boolean is made true when button 1 is pressed. (I can't press button 1 while button2's code is running).
I've searched, but all I found is with methods running async. How can I wait for button 1 to be pressed?
Here's a possible solution (may not be the most elegant):
public partial class Form1 : Form
{
// Variable to store whether button one has been clicked or not
private bool btnOneClicked = false;
// ..
private void btnOne_Click(object sender, EventArgs e)
{
// When button one is clicked, execute the code that needs to run before waiting for your second button to be clicked
LongCodeToExecuteFirst();
// Set your variable to true to say that button one has been clicked
btnOneClicked = true;
}
private void btnTwo_Click(object sender, EventArgs e)
{
// First check if button one has been clicked
if (btnOneClicked)
{
// If it has, execute the rest of the code that needed to be executed after button two was pressed
LongCodeToExecuteSecond();
// Reset our button one pressed variable to false
btnOneClicked = false;
}
}
private void LongCodeToExecuteFirst()
{
// Code to execute before button two is pressed
}
private void LongCodeToExecuteSecond()
{
// Code to execute after button two is pressed
}
}
I want when the button has been clicked, it will show some GUI button on it. I already tried the delegate, but the event is not fired (I mean the GUI button is not shown).
Here is the code that I am using:
The code below is to show the GUI button when I run the game.
public class IItemDatabase : MonoBehaviour
{
public delegate void Action(); // Set the event for the button
public static event Action onClicked; // The event for when the button has been clicked
protected virtual void OnGUI()
{
// Call the SetStyle method
SetStyle();
// Set the GUIContent as the tooltip
GUIContent buttonText = new GUIContent("Open Shop");
// Set the GUIContent as the tooltip
GUIContent buttonTexts = new GUIContent("Open Inventory");
// This GUILayoutUtility is useful because it is to fit the content
Rect buttonGUI = GUILayoutUtility.GetRect(buttonText, "Button");
// This GUILayoutUtility is useful because it is to fit the content
Rect buttonGUIs = GUILayoutUtility.GetRect(buttonTexts, "Button");
// Set where have to the Rect displayed
buttonGUI.x = 5;
buttonGUI.y = Screen.height - 25;
// Set where have to the Rect displayed
buttonGUIs.x = 125;
buttonGUIs.y = Screen.height - 25;
// If the button has been clicked
if (GUI.Button(buttonGUI, buttonText, style))
{
if (onClicked != null)
{
onClicked();
}
}
if (GUI.Button(buttonGUIs, buttonTexts, style))
{
if (onClicked != null)
{
onClicked();
}
}
// End of the clicked button event
}
}
And here is the I want it to display when the button has been clicked:
public class IInventory : MonoBehaviour
{
protected virtual void OnEnable()
{
IItemDatabase.onClicked += DoGUI;
}
protected virtual void OnDisable()
{
IItemDatabase.onClicked -= DoGUI;
}
protected virtual void DoGUI()
{
Rect slotRect = new Rect(x * 35 + (Screen.width / 3) + 50, y * 35 + (Screen.height / 3) - 10, 30, 30);
GUI.Box(slotRect, GUIContent.none);
}
}
But when I clicked the button that it suppose to fired the DoGUI() in IInventory class, it does not run the function.
How do I solve this?
Thank you.
Your answer much appreciated!
Your problem is not the event or the delegate, but a misunderstanding on how OnGUI() works.
The OnGUI() method might be called several times per frame, but your onClicked event will only be called once after you clicked the button. So your Inventory is only visible for a few milliseconds.
There are several ways to solve the problem. Your goal is to call DoGUI() during every OnGUI() call as long as you want the inventory to be shown. You could introduce a boolean that saves the state of the inventory menu and decides whether the menu should be visible or not. If you want your Open Inventory button to toggle the menu, you could try something like that
public class IItemDatabase : MonoBehaviour
{
public static event Action onClicked; // The event for when the button has been clicked
private bool showInventory = false;
protected virtual void OnGUI()
{
// I removed your other code to simplify the example
if (GUI.Button("Open Inventory"))
{
// toggle the status
showInventory = !showInventory
}
if (showInventory && onClicked != null)
{
onClicked();
}
}
}
If you want to keep the event depends on your application. If you keep it, I would rename it to showInventoryGUI or something similar to better reflect its intention. On the other hand you could simply remove the event and just call the method IInventory.DoGUI() directly.