GameObject prefab is not showing in scene when activated in my script - c#

I have 2 classes attached to 2 different GUIs, PlayerInfoGUI and DiplomacyGUI.
I am trying to have a method in PlayerInfoGUI create a list of buttons dynamically which, when clicked will then pull up DiplomacyGUI. (Both GUIs as well as the dynamic buttons have their own prefabs created)
My PlayerInfoGUI class dynamically populates a panel with buttons using the PopulatePlayerList method.
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
using System.Collections.Generic;
public class PlayerInfoGUI : MonoBehaviour
{
public Image[] guiElements;
public GameObject playerInfoButtonPrefab, canvasParent;
public GameObject diplomacyMenu;
void Awake ()
{
PopulatePlayerList (GameEngine.competingPlayers);
}
void PopulatePlayerList (List<CompetingPlayer> players)
{
for (int i = 0; i < players.Count; i++) {
GameObject go = (GameObject)Instantiate
(playerInfoButtonPrefab);
Button playerInfoButton = go.GetComponent<UnityEngine.UI.Button>
();
CompetingPlayer receivingPlayer = players [i];
playerInfoButton.onClick.AddListener (() => handleDiplomacyMenu
(receivingPlayer));
go.transform.SetParent (canvasParent.transform, false);
}
}
public void handleDiplomacyMenu (CompetingPlayer receivingPlayer)
{
diplomacyMenu.SetActive (true);
}
}
The listener on the PlayerInfo Button is firing when clicked, but the diplomacyMenu GameObject is not showing up in the scene. Most of the research I have read says this should be a simple diplomacyMenu.SetActive(true), or a diplomacy.gameObject.SetActive(true), but this doesn't work.
I have confirmed that the code is being run, but the object cannot be seen.
Thank you in Advance!
PlayerInfoPrefab
PlayerInfoButtonPrefab
DiplomacyPrefab

You're using diplomacyMenu.gameObject when diplomacyMenu is already a game object, this might cause issues. Also make sure the prefab that is represented by diplomacyMenu has its children enabled. I think SetActive() just sets the top level parent to enabled, not any nested objects.

Related

enable/disable Objects in Unity

I am totally new in programmation and unity, so I have hard time with basically everything!
Here is my issue : I have a 2D static game with a grid of boxes. each box is made of buttons to click.
I want all the boxes but one not visible at the beginning, and then the box have a button to make boxes appears one by one.
here is my code :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class OpenBox : MonoBehaviour
{
// Start is called before the first frame update
private GameObject boite1;
void Start()
{
box1 = GetComponent<Box1> ();
}
void Update()
{
if (Input.GetKeyUp(KeyCode.Space))
{
box1.enabled = true;
}
}
}
The "Box1" is underline in red with message : CS0246, The type or namespace name could not be found.
I am not sure I know how to refer to the game object.
thank you for your help !
try use
gameObject.SetActive(false);
more detail unity doc

How can I make another click on escape key that will return to the game?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class BackToMainMenu : MonoBehaviour
{
public PlayerCameraMouseLook cammouselook;
// Update is called once per frame
void Update ()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex - 1);
PlayerCameraMouseLook.mouseLookEnable = false;
cammouselook.enabled = true;
}
}
}
Now when pressing the escape key it's loading the main menu scene.
And in the main menu I have NEW GAME button but not RESUME.
Instead making a resume button I want that pressing the escape key again when the main menu scene is loaded it will return back to the game to the current position it is. Either if it's in a middle of a cutscene or just idle in the game.
So when pressing the escape key again it will back to the game and continue from the last point.
Another sub question : Should I use : LoadSceneMode.Additive ? Or when switching between the game play scene and the main menu it should remove the current active scene and then load the next one ?
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex - 1, LoadSceneMode.Additive);
The main menu scene is at index 0 the game scene at index 1.
What I tried :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class BackToMainMenu : MonoBehaviour
{
// Variables
private bool _isInMainMenu = false;
public GameObject mainGame;
public PlayerCameraMouseLook cammouselook;
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
if (!_isInMainMenu)
{
SceneManager.LoadScene(0, LoadSceneMode.Additive);
PlayerCameraMouseLook.mouseLookEnable = false;
cammouselook.enabled = true;
// -- Code to freeze the game
mainGame.SetActive(false);
}
else
{
SceneManager.UnloadSceneAsync(0);
// -- Code to unfreeze the game
mainGame.SetActive(true);
}
_isInMainMenu = !_isInMainMenu;
}
}
}
And the Hierarchy :
The script is attached to the Back to main menu gameobject. And all the game objects are under Main Game.
First time when pressing the escape key it's loading to the main menu and main menu scene to the hierarchy. Second time pressing on the escape key it's starting the game over like a new game and removing unloading the main menu.
In both cases the game scene is stay in the hierarchy.
I will suggest you to add your main menu scene with the flag Additive as you mentioned.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class BackToMainMenu : MonoBehaviour
{
// Variables
private bool _isInMainMenu = false;
public PlayerCameraMouseLook cammouselook;
// Update is called once per frame
void Update ()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
if (!_isInMainMenu)
{
SceneManager.LoadScene(0, LoadSceneMode.Additive);
PlayerCameraMouseLook.mouseLookEnable = false;
cammouselook.enabled = true;
// -- Code to freeze the game
}
else
{
SceneManager.UnloadSceneAsync(0);
// -- Code to unfreeze the game
}
_isInMainMenu = !_isInMainMenu;
}
}
}
Take a look at the variable _isInMainMenu : it will track if you are in the main menu or not. Depends on the value, the Escape key will behave differently.
Note : I suggest you to type the current index of the scene in LoadScene / UnloadSceneAsync, unless you may want to change their index. In this scenario, type the scene name (Methods overload).
Now what I mean with // -- Code to freeze the game depends on your game :
You can have a unique GameObject that contains all the others GameObjects your scene has, and Enable / Disable it
myBigGameObject.SetActive(true/*or false*/);
Have a logic in MonoBehaviour to freeze the game while your in the main menu.
For example you can use the bool _isInMainMenu in Update() to stop them from doing their job ;
For example in this MonoBehaviour I created as an example :
public class ExampleMonoBehaviour : MonoBehaviour
{
private void Update ()
{
if (_isInMainMenu)
return;
print("I'm running !");
}
}
Have a Collection (List as an example) that stores every top hierarchy GameObjects and enable/disable them all as needed to behave the same as above.
Depends on how your code is, there is many other options.
I will highly suggest you to do the first or third option, unless you have a better approach.
The thing is, if you want to go back to the main menu, it shouldn't be very expansive (loading time, memory usage, ...) so you can disable GameObject from the main scene (third point) to restore them back quickly when you leave the main menu without reloading the entire scene. This would lead you to use serialization and deserialization.
Edited : Typo

Custom Inspector Array/List not Staying in play mode

First of all i want to say Sorry for my bad english and bad grammar
i have a problem and that is when i press play in the editor my array i made in my custom editor disapares(also does that when i update the script)!
First i got a script called “ColorChangerSingle” which is the script i declare varibles
using UnityEngine;
public class ColorChangerSingle
{
public GameObject gameObjectToChange;
public Color color;
}
then i have a script called “ColorChanger” which is the script i make a custom inspector for and all it got is a static list of “ColorChangerSingle”
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ColorChanger : MonoBehaviour {
public static List<ColorChangerSingle> single = new List();
}
and i have the custom inspector script called “CustomChangeColorInspector” which is the custom inspector script.
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(ColorChanger))]
public class CustomColorChangerInspector : Editor
{
public override void OnInspectorGUI()
{
for (int i = 0; i < ColorChanger.single.Count; i++)
{
EditorGUILayout.BeginHorizontal();
ColorChanger.single[i].gameObjectToChange = (GameObject)EditorGUILayout.ObjectField(ColorChanger.single[i].gameObjectToChange, typeof(GameObject));
ColorChanger.single[i].color = EditorGUILayout.ColorField(ColorChanger.single[i].color);
EditorGUILayout.EndHorizontal();
if (ColorChanger.single[i].gameObjectToChange != null)
if (ColorChanger.single[i].gameObjectToChange.GetComponent() != null)
ColorChanger.single[i].gameObjectToChange.GetComponent().material.color = ColorChanger.single[i].color;
}
EditorGUILayout.BeginHorizontal("box");
if (GUILayout.Button("Add To Array"))
{
ColorChanger.single.Add(new ColorChangerSingle());
}
if (GUILayout.Button("Remove Object In Array"))
{
ColorChanger.single.RemoveAt(ColorChanger.single.Count - 1);
}
EditorGUILayout.EndHorizontal();
}
}
when i add arrays in “not play mode” everything works(setting objects / changing the color of them) but when i press play the array gets “reset”, i think it has to do with the “ColorChanger” script where i set the list equal to a new list of ColorChangerSingle :/
any help is greatly appreciated!
Pictures:
https://gyazo.com/167ab826b6d578ec5a66d9d2586479e8
https://gyazo.com/847a063f9885478200c5a504be1dae2a
thanks for your time and have a great day! //Jrp0h
btw i hope the catagory is good and i know i can clean up the code alot but i made this really quick becuse im working on a secret project and did not want to use that code :)
I don't think your problem comes from the public static List<ColorChangerSingle> single = new List(); line.
What I'd recommend is adding [SerializeField] attributes to your single field and [System.Serializable] to your ColorChangerSingle class. Also are you sure your scene is saved before entering Play mode (this is a common mistake I used to do earlier on) ? If not you can add something like this at the end of the OnInspectorGUI() method :
if(GUI.changed && !Application.isPlaying)
{
EditorUtility.SetDirty(m_Target);
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
}
EDIT : Also you have to give your custom inspector script a reference to the instance of the script you want to edit (think of many of your GameObjects holding a ColorChanger script), when you call ColorChanger.single[i].gameObjectToChange = [...]; your CustomColorChangerInspector inspector script doesn't know which of your GameObject you refer too.
This is why you have to reference it. The way I usually do it for quick custom inspetocrs (there is more than one way to do it, using serialization for example) is :
[CustomEditor(typeof(ColorChanger))]
public class CustomColorChangerInspector : Editor
{
// I like to declare it once for all but you can also call "(ColorChanger)target" each time to refer to the target
private ColorChanger m_Target;
public override void OnInspectorGUI()
{
m_Target = target as ColorChanger;
for (int i = 0; i < ColorChanger.single.Count; i++)
{
EditorGUILayout.BeginHorizontal();
m_Target.single[i].gameObjectToChange = (GameObject)EditorGUILayout.ObjectField(m_Target.single[i].gameObjectToChange, typeof(GameObject));
[...]
}
}
}

Unity3d C# - How to check if a button has been pressed, and then instantiate an object

So for the past two days (no joke) I have been trying to figure out how to check if a button is pressed, and then if so, make it instantiate an object. I have tried multiple methods so far and maybe one of those methods were closer to getting where I wanted but for now I will just show what I have currently. Right now, the problem is me detecting if the button has even been clicked in the first place.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class Master : MonoBehaviour
{
public Button storeButton;
public Transform hands;
public GameObject gun1;
void OnEnable()
{
gun1 = GameObject.FindGameObjectWithTag("Weapon1");
hands = GameObject.FindGameObjectWithTag("Player").transform;
// storeButton.onClick.AddListener(MyFunction);//adds a listener for when you click the button
storeButton.onClick.AddListener(() => MyFunction());
}
void MyFunction()
{
Debug.Log("YOUR PRESSED THE DAMN BUTTON");
// Instantiate(gun1, hands.position, hands.rotation);
GameObject.Instantiate(gun1, hands.position, hands.rotation);
}
}
Add an EventSystem to your Scene.
Otherwise you cant click Buttons an other Stuff.
http://docs.unity3d.com/Manual/EventSystem.html

Find a GameObject and check if the user has clicked on it

I have recently been making the UI for a game I am creating and have run into a problem.
I have been trying to find a way in the new Unity 4.6 for the user to be able to click on a player card and have it select the player they clicked on.
public void Panel1Click()
{
GameManager.Player1Select ();
}
This is the way I am doing it at the moment, calling this when the player clicks on Panel 1, there are also 3 more for each of them.
I have been researching different methods on how to find the object the player clicks the execute the correct selecting code.
if (GameObject.Find ("Panel 1"))
{
print ("Click Panel 1");
GameManager.Player1Select();
}
This is one of the methods I tried, however nothing gets called. (Because it just checks if the object exists/is true? I think).
All these methods are linked to the EventSystem component on the panels.
Is there a more efficient way of condensing all the functions and just checking which panel the player clicks on?
You can add a collider to the game object (sprite), and then in the OnMouseDown function to test if it is clicked.
Select the card --> Add a box collider to it --> Add a MonoBehaviour script and attach to the card --> In the script, add function:
bool bClicked = false;
void OnMouseDown()
{
Debug.Log(gameObject.name + " is clicked");
bClicked = true;
}
You can actually have one parameter for your click handler. Supported types are: int, float, string and object reference. So you can define your handler like this:
public void SelectCharacter(int character) {
GameManager.PlayerSelect(character)
}
Then just set the parameter in the event trigger.
Create a script and put it on the object(Panel) you want to interact with, then try this code. In this example it finds the parent panel and sets it to inactive
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class CloseInventory : MonoBehaviour, IPointerDownHandler
{
GameObject inventoryPanel;
// Use this for initialization
void Start()
{
inventoryPanel = GameObject.Find("Inventory Panel");
}
public void OnPointerDown(PointerEventData eventData)
{
//SET WHAT TO DO HERE
inventoryPanel.SetActive(false);
}
}

Categories