I'm making some game menu in unity using UI event systems.
My intention is when I move mouse pointer over the text in game menu area,
font-size get bigger and when I move mouse pointer out, font size get back
to it's original size.
It works as I intended but there's a problem that if I move mouse pointer over the text and set my game menu deactive then active again using key press,font-size doesn't get back to it's original size,just getting bigger.
Here's my code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class HandleIngameMenu : MonoBehaviour,IPointerEnterHandler,IPointerExitHandler,IPointerClickHandler
{
private Text texts=null;
private void Start()
{
texts = GetComponentInChildren<Text>();
}
public void OnPointerEnter(PointerEventData data)
{
texts.fontSize += 3;
}
public void OnPointerExit(PointerEventData data)
{
if (this.gameObject.name.Equals("ReStartBtn"))
{
texts.fontSize = 30;
}
else
{
texts.fontSize = 37;
}
}
I guess setting object deactive is not same as moving mouse pointer out.
Is there any way to solve this problem??
When you activate your menu set the defaults, this way it won't matter what happens when it is deactivated. Or alternatively when you deactivate your menu run the defaults method first then deactivate. This way when it's enabled it will be back to normal.
Related
Long story short, I'm trying to create a UI panel where you hold and drag your mouse wheel button and select the option you want (while holding that button). So it is a pop-up menu that is triggered when you press the mouse wheel button. When you release the button, there are 2 possible situations:
You didn't move your cursor to a valid position. The pop-up menu is closed.
You moved your cursor to a valid position. You triggered an option from this pop-up menu.
To give you an example, the weapon switch system in, say, Tomb Raider does this similarly. It looks like a roulette, you hold the button then move your cursor to a certain location that "belongs" to, say, shotgun. Then you release the button, the menu is closed and now you are equiped with a shotgun.
Right now, the pop-up panel kinda works. However it's not a hold-release mechanism but a click mechanism. You click the button once, then the menu pops up and stays there.
How do you do that in Unity3D?
Here is my script so far:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PosSelector : MonoBehaviour
{
Animator posSelectorAnimator;
public GameObject posSelector;
public Animator posButtonAnimator;
void Start ()
{
posSelectorAnimator = posSelector.GetComponent<Animator>();
}
void Update ()
{
if (Input.GetKeyDown(KeyCode.Mouse2))
{
Open();
}
if (Input.GetKeyUp(KeyCode.Mouse2))
{
Close();
}
}
void Open()
{
Vector3 mousePos = Input.mousePosition;
Debug.Log("Middle button is pressed.");
posSelector.transform.position = (mousePos);
posSelectorAnimator.SetBool("ButtonDown", true);
}
void Close()
{
if (posButtonAnimator.GetCurrentAnimatorStateInfo(0).IsName("Highlighted"))
{
Debug.Log("Position selected.");
Debug.Log(posButtonAnimator.GetCurrentAnimatorStateInfo(0).shortNameHash);
}
else
{
Debug.Log("Input not found.");
Debug.Log(posButtonAnimator.GetCurrentAnimatorStateInfo(0).shortNameHash);
}
}
}
First of all, what you are cresting is called a pie menu.
You could create a script for the buttons inside your pie menu. Then let that script inherit from MonoBehaviour, IPointerEnterHandler and IPointerExitHandler.
These interfaces force you to implement the following methods:
public void OnPointerEnter(PointerEventData eventData)
{
PosSelector.selectedObject = gameObject;
}
public void OnPointerExit(PointerEventData eventData)
{
PosSelector.selectedObject = null;
}
Now create a static field in your PosSelector script called selectedObject:
public static GameObject selectedObject;
Then in your Close() Method, you can use selectedObject as your output:
void Close()
{
//Close your menu here using the animator
//Return if nothing was selected
if(selectedObject == null)
return;
//Select a weapon or whatever you want to do with your output
}
Also, consider renaming your question to something like "how to create a pie menu in unity? " so that other people with the same question have an easier time finding this question
I'm trying to change the color of an image when I hover over it. It runs PointerEnter when I hover over it, and PointerExit when my mouse goes away.
Instead of changing the color of just the image I'm hovering over, it changes the color of every image in the scene. Can anybody help?
Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class click : MonoBehaviour {
void Start(){
}
void Update(){
}
public void PointerEnter(){
gameObject.GetComponent<Image>().material.color=new Color(1,1,0);
}
public void PointerExit(){
gameObject.GetComponent<Image>().material.color=new Color(1,1,1);
}
}
The material is shared for optimisation, it's the same one used for all the images using it.
You need to change the color of the image, simply remove material on your lines.
gameObject.GetComponent<Image>().color=new Color(1,1,0);
The Button component has transition settings where you can set colors for state, maybe you dont need the extra code.
Unity has 2 pre-programmed functions called OnMouseOver() and OnMouseExit(). Which you can use to see if the mouse entered your Image.
You would need to add this Code Snippet to each Image you want the Color to be changed on Hover and make sure that you get the .Color Component instead of the .material.color Component.
Example:
public class OnMouseOverExample : MonoBehaviour
{
void OnMouseOver() {
// Executes when you Hover over this GameObject with the Mouse
gameObject.GetComponent<Image>().color = new Color(1f, 1f, 0f);
}
void OnMouseExit() {
// Executes when you no longer Hover over this GameObject with the Mouse
gameObject.GetComponent<Image>().color = new Color(1f, 1f, 1f);
}
}
If you want to change a UI Components Color, you could also use the Button Component. Which already has functionality built in, you can use to tint the Color of your Image.
my character shoots arrows. She starts without zero arrows and cannot shoot any until she picks up an arrow icon. Arrow icons have a value of 3. After this she can shoot arrows. That code works fine. Now I have to make it so these arrows decrease in value through the UI text display. The UI text value changes from 0 to 3 when an arrow icon is picked up, but it doesn't decrease when I shoot an arrow. I have another game object with a script that will detect when an arrow is shot. when this happens, it tells that main script that, "hey, an arrow was just shot." The focus is on getting the Text to decrease when I shoot an arrow.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class arrowManager : MonoBehaviour {
private Text text;
public static int arrowCount;
public static int arrowRecount;
private int maxArrows = 99;
void Start ()
{
text = GetComponent<Text> ();
arrowCount = 0;
}
void Update ()
{
FullQuiver ();
arrowCounter ();
}
void arrowCounter()
{
if (arrowCount < 0) {
arrowCount = 0;
text.text = "" + arrowCount;
}
if (arrowCount > 0)
text.text = "" + arrowCount;
}
public static void AddPoints(int pointsToAdd)
{
arrowCount += pointsToAdd;
}
public static void SubtractPoints(int pointsToSubtract)
{
arrowCount -= pointsToSubtract;
}
public void FullQuiver()
{
if (arrowCount >= maxArrows)
{
arrowCount = maxArrows;
}
}
}
the game object with the script that detects arrows looks like this.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class arrowDetector : MonoBehaviour {
public int pointsToSubtract;
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.tag == "arrow")
{
arrowManager.SubtractPoints (pointsToSubtract);
}
}
}
Forgive me if I've misunderstood, but it looks to me like you are subtracting from the wrong variable.
Since you are displaying the 'arrowCount' variable, I imagine that's what should be subtracted from.
public static void SubtractPoints(int pointsToSubtract)
{
if (arrowCount > 0) {
arrowCount -= pointsToSubtract;//pointsToSubtract is an int value passed to this script from my player script whenever she shoots an arrow.
}
}
In SubtractPoints method you are detracting from the variable "arrowRecount".
Wouldn't you want to be subtracting from "arrowCount" instead? If you used "arrowCount" your text value should update properly.
I figured it out. Before, I was trying to get it to detect my arrows whenever a bool became true from my player script. That wasn't working so I said screw it and just made an empty that detects gameobjects with the tag "arrow." Then I updated the script in here to reflect that. I was dead tired last night after not getting any sleep for two days so I forgot to put in a value of pointsToSubtract in the hierarchy. Thanks everyone for their responses.
I'm creating a project using the Gear VR, where you can rotate an object and display information based on the swipe and tap controls on the side of the headset.
Everything works great, I can rotate and select stuff when I use the touchpad on the side of the Gear VR, but when I change scenes and return to the main menu, and then go back into the scene I was just on, the functionality stops working.
I am using this script I've made:
using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections;
using System;
public class GearVRTouchpad : MonoBehaviour
{
public GameObject heart;
public float speed;
Rigidbody heartRb;
void Start ()
{
OVRTouchpad.Create();
OVRTouchpad.TouchHandler += Touchpad;
heartRb = heart.GetComponent<Rigidbody>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.W))
{
SceneManager.LoadScene("Main Menu");
}
}
void Touchpad(object sender, EventArgs e)
{
var touches = (OVRTouchpad.TouchArgs)e;
switch (touches.TouchType)
{
case OVRTouchpad.TouchEvent.SingleTap:
// Do some stuff
break;
case OVRTouchpad.TouchEvent.Up:
// Do some stuff
break;
//etc for other directions
}
}
}
I've noticed that when I start my game, an OVRTouchpadHelper is created. I don't know if that has anything to do with my problem.
The error I am getting is:
MissingReferenceException: The object of type 'GearVRTouchpad' has
been destroyed but you are still trying to access it. Your script
should either check if it is null or you should not destroy the
object.
BUT I have not referenced this script anywhere else.
When I check my scene in play mode, the script is still there with the variable assignments still present.
Any help would be great!
OVRTouchpad.TouchHandler is a static EventHandler (so it will persist through the lifetime of the game). Your script is subscribing to it when it's created but isn't unsubscribing when it's destroyed. When you reload the scene the old subscription is still in the event but the old GearVRTouchpad instance is gone. This will result in the MissingReferenceException next time the TouchHandler event fires. Add this to your class:
void OnDestroy() {
OVRTouchpad.TouchHandler -= Touchpad;
}
Now, whenever a GameObject with the GearVRTouchpad behaviour is destroyed, the static event in OVRTouchpad will no longer have a reference to it.
I want to change the UI image in random order. I have a gameobject in UI(canvas) containing Image component and it has null image initially. I have a script attached to it(gameobject) to change the image on run time.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class changeImg : MonoBehaviour {
public Sprite sprite1;
public Sprite sprite2;
public Sprite sprite3;
void Start()
{
ChangeImg();
}
void ChangeImg()
{
int rand=Random.Range(0,3);
if(rand==0)
{
gameObject.GetComponent<Image> ().sprite = sprite1;
//gameObject.GetComponent<UnityEngine.UI.Image> ().sprite = sprite1;
}
else if(rand==1)
{
gameObject.GetComponent<Image> ().sprite = sprite2;
// gameObject.GetComponent<UnityEngine.UI.Image> ().sprite = sprite2;
}
else if(rand==2)
{
gameObject.GetComponent<Image> ().sprite = sprite3;
//gameObject.GetComponent<UnityEngine.UI.Image> ().sprite = sprite3;
}
}
}
I have assigned the public field (sprite1,sprite2,sprite3) in inspector. And I tried the both option as I had commented in code. I did not get an error but also the image did not get change as I want. During runtime of a program, GameObject(to which the script is attached) has null image source as it was initially.
Use overrideSprite field instead of sprite - documentation
Unfortunately, unity ui is full of such pitfalls and it's api is totally counter-intuitive, so you have to be careful and check the docs regularly
You can also just use Image if you are in Unity 2017.3 (not sure if this works for older versions). For example:
using UnityEngine.UI;
-----
public Image ObjectwithImage;
public Sprite spriteToChangeItTo;
void Start () {
ObjectwithImage.sprite = spriteToChangeItTo;
}
Works great for me.
Have you checked the position of the Gameobject? Also the color of the image?
To change the Image from a Button, don't use GetComponent<Image> () as you can potentially get another Image component that does not belong to the button. It can also return null if the object is disabled.
Use the Button.image.sprite or Button.image.overrideSprite variable instead.
public Button pb;
public Sprite newSprite;
void Start()
{
pb.image.sprite = newSprite;
}
Or
pb.image.overrideSprite = newSprite;
It really doesn't matter which one is used. Any of these two should work.