I am a beginner in Unity and I am currently making a simple game. I have a problem where I need to select an object automatically by script so I can click outside of it without clicking on it in the screen.
What I want to do is when I click the object another object or panel will show and it will be automatically be selected by script so I can click outside the panel and it will close or will setActive to false. I tried the Select() and it is not working for me. The two objects are originally an Image but I added a Button component so it can be selectable.
This is the script for the object that will show the Panel:
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class ShowPhone : MonoBehaviour, ISelectHandler
{
[SerializeField] Button phonePanel;
public void OnSelect(BaseEventData eventData)
{
phonePanel.gameObject.SetActive(true);
}
}
This is the script for the panel where I want to click outside to close it:
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class HidePhoen : MonoBehaviour, IDeselectHandler
{
public Button phone;
private void OnEnable()
{
phone.Select();
}
public void OnDeselect(BaseEventData data)
{
Debug.Log("The Object will be setActive false when clicked outside the object");
}
}
You would use EventSystem.SetSelectedGameObject
EventSystem.current.SetSelectedGameObject(yourTargetGameObject);
Note though: Your panel would automatically be closed even if clicking any UI element within it (like e.g. InputField etc)
You can checkout the TMP_Dropdown source code and the way they implemented a "UI Blocker" which basically is an overlay over the entire screen except the drop-down popup and closes the pop-up when clicked on.
you could either replicate this or have a simpler version with a fully transparent background button behind your panel with onClick for closing the panel.
As alternative you could check RectTransformUtility.RectangleContainsScreenPoint
Related
I have an MRTK Slate which comes with Pressable Button to close the slate.
When the close button is pressed, the Slate is disabled but not destroyed. This is because in the Events section>Interactable script> GameObject.SetActive() is set by default as shown in fig:
I want to destroy the slate after clicking close button.
I know I can do this by making a script, attaching the slate prefab to the script(or taking the parent of the button till I get slate as parent game object), calling the function, and using GameObject.Destroy().
But I want to understand how the GameObject dropdown in the Interactable script is getting populated :
I understand that the other dropdowns like Transform, Follow me toggle, Solverhandler, etc are displayed because they are attached to the Slate.
But how does the GameObject option is available? This seems a basic thing, but I would like to be sure about how it is coded.
And if it is possible to add my new action in the Gameobject dropdown, if so, how?
I spent time looking at the scripts of Interactable and others, but I am a beginner in C# and was not able to see where is the code which does this.
Any input will help me.
No you can't because Object.Destroy is static and in UnityEvent (which Interactable.OnClick uses) via the Inspector you can only select instance methods.
You at lest need a minimal component like
public class ObjectDestroyer : MonoBehaviour
{
public void DestroyObject()
{
Destroy(this.gameObject);
}
}
or if you don't want to do it via the Inspector but automatically
public class ObjectDestroyer : MonoBehaviour
{
// store the itneractable reference
[Tootltip("If not provided uses the Interactable on this GameObject")]
[SerialzieField] private Interactable _interactable;
// Optionally provide a different target, otherwise destroys the Interactable
[Tooltip("If not provided destroys the GameObject of the Interactable")]
[SerializeField] private GameObject _targetToDestroy;
private void Awake()
{
// use get component as fallback if no Interactable was provided
if(!_interactable) _interactable = GetComponent<Interactable>();
// attach the callback on runtime (won't appear in the inspector)
_interactable.OnClick.AddListener(DestroyObject);
}
private void DestroyObject()
{
// destroy the object of the interactable if no target was provided
if(!_targetToDestroy) _targetToDestroy = _interactable.gameObject;
Destroy(_targetToDestroy);
}
}
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 ();
}
}
I can't get my button to change the scenes.
Trying to change scene when a UI button is clicked. I have a script called SceneRemote.cs that just does this:
using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections;
public class SceneRemote : MonoBehaviour
{
public void Change(string scene)
{
SceneManager.LoadScene(scene);
}
}
This script was then added to the Canvas holding the button, then I pulled in that Canvas into the OnClick() component where it is set up in the following structure:
Runtime Only -> Canvas and SceneRemote.Change -> Scene1
Note: Both scenes have been added to the build settings.
0 -- CHECK your canvas is intact: MUST have EventSystem, MUST usually be 'scale with screen size'
1 -- CLICK "+" on the drag area of the button
2 -- DRAG to the button (in your case drag the holder of SceneRemote)
3 -- SELECT the correct function ("Change" for you)
4 -- ENTER the argument if any (in your case there will be a text field where you will enter the scene name)
5 -- LOG add a Debug.Log("yo... "+scene) statement inside your routine Change. Play, click button, look at console
6 -- SCREENSHOT the same as the one above and edit in to your question
I want to show popup when press the button.
But now it looks like this
I have viewed many tutorials about how to make a popup when press the button.
But they all make the popup by script,not instantiate the prefab.
I'm not sure if I can instantiate the prefab as I hope or it's not a good idea.
Here is my code
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class Purchase : MonoBehaviour,IPointerClickHandler
{
public GameObject purchasePanel;
public GameObject panelPosition;
public void OnPointerClick (PointerEventData eventData)
{
GameObject instantiatedPurchase = Instantiate(purchasePanel, panelPosition.transform.position,panelPosition.transform.rotation) as GameObject;
instantiatedPurchase.transform.SetParent(panelPosition.transform);
}
}
You would probably use Unity.UI, and just use a panel.
It is very easy (1) click "add canvas" (2) click "add panel".
Simply turn it on and off using
.SetActive
from your code. Enjoy! As you can see it's this easy:
Try turning it on and off in the Editor with that toggle on Inspector. In code it's just..
public GameObject popupPanel;
...
popupPanel.SetActive(false); or...
popupPanel.SetActive(true);
I describe my way how to make popup.
There is a .gif how it looks like.
And there is link where it is described (Dacke is nickname there).
I am trying to create a Quit button in Unity, but when I add my script to the button and click it, it doesn't quit.
Here is my C# script:
using UnityEngine;
using System.Collections;
public class Quit_App : MonoBehaviour {
void OnClick() {
Application.Quit();
}
}
I have created it and assigned to the canvas using the UI, and I use the Button(Script) box in order to execute this code using the OnClick() box.
There, I selected it as object MyButton and the Quit_App() function using a string name.
Your script assumes that calling the method OnClick will magically make the click detected, but that is not the case.
You need a Menu Manager script added to the scene exposing a public method to be binded to the Button component.
Here the setup you need:
The script MenuManager is attached to the MenuManager game object:
The code in the MenuManager script is real simple:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MenuManager : MonoBehaviour {
public void ExitNow()
{
Application.Quit();
}
}
I uploaded the package with a fully functional implementation here.
First, this answer assumes that your code works and the only problem is that the Application.Quit () command does not execute.
The Application.Quit () command does not work when testing the application in the Unity Editor (for example, by pressing the "Play" button). It would close the Unity Editor.
To test, go to the "Files / Build and Run" menu.
This will build and execute the project and Application.Quit() will be execute properly.
After a search I found that onclick not a member of MonoBehaviour look at OnMouseDown on the following link http://docs.unity3d.com/ScriptReference/MonoBehaviour.OnMouseDown.html
I find a semi-solution for this problem.I used this script that allows me to exit when i press the escape button.
using UnityEngine;
using System.Collections;
public class NewBehaviourScript : MonoBehaviour {
// Use this for initialization
void Start () {
if (Input.GetKey("escape"))
Application.Quit();
}
// Update is called once per frame
void Update () {
if (Input.GetKey("escape"))
Application.Quit();
}
}
if you mean exit Play Mode thats completely an other thing. because quit is only when its built into an app.
Quitting the app:
Application.Quit();
Quitting the play mode:
UnityEditor.EditorApplication.isPlaying = false;