UI Canvas Start - Quit Game - c#

I have 2 Canvas UIs (Start and Exit) on the home screen of my game. I want to add 1 script that does the following:
When the UI Image Play is clicked
public void NextLevel(int level)
{
Score.Inicializar();
Application.LoadLevel (1);
}
When the UI Image Exit is clicked
Application.Quit ();
C# if possible.

Add this script to your Play image:
using UnityEngine;
using UnityEngine.EventSystems;
//using UnityEngine.SceneManagement; // uncomment this line in case you wanna use SceneManager
public class HandleClickOnPlayImage : MonoBehaviour, IPointerClickHandler {
int level = 1; // I'm assuming you're setting this value somehow in your application
public void OnPointerClick (PointerEventData eventData)
{
Score.Inicializar();
Application.LoadLevel (level);
// SceneManager.LoadScene (level); // <-- use this method instead for loading scenes
}
}
And add this script to your Exit image:
using UnityEngine;
using UnityEngine.EventSystems;
public class HandleClickOnExitImage : MonoBehaviour, IPointerClickHandler {
public void OnPointerClick (PointerEventData eventData)
{
Application.Quit();
}
}
And finally make sure no other ui blocking/overlapping your images, otherwise they won't receive any click event.
Not to mention that a script file's name should match the name of it class :)

Related

Unity - How to Interact With Objects Between UI and World Space

I am new to unity and want to make a card - board game. I want to be able to place a card on a particular tile on the board. However, my draggable script that is attached to my card seems to not interact with the world space tile (it will interact with other UI). The world space tile has a droppable script, that currently doesn't have any real functionality, but should at least output a message to the console when a user hover overs it with their cursor. It doesn't even do that. (Again, droppable works with other UI elements) I thought that maybe because when the user is selecting their cards from their hand, and the canvas is in render mode - screen space camera - that had an effect, so I wrote a script that changes the render mode of the canvas to world space and it still seems to not interact. I will attach as much as I can for a clearer explanation, but at this point all I wish is for the board or tile to be able to recognize the user is hovering over it with the cursor.
Any help or information is appreciated, I am trying to absorb as much knowledge as I can, so even if you don't have a solution, advice is useful!
Dropzone.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class Dropzone : MonoBehaviour, IDropHandler, IPointerEnterHandler, IPointerExitHandler
{
public void OnPointerEnter(PointerEventData eventData)
{
Debug.Log("OPEnt");
}
public void OnPointerExit(PointerEventData eventData)
{
Debug.Log("OPExt");
}
public void OnDrop(PointerEventData eventData)
{
Debug.Log("on drop " + gameObject.name);
}
}
Draggable.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class Draggable : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
Transform originalParent = null;
private RectTransform RectTransform;
private void Awake()
{
RectTransform = GetComponent<RectTransform>();
}
public void OnBeginDrag(PointerEventData eventData)
{
originalParent = this.transform.parent;
this.transform.SetParent(this.transform.root);
GetComponent<CanvasGroup>().blocksRaycasts = false;
this.transform.parent.gameObject.GetComponent<CameraRender>().ChangeState();
}
public void OnDrag(PointerEventData eventData)
{
RectTransform.anchoredPosition += eventData.delta;
}
public void OnEndDrag(PointerEventData eventData)
{
this.transform.parent.gameObject.GetComponent<CameraRender>().ChangeState();
this.transform.SetParent(originalParent);
GetComponent<CanvasGroup>().blocksRaycasts = true;
}
}
CameraRender.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraRender : MonoBehaviour
{
enum RenderModeStates { camera, overlay, world };
RenderModeStates m_RenderModeStates;
Canvas m_Canvas;
// Use this for initialization
public void Start()
{
m_Canvas = GetComponent<Canvas>();
}
// Update is called once per frame
public void Update()
{
//Press the space key to switch between render mode states
if (Input.GetKeyDown(KeyCode.Space))
{
ChangeState();
}
}
public void ChangeState()
{
switch (m_RenderModeStates)
{
case RenderModeStates.camera:
m_Canvas.renderMode = RenderMode.WorldSpace;
m_RenderModeStates = RenderModeStates.world;
break;
case RenderModeStates.world:
m_Canvas.renderMode = RenderMode.ScreenSpaceCamera;
m_RenderModeStates = RenderModeStates.camera;
break;
}
}
}
I have tried to add a script that transitions render modes from Screen Space to World Space, I have attached box colliders to the world space objects.
For non-UI 3D objects in order to receive the IPointerXYHandler etc messages you need
Collider on the according object(s)
a PhysicsRaycaster component attached to your Camera (and make sure the according Layers are selected as "Event Mask" in its Inspector)

Unity button hover animation plays when the scene starts, not when the mouse pointer is over the gameobject

ive made a hoveron and hoveroff animation which when the mouse pointer is over the button (hovering) it slides the button out slightly to the left, and hover off the opposite animation where it slides back to its original position.
however it plays hoveron when the scene starts and i cant get hoveroff to play at all, anybody know a fix?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class hoverscript : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
public RectTransform NewGameMenuButton;
// Start is called before the first frame update
void Start()
{
NewGameMenuButton.GetComponent<Animator>().Play("Hover Off");
}
public void OnPointerEnter(PointerEventData eventData)
{
NewGameMenuButton.GetComponent<Animator>().Play("Hover On");
}
public void OnPointerExit(PointerEventData eventData)
{
NewGameMenuButton.GetComponent<Animator>().Play("Hover Off");
}
}
I hadn't dragged the button on the script.

I decided to keep both scenes loaded in the hierarchy since it's easier to reference variables between them. How can I restart then a new game?

In the Hierarchy I have two scenes when running the game first time.
The scene that contains all the gameplay objects all the objects are disabled.
The main menu scene objects are enabled.
Now this script is attached to the main menu and the function PlayGame is being called from a Play button On Click event :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class MainMenu : MonoBehaviour
{
public static bool sceneLoaded = false;
public void PlayGame()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
SceneManager.LoadScene(0, LoadSceneMode.Additive);
SceneManager.sceneLoaded += SceneManager_sceneLoaded;
}
private void SceneManager_sceneLoaded(Scene arg0, LoadSceneMode arg1)
{
sceneLoaded = true;
}
public void QuitGame()
{
Application.Quit();
}
}
And this script is attached to one active gameobject on the gameplay scene and all it does is to check if I'm in the main menu or not and then to decide if to setactive or not all the gameplay objects :
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
public class ActiveScene : MonoBehaviour
{
public GameObject gameData;
// Update is called once per frame
void Update()
{
if(MainMenu.sceneLoaded == true)
{
gameData.SetActive(true);
MainMenu.sceneLoaded = false;
}
if(BackToMainMenu.loadedMainMenuScene == true)
{
gameData.SetActive(false);
BackToMainMenu.loadedMainMenuScene = false;
}
}
}
This is a screenshot of the Hierarchy :
You can see that the GameObject name Active Scene in the top scene is enabled gameobject while all the other gameobjects are disabled. On this Active Scene I attached the script ActiveScene.
This way when I click the Play button a new game start and when I hit the escape key it's getting back to the main menu.
The problem is when I hit the escape key and then click the Play button again it will keep load to the Hierarchy the main menu scene over and over again.
And this is after few times I hit the escape key and then started a new game over again by clicking the Play button :
This is the script to return to the main menu using the escape key. The script is attached to the Game Manager object in the game scene :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class BackToMainMenu : MonoBehaviour
{
public static bool loadedMainMenuScene = false;
private void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
loadedMainMenuScene = true;
}
}
}
I want to keep both scenes in the Hierarchy all the time since it's easier then to reference between variables in both scenes.
When both scenes in the Hierarchy it's also easier to restart a new game by re loading the gameplay scene.
The problem is when restarting a new game I have to set the flag bool sceneLoaded to false but then next time since it's false it will load the main menu scene to the Hierarchy over and over again.

Touch event does not do any action on the Unity c # smartphone

I have this code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.Audio;
using UnityEngine.EventSystems;
public class start : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
public GameObject musica;
public bool pulsado;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void OnPointerDown(PointerEventData eventData)
{
pulsado = true;
audio();
SceneManager.LoadScene("pajaro");
}
public void OnPointerUp(PointerEventData eventData)
{
pulsado = false;
}
void audio()
{
musica.SetActive(true);
}
}
When I export it to Android, touch does not work, but if it works in unity
You're using OnPointerDown, this is specific to the mouse, this event does not fire for Touch input (touch input does not have a concept of "up" and "down").
In order to have touch input, you have to use Input.touches during the Update() loop.

Change GameObject Component on InitializeOnLoad

I created script that i want to use as main script when my game launch. Now i want to access specific button text via that script and change it's text. I have problem because my text is not changing. Here is what i was trying:
static main()
{
Debug.Log("Up and running");
GameObject devButtonText = GameObject.Find("devButtonText");
Text text = devButtonText.GetComponent<Text>();
text.text = "Test";
}
Button is devButton and text is devButtonText
full script
using UnityEngine;
using UnityEditor;
using System.Collections;
using UnityEngine.UI;
[InitializeOnLoad]
public class main : MonoBehaviour {
static main()
{
Debug.Log("Up and running");
GameObject devButton = GameObject.Find("devButton");
Text text = devButton.GetComponentInChildren<Text>();
text.text = "Test";
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
I created script that i want to use as main script when my game launch.
The InitializeOnLoad attribute must be used to run a function when the Unity Editor starts, not the game. Every editor script won't run when you compile your game. Unity documentation
Sometimes, it is useful to be able to run some editor script code in a project as soon as Unity launches without requiring action from the user.
Instead, create an Empty GameObject and attach the following script :
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class ChangeText : MonoBehaviour
{
private void Awake()
{
GameObject devButton = GameObject.Find("devButton");
Text text = devButton.GetComponentInChildren<Text>();
text.text = "Test";
}
}
Even better :
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class ChangeText : MonoBehaviour
{
// Drag & Drop the desired Text component here
public Text TextToChange ;
// Write the new content of the Text component
public string NewText ;
private void Awake()
{
TextToChange.text = NewText;
}
}
The script will automatically be called when the scene starts.
When Initializing a MonoBehaviour
You should use Start, Awake or OnEnable.
You shouldn't use constructor, static constructor or field initialization (like public GameObject go = GameObject.Find("devButton");)
This should work:
using UnityEngine;
using UnityEditor;
using System.Collections;
using UnityEngine.UI;
public class main : MonoBehaviour {
void Awake () {
Debug.Log("Up and running");
GameObject devButton = GameObject.Find("devButton");
Text text = devButton.GetComponentInChildren<Text>();
text.text = "Test";
}
}
Edit
Given the name main I guess this is the starting point of your project so if your script is not attached to any game object then Start, Awake or OnEnable would not be called. In this case you should attach it to a game object and change the unity script execution order and bring the script to the earliest point.

Categories