I'm trying to make a tower defense game. It's 3D but mostly viewed from above (2D).
But if I right-click the mouse the camera can zoom and roam using WASD keys. This works.
However, beside the playing field I have a sidebar where I pick which towers to build and so forth.
But when in zooming/roaming the sidebar becomes useless, so I want to hide it.
I'm trying to do that from the camera-script, so I added a script-component to the sidebar to make it static (accessible from anderswo):
using UnityEngine;
public class SideBar : MonoBehaviour
{
public static SideBar Instance;
void OnEnable() { Instance = this; }
}
In the camera-controller-script I try the below to hide the sidebar (and everything inside):
SideBar.Instance.GameObject.SetActive(false);
But that won't compile: CS1061: 'SideBar' does not contain a definition for 'GameObject'
GameObject is the name of the class, the actual instance is referenced using lowercase gameObject, so change:
SideBar.Instance.GameObject.SetActive(false);
to
SideBar.Instance.gameObject.SetActive(false);
and you should be fine
Related
I have created an empty GameObject (named FileCabinet) and assigned 4 prefabs as children (CabinetFrame, Drawer01, Drawer02, and Drawer03).
I would like to be able to click on any of the drawers to open them, but everything that I have tried thus far returns the parent GameObject FileCabinet as the item clicked rather than any of the children.
What's the best/simplest approach to call a method when any of the drawer child objects are clicked?
Update:
#LoïcLeGrosFrère provided a solution that ultimately worked. I initially had problems with events not firing because my UI was blocking raycasts to my 3D file cabinet object. I resolved the issue by adding a Canvas Group component to my Canvas and unchecking Blocks Raycasts, but this then disabled all my UI components. I then added Canvas Group components to individual UI panels and checked Ignore Parent Groups. I'm not sure if this is the correct way to handle the raycast conflict but it did work for me.
The simplest approach I see is:
Add a Physics Raycaster component to your camera.
Add a Event System to your scene, with a Input System UI Input Module.
Then, add this script to your drawers:
using UnityEngine;
using UnityEngine.EventSystems;
public class Drawer : MonoBehaviour, IPointerClickHandler
{
public void OnPointerClick(PointerEventData eventData)
{
Debug.Log($"Open {gameObject.name}.");
}
}
I am creating a game project with a main menu and 3 other scenes (MyWorld, ImportWorld, Lab). I've made the buttons on the main menu clickable to go the 3 other scenes, and want to make a back button to return to the main menu from the 3 scenes. I managed to make the back button work on the Lab scene, but when I tried the same steps and scripts to the MyWorld and ImportWorld, it doesn't bring to the main menu although they are clickable and changes color when hovered and clicked.
Below is the current script I am using for the Lab scene which is working. However I had a problem when I wanted to change the name of the text, suddenly it didn't worked. But luckily I didn't save and just undo which makes the button workable again.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class ReturnMainMenu : MonoBehaviour
{
public void returnMenu()
{
SceneManager.LoadScene("MainScene");
}
}
Below is the script I used for the Main Menu scene which opens up the 3 other scenes and works fine.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class ButtonTrigger : MonoBehaviour
{
public void btnMyWorld() //function when clicked, open My World scene
{
SceneManager.LoadScene("MyWorld");
}
public void btnImportWorld() //function when clicked, open Import World scene
{
SceneManager.LoadScene("ImportWorld");
}
public void btnLab() //function when clicked, open Lab scene
{
SceneManager.LoadScene("Lab");
}
public void btnQuit()
{
Application.Quit();
}
public void btnReturnMainScene() //function when clicked, should return to Main Menu
{
SceneManager.LoadScene("MainScene");
}
//tried adding this function to the Back buttons but didn't work
}
I've tried various scripts (including entering scene index and scene name), changed the canvas position in hierarchy to be on top, have Event System and RayCast target but nothing seems to fix the problem. Does anyone know what might be the cause that makes the button clickable, changes color when hover but doesn't load the Main Menu scene? And as I mentioned I had problems with the workable back button at Lab scene which stops working when I changed my text name, so maybe does it have anything to do with the project settings/scripts?
Maybe you didn't put the scene in build setting.
As in my understanding from the information provided, you have established a working code, which you use in multiple areas and scenes.
Understanding from the issue you are presented:
A button has been established and is clickable Returning a colour change to prove it.
The text your tried to change is about the scene change within your script.
public class ReturnMainMenu : MonoBehaviour
{
public void returnMenu()
{
UnityEngine.SceneManagement.SceneManager.LoadScene("MainMenu");
//Has to be written exactly as the Scene you are aiming to load up.
//Change the steps to include SceneManagement.
}
}
Look up if it is written down correctly keeping Case sensitivity in mind.
Check if the scene is added to your Build settings Found here!
Another area to take a look at is, if you have attached the script to your button, where it gets told on what it is supposed to be doing, OnClick -> do this action.
See attached below!
(Make sure it is enabled for both: Runtime / Editor)
Make sure the button has "Interactable" as checked (Ticked on)
If you copied the button from another scene, within unity more often than not there will be issues with it that it won't work as intended, for that I recommend making a copy of the button you wish to use and make a prefab out of it. (Which can be used in every area that you desire and scenes you desire).
How to get Gameobject automatically with script?
I need know. button OnClick method empty if the scene changes. My gameObject tpye Don'tDestroyLoad.
Instead of changing the object in the field you can use a script to then have GameObject gameObjectToClick to be changed. Use the inspector to add a script to the button called "Click", then drag the button object into the object field shown in the screenshot and then select the function OnClick(). Click has the following code:
using UnityEngine;
using System.Collections;
public class Click : MonoBehaviour {
public GameObject gameObjectToClick;
void OnClick(){
gameObjectToClick.SpecialFunction(); //call special function you wanted to call
}
}
Simply change gameObjectToClick through another script how you would normally achieve it and change it (e.g button.GetComponent<Click>().gameObjectToClick = otherGameObject) Also change SpecialFunction() to the function you would have set in the dropdown menu in the screenshot.
Task:
I want to create a context menu item that will work on GameObject selected in Hierarchy. This action should be available only when selected GameObject is a Prefab. I'm working on Unity 5.3.2
Code:
File MenuItems.cs is located in Assets\Editor
using UnityEditor;
using UnityEngine;
public static class MenuItems
{
[MenuItem("GameObject/Action on prefab", false, 14)]
private static void MenuActionPrefab()
{
}
[MenuItem("GameObject/Action on prefab", true, 14)]
private static bool ValidateMenuActionPrefab()
{
var isPrefab = PrefabUtility.GetPrefabParent(Selection.activeGameObject) != null;
return isPrefab;
}
}
Problem:
The problem is that the menu item is visible (and can be clicked) no matter if selected GameObject is a Prefab or not. I have tested code in debugger and value returned from ValidateMenuActionPrefab() is OK (true when I run it on Prefab, false on non-prefab gameobject).
I've read somewhere that Unity 5 have problem with validation methods but the example from UNITY EDITOR EXTENSIONS – MENU ITEMS about validation in Assets work perfectly OK.
Question:
So if this is a proper solution? Or is there another way to achieve same goal?
Additional info:
I have tried to run those methods simple way using:
[MenuItem("GameObject/Action on prefab")]
and
[MenuItem("GameObject/Action on prefab", true)]
but in this case there is no Action on prefab in context menu. Also this item isn't visible when I try not to set priority index.
Edit:
Behaviour should be simillar to Select Prefab item (visible on screenshot). When object isn't connected to prefab field should be grey and not-clickable. When object is a prefab field is black and can be clicked.
I've just set up a new unity3d project and your code works then clicking on the menu Gameobject/Action on Asset.
I'm using Unity3d 5.3.4f1. Maybe it's a bug in your specific version, however I didn't find any mention about this neither in the 5.3.3 nor the 5.3.4 changelog
However when you right-click and open the context menu over an object in the hierarchy, the ValidationMethod is not called, so the context menu element is always enabled. But if you actually click the context menu item, then the validation method is called; if it returns false then no action is performed.
Seems like a bug, but at least is safe to use it.
Prefab selected
Instance selected
I am just starting with unity and having problems to show/hide menu panel with a button click.
I am using unity 5 and able to do it by playing On Click() button parameter right in the inspector:
I click "+", drag my panel in object field, and the select GameObject > SetActive(Bool) function.
However what I am looking to learn is the way to achieve similar behavior with C# script. I tried:
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using System.Collections;
public class closebutton : MonoBehaviour {
public GameObject menu;
void OnMouseDown() {
menu.SetActive(false);
}
}
but nothing happens...
Please help me to achieve this basic task :)
The way you are already doing it is better (in inspector with onClick).
If you are just curious then you can do the following:
void Start()
{
GetComponent<Button>().onClick.AddListener(() => {
menu.SetActive(false);
});
}