Unity3D - Turning off a GameObject's guiTexture fails to respond - c#

I've been struggling with what appears to be a simple task for the past few hours. I have been successfully able to turn a GameObject's guiTexture on an off using GameObject.guiTexture.enabled as I have read in other similar questions. I do this in a script that is attached to the GameObject I wish to toggle.
The problem arises when I try to preform this same command from another script that is attached to an empty game object in my scene. When I interact with the button, simply nothing happens.
To give this some context, I am trying to create functionality to switch menus on the screen. When a user taps a certain UI button, I want to call unloadMenu() so I can wipe everything off the screen and draw the textures that belong to the appropriate menu.
//When the user lifts their finger
void OnTouchEnded ()
{
switch (this.gameObject.name)
{
//If they have selected the quiz button
case "QuizButton":
//this.guiTexture.enabled = false;
//Call the unloadMenu function which will clear the GUITextures
menuMgr.unloadMenu();
break;
The commented out section is what works fine. But now, I wish to perform this code in a function that is located in another script - menuMgr.unloadMenu()
This is what the MenuManager script looks like:
public GameObject quizButton;
void unloadMenu()
{
quizButton.guiTexture.enabled = false;
}
I have ensured to drag the quizButton gameobject from my scene into the inspector and connect it properly with the variable I have created yet nothing happens when this function is called. Does anyone have any idea why? Thanks in advanced.

How you declare MenuManager creates a new script while the reference to quizButton is in your MenuManager GameObject. That is why your menuMgr.UnloadMenu didn't do anything.
I have created something similar to yours and I found it worked fine :
Quizbutton Script:
public GameObject menuMgr; // reference to the empty game object (menu manager)
void OnMouseDown() // In your case, this is OnTouchEnded
{
// get the script of menu manager here
MenuMgrScript menuscript = menuMgr.GetComponent<MenuMgrScript>();
// and execute the function you want
menuscript.UnloadMenu();
}
Menu Manager Script:
// this script is exactly the same as yours, nothing's wrong here
// oh except add public to function UnloadMenu, so it can be called
// in the quizbutton script
public GameObject quizButton;
public void UnloadMenu() {
quizButton.guiTexture.enabled = false;
}

Related

Is it possible to add a onClick() Event action(in GameObject dropdown) without adding new script in Unity?

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

listeners not working on dont destroy on load objects in unity

Never used listeners before so I might just be not understanding how the work properly? But what's happening, is I add a listener to a button every time a specific scene is loaded.
Here is a list of events that stop it working:
When I first run the game, the listener works as intended, the buttons are created in the script, and the listener is added.
I change the scene, not destroying the object with the script containing the listener.
When the scene changes back, the script will re-create the buttons, and re-add the listener to the buttons.
Using a simple log to check the method the listener should run, the log will no longer show.
Where the listener is added:
foreach (Sprite texture in spriteImages)
{
//Creates a button
GameObject button = Instantiate (shopButtonPrefab) as GameObject;
// gets the buttons image compnent for changing
Image buttonImage = button.GetComponent<Image> ();
Image[] images = button.GetComponentsInChildren<Image>();
int newIndex = spriteIndex;
button.GetComponent<Button> ().onClick.RemoveAllListeners ();
button.GetComponent<Button> ().onClick.AddListener (() => ChangePlayerSkin (newIndex));
spriteIndex++;
}
The method that should be called.
private void ChangePlayerSkin(int index)
{
selectedSkinIndex = index;
Debug.Log ("noo");
if (skinPurchased [index])
{
currentSkinIndex = index;
foreach (GameObject button in shopButtons)
{
button.transform.GetChild (2).gameObject.SetActive (false);
}
shopButtons [currentSkinIndex].transform.GetChild (2).gameObject.SetActive (true);
}
}
// Stops working after the scene is re-loaded
Only trying to show relevant code. The buttons are created in OnSceneLoaded method every time a certain scene is run. Then the listener is added. Why will the listener only work the first time the scene is loaded? And not every time the scene is reloaded. Does the dontdestroyonload mess up the listener?
Since asking the question, I have further looked around at the rest of the program am cannot find the error to be anywhere else. Also can't find anything in the documentation relating to this? Still can't find a fix.
I have now tried to add the listener in a separate scripts in the awake method of the buttons. Still the listener will not work.

Unity object reference + serialized field. What am I missing?

I have a ui Button called "Attack Button". I have a script called HeroBattleController attached to my Gameobject. I have an attack button set as a serialized field and the attack button object dropped on the script in the editor.
[SerializeField]
private Button AttackButton;
public void SetButtonStatus(bool status) {
AttackButton.interactable=status;
}
Trying to access that gives me the error NullReferenceException: Object reference not set to an instance of an object
I thought putting the object in the editor would allow me to access it without having to "Find" the object. Can anyone point me in the right direction?
The error is on the line
AttackButton.interactable=status;
Complete HeroBattleController script
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class HeroBattleController: MonoBehaviour {
public static string SelectedHero;
[SerializeField]
private Button AttackButton;
public void SetButtonStatus(bool status) {
AttackButton.interactable=status;
}
public void HeroTouch() {
Debug.Log("Hero was touched: "+this.name);
SetButtonStatus(false);
}
// Use this for initialization
void Start() {
}
// Update is called once per frame
void Update() {
}
}
HeroTouch is called via onClick from the heroprefab object.
Update: I had the herobattlecontroller script attached to two objects, the gameobject at the root of the scene and the heroprefab object. I removed it from the gameobject and only have it on the prefab. However now when I drag the attack button to the script section on the prefab it stays bold and when I run the game the attack button reference is gone. I can drag the button to the running object and it functions as I expected. I'm clearly missing something on the connection between the object hierarchy and where the objects are usable. Putting the hero battle controller script on the root gameobject only acts the same way meaning it's bold and when ran it's missing the link.
hierarchy during edit
hierarchy during runtime
Does HeroBattleController attached to a prefab? and does the AttackButton is on the same prefab ? if not then there is a problem.

Cannot turn script back on

I've got an issue. When (Input.GetMouseButtonUp (0), Speedy script is disabled, thus we cannot enable it again from inside the script like shown below. How can we go around this?
public class Speedy : MonoBehaviour {
GameObject car;
if (speed == good)
{
GameObject car = GameObject.FindWithTag ("Car");
if (Input.GetMouseButtonUp (0))
{
car.GetComponent<Speedy>().enabled = false;
}
else car.GetComponent<Speedy>().enabled = true;
}
}
When disabled, a script wont run anymore and therefore you cannot enable it from the same script again (of course you could create a background thread which keeps it running, that would be a terrible solution).
Create a separate script called SpeedyEnabler, that enables the Speedy script on mouse click and add it to the GameObject.
Alternatively, declare a field isEnabled in Speedy, replace this.enabled by isEnabled and perform the desired actions when isEnabled is true.
If your script simply is supposed to act on input, enabling and disabling the script is not a good idea anyway. Instead, call a method from the input controller to act...

iGUI for Unity 3D

Well,I am working on my graduation project with unity 3d pro v4.5.0 ..I was using the normal method OnGUI() in my scripts but now i want to make a better interface for my project and i didn't anderstand how can i replace for example these lines in my "Database" Script:
if (GUILayout.Button ("Add to database"))
{
// Insert the data
InsertRow (FirstName,LastName);
// And update the readout of the database
databaseData = ReadFullTable ();
}
With just calling a Button1_click for example from my iGUI Class specially that every thing related to interface and buttons exists in OnGUI() method so how can i change all of that in my "Database" Script..i did anderstand how to make a button in iGUI that LOAD a scene or set an other function in the same iGUI Class but i just want to make buttons and iGUI field texts in iGUI MonoBehaviour Class and call them later whenever i need in my pricipal script "Database" if it is possible.Please am so in need for help. Thank you in advance.
You need do this:
create a public method in any script.
add the script to a GameObject.
Click the button and add the object with the script in the method
OnClick located in the inspector.
Choose your script and the public method where said No function.
Boala!!, when you click, your method run.

Categories

Resources