I'm trying to divide the screen to 2 and use them as 2 different buttons (L,R) in Unity. But for the ones who are playing first time, I want to show the buttons' text and image to teach them what they do, and after that I want to disable buttons' image and text, they will be still interactable but invisible.
First time screen
How can I ?
Way easier and more reliable than what you did would simply be do add something like this to your Button:
using UnityEngine;
using UnityEngine.UI;
[RequireComponent(typeof(Button))]
[DisallowMultipleComponent]
public class HintsController : MonoBehaviour
{
private Image _image;
private Text _text;
private float _originalAlpha;
// optional to control if Hints should be enabled on starting the App
public bool enableAtStart;
private void Awake()
{
// GetComponentInChildren finds the component on this object or any
// child of this object recursively
// (true) : make sure you also find the components if this or the child objects
// are currently disabled
// On this way you don't even have to rely on that the Image is on the
// Button GameObject or below in the hierachy
_image = GetComponentInChildren<Image>(true);
_text = GetComponentInChildren<Text>(true);
if(_image)
{
_originalAlpha = _image.color.a;
}
// optional to controll if Hints should be enabled on starting the App
ShowHints(enableAtStart);
}
public void ShowHints(bool isVisible)
{
// Skip if no Image found
if (_image)
{
var color = _image.color;
color.a = isVisible ? _originalAlpha : 0;
_image.color = color;
}
// Skip if no Text found
if (_text)
{
_text.enabled = isVisible;
}
}
}
Then from any other script, you simply can do e.g.
// TODO somehow get the reference either to the button GameObject or the Button component
var button;
button.GetComponent<HintsController>().ShowHints(false);
To disable hints.
I used button.image.enabled = bool valuefor image component and button.transform.GetChild(0).gameObject.SetActive(bool value) for the text.
i would suggest just making an empty for each button in the scene view, name them left and right. drag you button images(sprites) onte the scene and size them to fill the camera with proper positioning. apply boxCollider2D to both of the parent game objects(the empties you created and named left and right.) then you will need some light scripting.
pseudo-wise i would say:
you will use:
void OnMouseDown(){
//button touched
}
to see if the button is pressed.
when your tutorial is over you will set the image and text invisible with the code you mentioned above or something similar. this script goes on each button.
Related
I am making a 2D game in unity, and I want a start screen, but I cant find out how to make the start button clickable, and to then change the scene to level 1
The game will be a cursor labyrinth, so any help with detecting if a mouse is hovering over something would be appreciated
I looked up a bunch of tutorials but none of them worked in c#
STEP 1:
You will have to add a Button Component to the sprite.
Alternatively, you can right click in the Scene Hierarchy and go to Create -> UI -> Button. This automatically creates a simple Button for you. Then it sprites can be changed accordingly.
STEP 2:
Then assign callback to the Button in the OnClick() Field to make it interactable. To load the scene,
Create a new C# script. Make a new method in it. Use the LoadScene method in SceneManagement class. Then the script becomes:
using UnityEngine;
using UnityEngine.SceneManagement;
public class ExampleScript: MonoBehaviour
{
public void Loadscene(int sceneIndex)
{
SceneManager.LoadScene(sceneIndex);
}
}
Here you go bro.
public bool IsOverUi()
{
var eventDataCurrentPosition = new PointerEventData(EventSystem.current)
{
position = Input.mousePosition
};
var results = new List();
EventSystem.current.RaycastAll(eventDataCurrentPosition, results);
return results.Count > 0;
}
Following the Answer here: https://answers.unity.com/questions/1199251/onmouseover-ui-button-c.html
You can add a script:
public class MyClass: MonoBehaviour, IPointerEnterHandler{
public void OnPointerEnter(PointerEventData eventData)
{
//do stuff
}
}
I'm making an upgrade button for a game I'm creating, obviously I want the upgrade to only be available once, how do I code that?
I looked around the internet and each person suggested trying the following:
Bouton.SetActive (false);
or something like that. However, this makes the button inactive during startup. I want it to be inactive or destroyed after just one click. the button in question must be a GameObject
Anyone know how to fix this?
Thank you in advance!
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class One_One_Click_to_Save_the_GameObject_Deactivate_If_scene_replay : MonoBehaviour
{
public GameObject Bouton;
void Start()
{
if (PlayerPrefs.HasKey("buttonState")) // if the button was saved in memory
{
if (PlayerPrefs.GetInt("buttonState") == 0) //if the value is 0
Bouton.SetActive (false); // make button disabled
}
else
{
PlayerPrefs.SetInt("buttonState", 1); // saving in memory that button is on
}
}
public void buttonCliked()
{
Bouton.SetActive(false); // making the button disabled
PlayerPrefs.SetInt("buttonState", 0); //saving in memory that button is off
}
}
First of all you do not have any code piece to reset the state of your button on PlayerPrefs.
You should go to Edit -> Clear All PlayerPrefs on Unity Editor to get rid of the previous saved states.
Then you will check if the player is already used the upgrade button which you did on start but you dont need the else statement because in default it will be already active on the scene so this should be enough
void Start()
{
if (PlayerPrefs.HasKey("buttonState")) // if the button was saved in memory
{
if (PlayerPrefs.GetInt("buttonState") == 0) //if the value is 0
Bouton.SetActive (false); // make button disabled
}
}
Alternatively you can use the PlayerPrefs.GetInt() method with a default parameter so you don't need to check if it has a key, like this
void Start()
{
if (PlayerPrefs.GetInt("buttonState",1) == 0) // This will return 1 if there is no key with the name "buttonState"
Bouton.SetActive (false);
}
And after you clicked the upgrade which you should be doing on your buttonCliked() method. You can set the buttonstate to zero and it will always disable it on start. If you want to reset the state you need to clear the player prefs again like we did it on first step
public void buttonCliked()
{
Bouton.SetActive(false); // making the button disabled
PlayerPrefs.SetInt("buttonState", 0); //saving in memory that button is off
}
But again alternatively you can disable the clicking function on the button rather than just disabling it on the menu. What you should do is create a Button reference rather than a gameobject (or get the button component on the gameobject) and set it's interactable field to false. Which makes the button not clickable but still be seen on the screen.
You can use public Button Bouton; rather than public GameObject Bouton;and instead of using Bouton.SetActive (false); you can now call Bouton.interactable = false;
I would love to change button color on click but have no idea how to access the color. I see that my button has component Image which includes that color however I am unable to access it. I have the same issue with button's text where I also didn't found a way how to access it.
I have tried follow this tutorial but I am getting error (more on screenshots).
using UnityEngine.UIElements;
public class GameManager : MonoBehaviour {
//...
// This is my onclick function
public void SelectLevel(int level ) {
Debug.Log(level);
GameObject btn = GameObject.Find("Btn" + level);
Debug.Log(btn);
Image imgButton = btn.GetComponent<Image>();
Debug.Log(imgButton);
}
}
What you want is not the UnityEngine.UIElements.Image from the namespace
using UnityEngine.UIElements;
but rather UnityEngine.UI.Image
using UnityEngine.UI;
Try this to change the color of the button:
btn.GetComponent<Image>().color = Color.red;
If you want a different color, remember to instantiate it like:
new Color(rValue,gValue,bValue);
And if you want to happens on onClick:
btn.onClick.AddListener(MethodToChangeColor);
Or with lambda expression:
btn.onClick.AddListener(() => { btn.GetComponent<Image>().color = Color.red; });
Also check that your Button700 has an Image component attached!!
I have two images named hungerbar and cheesebar.
when the mouse approaches the cheese one button is activated. and I added pointer down function so when I press cheesebar level is decreasing and when the chees bar is empty the first cheese disappears.
and the second cheese appears but I can not control it with the same code. I dont know how to.
here some samples of my code;
void Start()
{
cheesbar1= GetComponent<Image>();
}
void Update()
{
cheesbar1.fillAmount = eatencheese / maxcheese;
}
private void FixedUpdate()
{
if (eating== true)
{
eatencheese--;
hungerscript.gettinghungery += 3f;
}
if (eatencheese <= 0)
Destruction();
}
SO that codes control only one image (Cheesebar1) . I want to use the same code and game object for controlling the second one..
Add this somewhere in your class (preferably at the top)
[SerializeField, Tooltip("The image of your second cheesebar")]
private Image cheesebar2;
This will add a field that will be exposed to the inspector, like so:
Like what the image states, drag the game-object with the image of the second cheesebar into the new field.
You should be able to modify cheesebar2 in your code afterwards.
I'm starting with unity since a few weeks and i'm stuck with some displaying problems.
You can see what I want to achieve here :
On several of my pages I have a title with an icon on the left and I want it to be at 40px on the left of the title, no matter the size of it.
So I did a prefab with an empty Text for the title, an empty RawImage for the icon and I put that prefab on the center top of the screen.
I link the following C# script on my prefab with the 'string' parameter for the title and the 'Texture' parameter for the icon to display.
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
public class TitlePage : MonoBehaviour {
public string title;
public Texture texture;
private Text titlePageText;
private RawImage iconPage;
void Awake()
{
titlePageText = gameObject.GetComponentsInChildren<Text>().First();
iconPage = gameObject.GetComponentsInChildren<RawImage>().First();
}
void Start()
{
titlePageText.text = title;
}
void Update()
{
iconPage.rectTransform.anchoredPosition = new Vector2(-titlePageText.rectTransform.rect.width / 2 - 40, iconPage.rectTransform.anchoredPosition.y);
iconPage.texture = texture;
}
}
The title is set well in the "Start" function, the problem is with the icon. The code in the "Update" function put the icon at the wanted position if it's in the "Update" function because in the "Start", 'titlePageText.rectTransform.rect.width' give 0. But with that code in the "Update" function, the icon start with a display by default in the center and nearly instantly it moves on the left but we can see that position changing.
Maybe there's a solution to avoid that ?
Maybe I started in a wrong way ?
(I don't put my title's text hardly because I want my application to be multilingual so instead of displaying the 'string' in parameter, I'll display the corresponding translation and it's why I can't set a fixed position because two translations are not the same length.)
Thanks in advance !
I am not entirely sure what your problem is exactly, but it does sound like you are trying to solve something from a slightly awkward angle. IS there a reason for not using Unity's layout (or even auto layout groups) to achieve your goal?
I just did a quick test: added 'Content Size Fitter component' to the text object with Horizontal set to Preferred, then placed an image as a child of that text object, when I set the anchor X to 0 and pivot X to 1, the image now follows the left hand side of the text, no matter what size.
This has the advantage of doing absolutely zero work unless text (or its position) changes, in which case everything is handled automagically by Unity's UI system
It sounds like the width of the titlePageText is not obtaining a value immediately in Start(), which is why it is initially zero. After a couple of frames when a non-zero value is found, it finally shifts your iconPage over but your object already has a texture at this point. You really shouldn't be doing this in Update() because it means it will constantly be setting the anchoredPosition and texture of your iconPage every frame.
One solution to avoid this would be to use a coroutine with yield to wait for your components to initialize and then set the position. Note that this is a bit of a hack since you are introducing some forced loading time.
public string title;
public Texture texture;
private Text titlePageText;
private RawImage iconPage;
void Awake()
{
titlePageText = gameObject.GetComponentsInChildren<Text>().First();
iconPage = gameObject.GetComponentsInChildren<RawImage>().First();
}
void Start()
{
titlePageText.text = title;
StartCoroutine(initializeComponenets());
}
IEnumerator initializeComponenets()
{
yield return new waitForSeconds(.05f); //might need longer wait here
iconPage.rectTransform.anchoredPosition = new Vector2(-titlePageText.rectTransform.rect.width / 2 - 40, iconPage.rectTransform.anchoredPosition.y);
iconPage.texture = texture;
}