I'm working on my menu, here I have a couple of classes (represented as GUI buttons) that the player can pick. I have already made them highlighted on hover and also it registers when a class is selected.
The issue I don't know how to solve is, I want the selected class to stay "hovered" after click so it remains highlighted and the player is aware he has selected that class.
if (GUI.Button (new Rect (Screen.width / 2 - 625, 500, 200, 30), "The Cunning", buttonStyle))
{
classValgt = "1";
// Some code here that makes the button appear as if hovered with the effects I added via my GUI style
}
You Can Only Use Hover Effect with GUI Skin or GUI Style,go through the documentation below.
http://docs.unity3d.com/Manual/class-GUIStyle.html
http://docs.unity3d.com/Manual/class-GUISkin.html
In the Project Panel In Unity go to create and select GUISkin ,and make public GUIStyle type Variable in your script and pass your GUISkin on it and code like the Example Below:-
public class ExampleClass : MonoBehaviour
{
public GUIStyle style;
void OnGUI()
{
GUI.skin.label = style;
GUILayout.Label("This is a label.");
Debug.Log("" + GUI.skin.button.hover.textColor);
}
}
I would approach this by using two GUIStyles and a bool "selected" for each object represented for your button. Test the state of your bool before drawing the button and pass the correct style (selected/unselected) to it.
Even better if you could use GUI.Toggle instead of a button (you can change the style to resemble a simple button instead of a toggle). It is way more elegant as it controls selected/unselected status automatically and uses just one style (hold state for unselected and OnHold state for selected).
Related
New to coding here, setting up a UI in unity and having a visual issue where the back button appears until I hit options and back on the start up page, any reccomendations for a fix?
Image showing back button behind the quit button
Settings of the image on the right
You can use Gameobject.setactive(true/false) and try to manage the panel by making empty game object inside UI Canvas and name it as a panel so the whole button became a child and you can easily manage it
for example like this one
public Gameobject startPanel;
public Gameobject optionPanel;
public void Startpnl()
{
//deadActive optionPanel and Activate startPanel
startPanel.setActive(true);
optionPanel.setActive(false);
}
public void optionpnl()
{
//deadActive starPanel and Activate OptionPanel
startPanel.setActive(false);
optionPanel.setActive(true);
}
I'm developing a game and I've reached a stage in which I need to dynamically create a list of buttons.
My approach was to create a scroll view and then add the buttons through scripting.
I've already created the button prefab. This button purpose is to open a specific link outside the application, so I created the button prefab with two text components: One saying "Show Path" which is what I want the buttons to show, and the other text component is the link I need to open, which isn't visible to the user.
I'm running into several problems:
I need to create the buttons as I am going through a list of user data. I display the data right beside the button, in another scroll view, correctly. However, only one button is created.
I'm unable to access the prefab link text component to change it to the link I need to open.
Thank you for your time!
What I'd recommend you do is create your own class to handle this, so it's easier to visualise in the inspector.
[System.Serializable]
public class RelevantClassName
{
public string link = "http://defaultbackuplink";
public string text = "Default content";
[Space]
public Transform button;
public Transform contentHolder;
}
And in a seperate class, you use this information to generate your scroll views and buttons:
public class UIController : MonoBehaviour
{
public List<RelevantClassName> contentToDisplay;
[Header("References"]
public Transform buttonParent;
public Transform contentParent;
public GameObject buttonPrefab;
public GameObject contentPrefab;
public void DisplayUI()
{
foreach(RelevantClassName content in contentToDisplay)
{
content.contentHolder = Instantiate(contentPrefab, contentParent);
content.button = Instantiate(buttonPrefab, buttonParent);
// And here you can run any custom changes, for example finding a text
// component on the content holder and changing the description:
content.contentHolder.GetComponent<Text>().text = content.text;
}
}
Naturally I heavily advise you use a pooling system, and if you're planning to access a component, cache it in that class.
Hope this helps!
I have a fadepanel gameobject in my scene that has to sit on top of all the other gameobjects. However, when I click on an object int the editor window, since this gameobject is on top of all, is the one that is automatically selected in the hierarchy.
Is there a way to keep the gameobject on top of the canvas, as it is right now, but make it completely unselectable wIen i click on my scene?
You can use HideFlags on gameobject to make it unselectable:
public class HideFlagsSetter : MonoBehaviour
{
public Component target;
public HideFlags customHideFlags;
public enum Mode
{
GameObject,
Component
}
public Mode setOn = Mode.GameObject;
[ContextMenu("Set Flags")]
private void SetFlags()
{
if (setOn == Mode.GameObject)
{
target.gameObject.hideFlags = customHideFlags;
}
else if (setOn == Mode.Component)
{
target.hideFlags = customHideFlags;
}
}
}
Setting customHideFlags to HideInHierarchy would make it disappear from hierarchy so you won't be able to select it.
Edit: As the object will disappear, there is no way to bring it back if you can't access the script. So this script should be attached to a persistent object and target object should be set in the inspector.
You can use Context menu option by clicking on the gear icon in the top right corner and choose "Set Flags". its the last option in the menu.
Read more
Hope this helps :)
(ADDED BY PERSON WHO ASKED THE QUESTION)
I wanted a way for this to automagically happen on editor mode. So i did the same steps, but i changed the script a bit to work on Editor mode. I added [ExecuteInEditMode] on top of the class and also added an Awake() method that executes the same code as in SetFlags. Seems to work just fine.
I have three buttons, when you tap one button, a panel with a text appear.
The problem is when I attached the script, nothing happens.
The "click" is registered but the the panel never appears.
My script is attached to each of the button and is something like this:
public GameObject panel; //i use to put the panel in unity
bool selected = false;
void Start () {
panel.SetActive(false);
}
void OnSelect() {
selected = !selected;
panel.SetActive(true);
}
I probably have to do something else with the panel but I can't figure it out.
Do it like this:
(1) Add the canvas to your project
(2) BIG TIP - be sure to select Scale with screen size.
That's the only one you ever use. Unity accidentally set the wrong default there, they have not fixed it yet.
(3) In your Canvas, add a BUTTON Make it say perhaps "Test"
(3) In your Canvas, add another BUTTON Make it say perhaps "Another Test"
(4) Make a script something like this...
public class MainScreen:MonoBehaviour
{
public void UserClickedTest()
{
Debug.Log("test..");
}
public void UserClickedAnotherTest()
{
Debug.Log("another test..");
}
}
(5) put ONE copy of that script on ANY object you like. You can put it on your camera, on the canvas, or anywhere else that makes sense
For now let's say you put it on your CAMERA object, for example.
(6) Click on the button "Test" .....
And do this ...
click the PLUS button under OnClick
you see the slot that says "_main" in this example. DRAG your CAMERA item from HEIRARCHY, to that slot
Using the drop down menu:
select the "UserClickedTest()" function ...
good eh?
Now for the other button, do the same but select the "UserClickedAnotherTest()" function.
You're done! Run and test!
You can't use the OnSelect system unless you use ISelectHandler and more stuff: it is difficult for beginners. I strongly recommend the OP masters the simpler technique I explain here. Enjoy!
Maybe you attached the script to the panel. If so, your scripts can not be executed as long as your GameObject is SetActive(false).
I hope I was able to help you.
I have custom control - using Win Forms, that contains four TextBoxes, all have property to turn them off or on - I just setting visible parameter on them.
I would like to change size and position of the custom control - for example, when I turn off first textbox, I would like to change position of all 3 componets below him, to get them higher.
Of course, I would like to work it with every TextBox - every TextBoxes, below TextBox I am changing position, should change position.
I cant achieve it with changing of Position of TextBox in its own property - I can ask TextBox on top of me, if its property is set to on or of, but it dont works, because I dont know order of setting property in the application.
I can change position of TextBox below me - in the property of Top textbox, but I can do that with only one TextBox below, I dont know and cant find out, if two TextBoxes below are not off and fourth TextBox should be on position of second.
I cant change it by using some variable - when I change it, other TextBoxes dont care about it and they have set their position before.
So do you have any idea how could I achieve it?
The FlowLayoutPanel is designed for exactly this kind of behavior. Place your textboxes inside a FlowLayoutPanel, and then when you set the visible property of one or more of them to false, the other textboxes will automatically move up (or over if that's how you have it set up).
If you want for some reason do it manually, just make a chain of controls.
public class CustomTextBox
{
public CustomTextBox(CustomTextBox previousSibling)
{
PreviousSibling = previousSibling;
}
public CustomTextBox PreviousSibling { get; private set; }
public CustomTextBox PreviousVisibleSibling
{
get
{
if (PreviousSibling == null)
{
return null;
}
return PreviousSibling.Visible ? PreviousSibling : PreviousSibling.PreviousVisibleSibling
}
}
}