Text in Prefabs is Empty - unity3d

i have created a text and under text there are two input fields. then i have created a prefabs of them and instantiated through code. and its working, but problem is the instantiated object is empty and does not show anything just a box, is there any solution to the problem i'm facing of.
Here is my code
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class SubmitButton : MonoBehaviour {
public GameObject objects;
public void Start () {
// Debug.Log ("ok");
}
public void InstantiateButton () {
objects.transform.position = new Vector3 (57.4f, 381.58f, 0f);
Instantiate (Resources.Load ("Prefabs/Bupivacaine"), new Vector3 (57.4f,
381.58f, 0f), Quaternion.identity);
}
}

If you're trying to display UI on the Canvas then you need to parent your prefab to the canvas.
go.transform.SetParent(canvasGo.transform, false);

To instantiate a UI object, you must make sure its a root child of a Canvas.
So you should change your instantiating method:
Instantiate(Resources.Load("Prefabs/Bupivacaine"), GameObject.Find("parentNamehere").transform);
enter the name of the parent gameobject in "parentNamehere" and remember: it must be a child of a canvas or the canvas itself.

Related

How to load next scene when pressed a button while playing in unity

This what I tried,
I was watching Brackeys
public void PlayGame()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
};
Your script probably doesn't work if you have 1 scene, or the current scene is at the end of the list in Build Settings.
Also you can use it this way:
//Add scenes in inspector
[SerializeField] private List<Scene> _sceneList;
public void LoadNextScene()
{
int currentScene = SceneManager.GetActiveScene().buildIndex;
if (currentScene < _sceneList.Count)
SceneManager.LoadScene(_sceneList[currentScene + 1].buildIndex);
else
print("Its last scene");
}
You can use SceneManager.LoadScene() method to load the Scene by its name or index in Build Settings.
The SceneManager.GetActiveScene().buildIndex gives you the index number of the current scene and you can add an incremental value to navigate to the next scene.
To do that,
Create a new script named SceneController and methods as follows,
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneController : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void LoadMenuScene() {
SceneManager.LoadScene("MenuScene");
}
public void NextScene() {
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
}
public void ReloadScene() {
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
}
Add the script to the Canvas object
Add the method to the button OnClick event in the inspector
NB: You can also use name or index values to load the scene (like LoadMenuScene)
For more: https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager.LoadScene.html

Unity says that 'Button' is not a Component and doesn't derive from Monobehavior

This was originally coded in unity 2018 then ported to unity 2019 because my main project is on that version. It works perfectly in unity 2018 (aside from that button.clicked += used to be button.AddListener())
The only relevant bit of the code is lines 12 - 17 but who knows.
Script is attached to object with the Button component.
Unity 2019.4.11f1
Returns the following error with the setup listed above:
ArgumentException: GetComponent requires that the requested component 'Button' derives from MonoBehaviour or Component or is an interface.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UIElements;
using UnityEngine.Events;
public class ButtonProperties : MonoBehaviour {
public ButtonType buttonType;
public string dest;
Button button;
void Start()
{
button = GetComponent<Button>();
//perform different functions dependant on the button type
if (buttonType == ButtonType.Scene)
{
//add ButtonLoadScene as a listener to the the button
button.clicked += ButtonLoadScene;
}
else if (buttonType == ButtonType.Menu)
{
button.clicked += ButtonLoadMenu;
}
//change button text to "Load Scene" + the name of the scene
string str = "Load " + dest;
GetComponentInChildren<TextElement>().text = str;
}
//private scene loader because event listeners cant take arguments >:(
void ButtonLoadScene()
{
SceneManager.LoadScene(dest);
}
void ButtonLoadMenu()
{
//array of all canvases in the scene
Canvas[] canvases = GameObject.FindObjectsOfType<Canvas>();
//foreach canvas
foreach (Canvas canvas in canvases)
{
//if the canvases name is the desired name
if (canvas.name == dest)
{
//turn all canvases off
foreach (Canvas c in canvases)
{
c.enabled = false;
}
//turn current canvas on
canvas.enabled = true;
//break loop
break;
}
}
}
}
public enum ButtonType
{
Scene,
Menu
};
I also tested this by adding a NewBehaviourScript to the button with Button button; and, in the start function, Start() {button = GetComponent<Button>();}
Same error
I believe you are using the wrong namespace for your button. Try changing:
using UnityEngine.UIElements;
to
using UnityEngine.UI;
There is a Button in both namespaces, but the one in UnityEngine.UI is likely the component you're working with.
Had somebody else on the team test the build, as I started to think from the comment thread, I was missing the UI library. Changing it to the UI library was the solution but not for me until I restarted the computer. Thank you Thomas Finch for the help.

How to instantiate objects in a specified place in unity?

I have an AR app that displays objects when it detects a QR code. The way I do it is with an empty object called model caller that has an script that instantiates a model, this is the script:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Android;
using UnityEngine.Networking;
using UnityEngine.UI;
public class Load_Models: MonoBehaviour
{
// Start is called before the first frame update
[Serializable]
public class PlaceModel
{
public string Clave = "";
}
public GameObject[] model;
public string[] clave_modelos;
public string URL;
public GameObject ModeloUI;
public PlaceModel placeModel;
Dictionary<string, GameObject> strGO = new Dictionary<string, GameObject>();
public void Start()
{
StartCoroutine(GetRequest(URL));
for (int i = 0; i < model.Length; i++)
{
strGO.Add(clave_modelos[i], model[i]);
}
}
IEnumerator GetRequest(string uri)
{
using (UnityWebRequest webRequest = UnityWebRequest.Get(uri))
{
// Request and wait for the desired page.
yield return webRequest.SendWebRequest();
string jsonForm = uri;
if (webRequest.isNetworkError)
{
Debug.Log("Error loading");
}
else
{
try
{
PlaceModel model_1 = JsonUtility.FromJson<PlaceModel>(webRequest.downloadHandler.text);
Instantiate(strGO[model_1.Clave], new Vector3(0, 0, 0), Quaternion.identity, transform); //instantiates the model
Debug.Log("Loaded");
}
catch
{
Debug.Log("Error in connection");
}
}
}
}
}
and this is what happens when I detect more than 1 QR (it also happens with only one, just without the models "fusing" with each other):
Explanation: It should display 3 models, 1 simple street (the white block) and 2 "no model" 3d texts, but, the idea is for the models to appear "attached" (I don't know how to word it) to the QR code. And I tried to do it by having model caller as a child of the ImageTarget and with model caller being in the dead center of the imagetarget, also with new Vector3(0, 0, 0).
Is there a way to do this?
I know that I can do it by simply using the prefab by itself instead of a script, but I need for the models to change depending on a website (which I already did).
I'm using EasyAR 3 for this
If I got you right, try to change Instantiate line this way:
Instantiate(strGO[model_1.Clave], transform.position, Quaternion.identity, transform);
Also, maybe, you dont need to set parent transform, it depends from your implementation.

How to display a name and score list for players using happyfuntimes and unity3d

This is related to happyfuntimes plugin if you have used it .
I am trying to make a game on it and stuck at a point of displaying score along with name to display on large screen while user is playing on his mobile.(i have already tried to display name and score on mobile screens have seen in sample do not need that ). Please suggest how can this be done if you have used happyfuntimes plugin.
I could see the HFTgamepad input having public GameObject player name which I am trying to access ,do I have to make array ?
public string playerName;
I am trying to put these name on array.
Displaying anything in unity is really normal unity issue and not special to happyfuntimes. Games display highscore lists, item lists, inventory lists, etc... A list of players is no different
Use the GUI system display text.
According to the docs if you want to generate UI dynamically you should make a prefab
So basically you'd make a UI hierarchy in the scene. When a player is added to the game Instantiate your name-score prefab, search for the UI hierarchy gameObject (do that at init time), then set the parent of the preafab you just instantiated so it's in the UI hierarchy.
Look up the UI.Text components that represent name and score and set their text properties.
There's various auto layout components to help layout your scores
When a player disconnects Destroy the prefab you instantiated above.
OR ...
Conversely you can use the old immediate mode GUI. You'd make a GameObject, give it a component that has a OnGUI function. Somewhere keep a list of players. Add players to the list as they connect and remove them from the list as they disconnect. In your OnGUI function loop over the list of players and call the GUI.Label function or similar to draw each name and score
Here's a hacked up example.
Assuming you have a PlayerScript script component that's on each player that has a public accessor PlayerName for getting the player's name then you can make a GameObject and put a script like this on it.
using UnityEngine;
using System.Collections.Generic;
public class ExamplePlayerListGUI : MonoBehaviour
{
static ExamplePlayerListGUI s_instance;
List<PlayerScript> m_players = new List<PlayerScript>();
static public ExamplePlayerListGUI GetInstance()
{
return s_instance;
}
void Awake()
{
if (s_instance != null)
{
Debug.LogError("there should only be one ExamplePlayerListGUI");
}
s_instance = this;
}
public void AddPlayer(PlayerScript bs)
{
m_players.Add(bs);
}
public void RemovePlayer(PlayerScript bs)
{
m_players.Remove(bs);
}
public void OnGUI()
{
Rect r = new Rect(0, 0, 100, m_players.Count * 20);
GUI.Box(r, "");
r.height = 20;
foreach(var player in m_players)
{
GUI.Label(r, player.PlayerName);
r.y += 20;
}
}
}
PlayerScript can then call ExamplePlayerListGUI.GetInstance().AddPlayer in its Start function and ExamplePlayerListGUI.GetInstance().RemovePlayer in it's OnDestroy function
public PlayerScript : MonoBehaviour
{
private string m_playerName;
...
public string PlayerName
{
get
{
return m_playerName;
}
}
void Start()
{
...
ExamplePlayerListGUI playerListGUI = ExamplePlayerListGUI.GetInstance();
// Check if it exists so we can use it with or without the list
if (playerListGUI != null)
{
playerListGUI.AddPlayer(this);
}
}
void OnDestroy()
{
...
ExamplePlayerListGUI playerListGUI = ExamplePlayerListGUI.GetInstance();
if (playerListGUI != null)
{
playerListGUI.RemovePlayer(this);
}
}
}

Disabling a script inside a child component through scripting on parent gameobject

I have a script inside a child gameobject , I want to disable it through coding on the parent Object ,help will be much appreciated,thanks.
edit:the script I want to carry out all the actions is not attached to the parent gameobject.
I hope this code is self commenting ;)
using UnityEngine;
using System.Collections;
public class ScriptAttachedToParent : MonoBehaviour
{
void Start ()
{
transform.GetChild (0).GetComponent<ScriptAttachedToChild> ().enabled = false;
// OR
//transform.Find("ChildGameObject").GetComponent<ScriptAttachedToChild> ().enabled = false;
}
}