Unity 5 change button text created with UnityScript - unity3d

In my 2D project I create a canvas and a button in code. I would like to set the text of the button in code, but after numerous attempts I can't seem to do it.
My UnityScript code:
#pragma strict
var loginButton : UnityEngine.UI.Button;
function Start () {
var canvas = new GameObject ("canvas", Canvas);
var instance : UnityEngine.UI.Button = Instantiate(loginButton);
instance.GetComponent(UnityEngine.UI.Text).text = "login"; //Error below
instance.transform.position = Vector2(0,0);
instance.transform.SetParent(canvas.transform);
}
This provides an error
"NullReferenceException: Object reference not set to an instance of an object
GameLogicLogin.Start () (at Assets/GameLogicLogin.js:11)"
--------------------------------Edit---------------------------------------
The generated hierarchy looks like this: http://puu.sh/iMYe6/4f4a8f545c.png
On the left at the bottom is the prefab I link to the script.
The following line doesn't cause an error and seems to change the text, but the change doesn't show up in game nor does the original text assigned to the "Text"in the prefab.
instance.GetComponentInChildren(UnityEngine.UI.Text).text = "login";

If you would of built your button in the unity editor you could easily change its text in script like this:
var button = GameObject.Find("buttonObjectName").GetComponent<Button>();
button.GetComponentInChildren<Text>().text = "What ever you like";
I imagine you can easily adjust this to fit your needs without being spoon fed.

You are instantiating a UnityEngine.UI.Button, that doesn't have a component for UnityEngine.UI.Text hence the error.
Is there any reason why you are instantiating that object?
If you are linking in the editor a game object to loginButton, and I think you are, you should do something like this:
var comps = loginButton.gameObject.GetComponentsInChildren(UnityEngine.UI.Text);
comps[0].text = "login";

Related

Unity how to Create Texts via script?

I'm trying to create Texts via script. I want to create texts with the name of objects of a certain tag.
"For example, if I have two objects named Cube and Sphere and both have a tag of "TargetObj" then their names should be displayed as texts on the screen(in the case Cube, Sphere)"
I want to achieve this regardless of the number of objects. so a loop is needed.
Here is what I've tried so far.
[SerializeField] GameObject LevelCanvas;
targetObjects = GameObject.FindGameObjectsWithTag("TargetObj");
foreach (var obj in targetObjects)
{
Text mytext = LevelCanvas.AddComponent<Text>();
mytext.text = "Find " + obj.name;
Font ArialFont = (Font)Resources.GetBuiltinResource(typeof(Font), "Arial.ttf");
mytext.font = ArialFont;
mytext.material = ArialFont.material;
}
it only shows one object name although I have 2 more objects that were supposed to be shown as well.
You need to create a text object on a new gameobject.
static Text CreateText(Transform parent)
{
var go = new GameObject();
go.transform.parent = parent;
var text = go.AddComponent<Text>();
return text;
}
var mytext = CreateText(LevelCanvas.transform);
myext.text = ...
Many components in unity can only be added once per game object. That means you need a separate game object for every text you want to show.
A typical way to approach this is to create a "prefab" of a game object which has a text element already. This way you can set a default font and other settings.
Then in code you use the Instantiate method on that prefab and via GetComponent() you can access the text component instance to set the desired string to display.

Unity2d: Trying to change the color of a GameObject from a different class

So I can see that the GameObject is in the List but it gives me a "Object reference not set to an instance of the object" error when trying to change color to it.
public class Paint : MonoBehaviour
{
//inside Create is where the list of objects are created
Create create = new Create();
ColorPicker colorPicker = new ColorPicker();
public void SetColor()
{
create = GetComponent<Create>();
if (create.GraffitiLetters.Count > 0)
{
colorPicker = GetComponent<ColorPicker>();
for (int i = 0; i < create.GraffitiLetters.Count; i++)
{
create.GraffitiLetters[i].GetComponent<Image>().color = colorPicker.GetColor();
}
}
}
}
I bet it has something to do with me having to get hold of the component first but I dunno?
----------------------EDIT--------------------------
OK, new attempt for the same problem.
I have a class called ColorPicker. Inside of it I have a Color color; which gets an rgba value.
Now I want to grab that value from another class. How?
Inside my Paint class I tried this.
ColorPicker colorPicker = new ColorPicker();
colorPicker = GameObject.Find("color").GetComponent<ColorPicker>();
Debug.Log(colorPicker.color);
I've also tried various other ways but I just don't get it. seems like a simple problem.
--------- Second edit------------------
I have tried all of these. I can't understand it. all the questions that seem similar has gotten one of these answers. nothing works for me.
//This Gets NullReferenceException
//Debug.Log("test color" + colorPicker.GetComponent<ColorPicker> ().GetColor());
//This Gets NullReferenceException
//colorPicker.GetComponent<Color>();
//Debug.Log("test 2" + colorPicker.color);
//This Gets NullReferenceException
// colorPicker.transform.Find("color");
// colorPicker.GetComponent<Color>();
// Debug.Log("test 3 " + colorPicker.color);
You did not specify what line gives the Null Reference Exception, so proper help cannot be given. I will write down some things that may be the issue:
Create create = new Create();
This is not the issue, but it's confusing. I don't think you want to instansiate this class, it makes no sense. What value is an empty instance. You're later setting it to this GameObject's component, which makes sense through create = GetComponent<Create>();.
So I'll assume that create is null. This means you haven't attached the Create component/script to the GameObject that has the Paint script on it.
If that is not the case, I'm guessing your issue lies in the next step, namely that the create.GraffitiLetters[i] may not have an Image component.
Sidenote: Since your Paint class is dependant on its GameObject having a Create script, you could set an attribute on the class, that validates it for you:
[RequireComponent(typeof(Create))]
public class Paint: MonoBehaviour

Unity How do I capture GameView in my EditorWindow

I'm making a simple leveleditor window for my game and I want to capture GameView image to that leveleditor window. I'm using ScreenCapture.CaptureScreenshotAsTexture() but it gives the image of leveleditor window, I also try Texture2d.ReadPixels but it gives the same result.
You could have a look at my answer here. I wrote a script that can capture any window that is currently focused.
You could easily adopt it to allways make the GameView the captured window. For example using reflection like this (source)
public static EditorWindow GetMainGameView()
{
var assembly = typeof(EditorWindow).Assembly;
var type = assembly.GetType("UnityEditor.GameView");
var gameview = EditorWindow.GetWindow(type);
return gameview;
}
and replacing
var activeWindow = EditorWindow.focusedWindow;
with
var activeWindow = EditorWindow.GetMainGameView();
Note that this will open a new GameView window if none was there yet.

Private integer not updating

Trying to write a script that's on several different objects where on mouseclick, 1 is added to a defined variable which then prints out. Currently when I click the objects, 1 is always printed.
#pragma strict
import UnityEngine.UI;
var theImage:UnityEngine.UI.Image;
var theSprite:Sprite; //The image you want to drag in the inspector
private var clickCount = 0;
function OnMouseDown () {
theImage.sprite = theSprite;
clickCount++;
Debug.Log(clickCount);
}
Here's my script. It also changes a GUI sprite. Seems like an easy fix, not sure where I've gone wrong.

Scripting GUI buttons to trigger an event of changing materials

Apologies if there's a similar question, however, I have probably seen it and it has not fixed my problem.
I am trying to write a JS script for unity in order to achieve an event to be triggered once clicked.
I have searched online on UnityAnswers website and others, the closest I can get is based on these questions
http://answers.unity3d.com/questions/368303/changing-shaders-of-a-gameobject-via-script-1.html
and this one
http://answers.unity3d.com/questions/319875/change-objects-material-using-gui-buttons-via-scri.html
and also looked at this one
http://docs.unity3d.com/ScriptReference/Material-shader.html
So, my code is this so far
var button2_tex : Texture;
var button3_tex : Texture;
var button4_tex : Texture;
var seat_mat1 : Material;
var seat_mat2 : Material;
var veneer1 : Texture;
var veneer2 : Texture;
var rend : Renderer;
var _mouseDown = false;
function Start() {
seat_mat1 = Resources.Load( "seat_mat1" );
seat_mat2 = Resources.Load( "seat_mat2" );
}
function Update(){
if(Input.GetMouseButtonDown(0)){
_mouseDown = true;
}
}
function OnGUI() {
GUI.Box (Rect (10,10,100,200), "Menu");
if (_mouseDown){
if (GUI.Button (Rect (20,40,40,20), button1_tex)){
if(seat_mat1){
rend.material = seat_mat2;
Debug.Log("This button was clicked!");
}
else{
rend.material = seat_mat1;
}
}
}
Please note some variables I haven't used yet, as am still testing bunch of other codes to get it working..
the code snippet I am trying to fix starts with "function OnGUI()" but I maybe wrong and could use some fresh insight.
this is a screenshot of the resulting script. The button on the left side is supposedly to change the colour of the material from seat_mat1 to seat_mat2 by the event of mouse clicking on the button.
I have attached the previous script to the 3D object in unity and had made a folder names "Resources" for the materials to be visible and referenced through the script.
My problem is that upon clicking the GUI button, nothing happens, and it maybe something very simple and I am just missing it .. apologies for being inexperienced in JS much or unity.
Thanks in advance.
EDIT:
So after playing a bit more with the code. I added a Debug.Log() after this line
GetComponent.<Renderer>().material = seat_mat2;
Debug.Log("This button was clicked!");
and seems to be this error that I am getting every time the button is pressed
"MissingComponentException: There is no 'Renderer' attached to the "scene_export3" game object, but a script is trying to access it.
You probably need to add a Renderer to the game object "scene_export3". Or your script needs to check if the component is attached before using it.
materialChanger.OnGUI () (at Assets/materialChanger.js:44)"
So with simple understanding, it seems that the renderer is not attached somehow?
Your code is working fine But still i think once you have loaded The materials in start function you do not need to load them every time. And one thing more is to make sure you have applied the script to the gameobject you want to change the material of. If you just want to change the color not want to change complete material use color property of material and your OnGUI function should look like this.
function OnGUI() {
GUI.Box (Rect (10,10,100,200), "Menu");
if (_mouseDown){
if (GUI.Button (Rect (20,40,40,20), button1_tex)){
if(GetComponent.<Renderer>().material == seat_mat1)
GetComponent.<Renderer>().material.color = seat_mat2.color;
else
GetComponent.<Renderer>().material.color = seat_mat1.color;
}
}
}
But if you do not use color poperty it will work fine just make sure you have applied script to game boject you want to change material i your case may be to your seat1.
Thanks Nain for your guidance, with your help I was able to come up with a partial solution, where I know I can fix from there.
The solution is as follows.
The code:
function OnGUI() {
GUI.Box (Rect (10,10,100,200), "Menu");
if (_mouseDown){
if (GUI.Button (Rect (20,40,40,20), button1_tex)){
var rendArray : Renderer[];
rendArray = GetComponentsInChildren.<Renderer>(true);
for(var rend : Renderer in rendArray){
if(rend.sharedMaterial == seat_mat1){
rend.sharedMaterial = seat_mat2;
Debug.Log("This button was clicked!");
}
else{
rend.sharedMaterial = seat_mat1;
}
}
}
}
}
After saving the script in MonoDevelop, open Unity where you create an empty game object and add all the objects with specific material e.g. seat_mat1 under it as children.
Then click on the empty object, rename it if you like, and add a "Mesh Renderer" component from "Add Component > Mesh > Mesh Renderer".
After that drag the script to the empty object and in the inspector you can find an option which you can choose a renderer called "rend". Choose the empty object as the Mesh Renderer.
Upon testing the outcome, I have managed to change materials of some objects together to seat_mat2, but unrelated materials changed themselves to seat_mat1 and once the button is clicked again, they alternate between seat_mat1 and seat_mat2
and even though it is not perfectly done, I am answering this question as anything else is fixable (I hope).
Thank you again Nain for your help :)