How to find UI in code c# (button, Panel etc) - unity3d

in an empty game object i have a selection Manger script. I'm having some difficulties with finding a panel (called: OpenSelection) I created in Canvas.
I would like to find the panel where ever it is in the hierarchy and set enabled to true.
But the code isn't finding the panel. I'm not sure why.
any help would be appreciated
//UI
private GameObject panel;
// Start is called before the first frame update
void Start()
{
panel = GameObject.Find("OpenSelection");
panel.SetActive(true);
}

Generally, Find() is never the best approach for anything.
Try to set a variable reference to your OpenSelection, like you did with your panel, then call this variable.

GameObject.Find() only returns active GameObject. Here you are trying to find the OpenSelection panel which is not active. That's why the Find() is not finding the OpenSelection panel.

Related

What's the simplest way to handle mouse click events for children of a GameObject in Unity?

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}.");
}
}

Best way to organize OnClick events for Unity buttons?

enter image description here
Unity has a component called Button as part of its UI system which you can use to subscribe on-click events to it through the inspector which is incredibly useful.
However, when projects get larger, I run into trouble in many situations:
events subscribed this way in the inspector are not rearrange-able which makes buttons that have lots of events difficult to manage
changing the contents of the scripts used for events can cause the button to not recognize a function that was used for an event which means you have to re-reference it
if anything happens to the GameObject or prefab that stores the Button component such as it getting corrupt then all your events that were serialized onto the button would be wiped and you would need to re-reference all of them
the above points make debugging very very difficult
What are some ways I can work around the problems I've listed above?
Inject event functions inside the code:
public Button playButton; // set button in inspector
public void Start()
{
playButton.onClick.AddListener(() =>
{
transform.position = point1;
// do something..
});
}

No function dropdown in AnimationEvent in Unity

I try to handle some events during animations, but everywhere I look, every tutorial have access to AnimatorEvent Inspector like this:
A nice simple field, where you can select a function, I want this!
But instead of this, I always getting this sick 5 fields view, and don't have any idea how to handle animation event in this case!
I tried to create function test() with debug log, but it didn't work anyway. Why I can't get access to this simple window where I can choose an function?
You will need to add this animation into a State in Animator Controller (via Animator Window).
In the object which contains Animator component, attach your script component to it.
Open the Animation window, select the object above, you will see a dropdown of animations (top left) which Animator Controller of this object contains. Choose and add event to the animation you want to.
Select the event in Animation Window, in the Inspector, you should see the dropdown of public functions of your script component attached above.
Answer by Aluminium18
Sometimes it doesn't work even if you do all things according to tutorials or advices in internet. I often leave Unity editor launched for a long time without any interactions with it. After several gibernations and several days it can get buggy - various errors appear, you can't see some functions from scripts and so on. So, just reloading the Unity editor solves many of such issues for me. And it continues to happen so for several years no matter what Unity version you have. I tried versions from 2019.x.x to 2022.x.x - all this time Unity behaves itself the same.

Unity Editor - validating GameObjects

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

Input disabled after moving object in editor while in "play mode"

This is my first question here, i couldn't find an answer online for my problem.
Here it is:
I made a simple script to print some debug info about objects when i press a key. It works as expected unless i first move any of the objects in the scene editor while the game is running.
If i move any of the objects after i hit play it seems that Input.GetKeyDown is ignored after that. I am detecting the input inside the Update function of one of the objects.
public GameObject target;
void Update ()
{
if (Input.GetKeyDown(KeyCode.P))
{
Debug.Log (transform.position);
Debug.Log (target.transform.position);
}
}
NOTE: this is not the only thing im trying to achieve with my script, but is the simplest case i could build with the same problem.
thanks in advance!
I think that's because when you move the object, the Unity GameView will lose its focus. So just ensure it has the focus again (klick into it), before hitting the key.