I have the problem that I can't access my own script, that I attached to my image object, from another script.
I can access the Image(Script) that comes when I create the image object but that's all.
Error: object reference not set to an instance of an object.
My GameManager script is the one trying to access my custom image script and this is how:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class scriptGameManager : MonoBehaviour {
public Image img1;
private int gmValue = 0;
void Update () {
gmValue = img1.GetComponent<MyImageScript>().GetValue();
}
}
and the Script I attached to my Image Object is:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class MyImageScript: MonoBehaviour {
public int GetValue () {
return 10;
}
}
Any ideas what I'm doing wrong?
I can access the Image(Script) that comes when i create the image
object but that's all
If I am correct, you are trying to access MyImageScript from the scriptGameManager script and the MyImageScript is attached to the-same GameObject img1(Image) is attached to.But according to the image in your comment, you do NOT have MyImageScript script attached to the Image.
The only script that is attached to your Image is the ScriptCharSpot script.
You must attach MyImageScript to your image within the Editor or the through code before you can use GetComponent on it or else, it will return null. At the-same time, you need to cache the MyImageScript script instead of calling GetComponent each frame.
public class scriptGameManager : MonoBehaviour {
public Image img1;
MyImageScript imgScript;
private int gmValue = 0;
void Start () {
//Add MyImageScript to img1
img1.gameObject.AddComponent<MyImageScript>();
//Get/Cache MyImageScript that is attached to img1
imgScript = img1.GetComponent<MyImageScript>();
}
void Update () {
gmValue = imgScript.GetValue();
}
}
Related
I've been using Unity to create a simple 2D game but the problem is that even when the game object "player" gets destroyed, the gameobject "isDead" (text) doesn't appear.
This is my script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class youDied_Text : MonoBehaviour
{
private Transform player;
private Text isDead;
// public static bool isDead;
// Start is called before the first frame update
private void Start() {
isDead = GetComponent<Text>();
}
void checkForDeath()
{
if (player==false)
{
isDead.gameObject.SetActive(true);
}
else
{
isDead.gameObject.SetActive(false);
}
}
// Update is called once per frame
void Update()
{
player = GameObject.FindWithTag("Player").transform;
checkForDeath();
}
}
This script is attached in the text which I need to display in UI element.
As was noted currently you would get a NullReferenceException which is definitely not what you want.
There is absolutely no need / redundancy going through Transform at all actually. Simply store the GameObject reference instead
You are currently setting the object to inactive which has the Text attached ... which is the same object your component is attached to as well!
=> As soon as you end up in the second case once you set it to inactive => from now on Update is never called anymore!
In general as it sounds like this should only happen once anyway I would use a more event driven approach and have a component on your player like e.g.
public class Player : MonoBehaviour
{
public UnityEvent onDied;
private void OnDestroy ()
{
onDied.Invoke();
}
}
And then simply attach a listener/callback to that event once without poll checking states. You can do this either via the Inspector directly (just like in e.g. Button.onClick) or via code like e.g.
public class youDied_Text : MonoBehaviour
{
// Already reference things via the Inspector if possible!
[SerializeField] private GameObject player;
[SerializeField] private Text isDead;
private void Awake()
{
if(!isDead) isDead = GetComponent<Text>();
isDead.gameObject.SetActive(false);
// If you want to rather set it via the Inspector remove all the rest here
//if(!player) player = GameObject.FindWithTag("Player"). GetComponent<Player>();
// or even simpler
if(!player) player = FindObjectOfType<Player>();
player.onDied.AddListener(OnPlayerDied);
}
// If you want to rather set it via the Inspector make this public
private void OnPlayerDied()
{
isDead.gameObject.SetActive(true);
}
}
i have a canvas with a few GameObjects and i wanna instantiate a new GameObject that contains a canvas, so the porblem is its appears outside of main camera, and i need to set the render camera on the MainCamera of my game.
I have this and it does not work.
Main Camera where the game is running:
img of unity
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class newCanvas: MonoBehaviour
{
// Start is called before the first frame update
public GameObject text; //here i put the text, that I want to appear
private GameObject textD; //i use the for to delete the text
public void Start(){
textoD = Instantiate(text, transform.position, transform.rotation);//instantiate the text, and its instantiated outside of the maincamera of the game
Invoke("DeleteText",2f);//invoke to delete the game object
}
void DeleteText(){
Debug.Log("Delete text");
Destroy(textD);
}
}
i have something like this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class mainGAme : MonoBehaviour
{
public newCanvas text=null;
void Start(){
text = GameObject.FindObjectOfType<newCanvas>();
Instantiate(newCanvas);
}
void Update(){
}
}
And when i execute thegame, the object is instantiated, it is instantiated outside the maincamera as it doesn't have the render camera set to the game's maincamera.
Some know how to solvet, thank you<3
You need to set the parent of your gameobject's transform to your camera's transform.
https://docs.unity3d.com/ScriptReference/Transform.SetParent.html
Instantiate actually has a overload that allows you to set parent aswell
public static Object Instantiate(Object original, Transform parent);
https://docs.unity3d.com/ScriptReference/Object.Instantiate.html
You can get your camera via static properties in Camera
https://docs.unity3d.com/ScriptReference/Camera.html
You should check out the following docs to get a better understanding of how Transform and Gameobject are used.
https://docs.unity3d.com/ScriptReference/GameObject.html
https://docs.unity3d.com/ScriptReference/GameObject-transform.html
https://docs.unity3d.com/ScriptReference/Transform.html
Im trying to make a Vuforia Video Player with virtual buttons but when I try to pause and play it gives me and error. I looked at some forums and some question that is old but they didnt fix my problem. Error is:
Assets\vp_time.cs(23,9): error CS0120: An object reference is required for the non-static field, method, or property 'VideoPlayer.Pause()'
Assets\vp_time.cs(27,9): error CS0120: An object reference is required for the non-static field, method, or property 'VideoPlayer.Play()'
Code is:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Video;
using Vuforia;
public class vp_time : MonoBehaviour
{
public GameObject vbBtnObj;
public GameObject vbVpObj;
// Start is called before the first frame update
void Start()
{
vbBtnObj = GameObject.Find("VideoBtn");
vbBtnObj.GetComponent<VirtualButtonBehaviour>().RegisterOnButtonPressed(OnButtonPressed);
vbBtnObj.GetComponent<VirtualButtonBehaviour>().RegisterOnButtonReleased(OnButtonReleased);
vbVpObj.GetComponent<VideoPlayer>();
}
public void OnButtonPressed(VirtualButtonBehaviour vb){
VideoPlayer.Pause();
}
public void OnButtonReleased(VirtualButtonBehaviour vb){
VideoPlayer.Play();
}
// Update is called once per frame
void Update()
{
}
}
Well as the error says VideoPlayer is a type. It has no static method VideoPlayer.Play. You need a reference to an instance of type VideoPlayer and call the method on that instance.
vbVpObj.GetComponent<VideoPlayer>();
this line does absolutely nothing!
You rather wanted to store this reference in a field
// Drag this already in via the Inspector in Unity
[SerializeField] private VideoPlayer videoPlayer;
or do
private void Start ()
{
...
// As fallback get the reference on runtime ONCE
if(!videoPlayer) videoPlayer = vbVpObj.GetComponent<VideoPlayer>();
}
and later
videoPlayer.Play();
and
videoPlayer.Pause();
I'm making a game in Unity3D and I have a 2 different scripts. One called Rays (it checks what I'm clicking on and lowers its hp) and a script called colorChange (it changes the color of the object that I clicked on depending on its hp). I created the hp variable in colorChange and I need to check hp in Ray.
So the "colorChange" script depends on the "Rays" script, yes?
Then you can define the "colorChange" script to expect a "Rays" component on the same GameObject by using the [RequireComponent] tag, which is described
here: https://docs.unity3d.com/ScriptReference/RequireComponent.html
Then in the "Awake" function of "colorChange" you retrieve a reference to "Rays". If the "hp" variable in "Rays" has public get access then in "colorChange" you can use the acquired reference to the "Rays" script to check its current value.
Example for script "Rays":
using UnityEngine;
public class Rays : MonoBehaviour {
private int hp = 0;
public int Hitpoints {
get { return hp; }
}
// ... other methods ...
}
Example for script "colorChange":
using UnityEngine;
[RequireComponent (typeof (Rays))]
public class colorChange : MonoBehaviour {
private Rays raysReference = null;
protected void Awake() {
raysReference = GetComponent<Rays>();
}
protected int getRaysHitpoints() {
return raysReference.Hitpoints;
}
// ... other methods that may use getRaysHitpoints ...
}
I made 2 scripts and assigned it to 2 cubes: "cube" and "cube 1".
Normally if you click on cube it sets a value so that when you click cube 1 it disappears.
If you click cube 1 first it's not gonna work.
So that's what I tried to make but it does not work and I don't understand why.
here are my scripts
cube:
using UnityEngine;
using System.Collections;
public class script : MonoBehaviour
{
public int test = 0; // make the variable for the value
public void OnMouseDown() // when the user click
{
test = 1; //make the value of test 1
}
}
cube 1:
using UnityEngine;
using System.Collections;
public class NewBehaviourScript1 : MonoBehaviour
{
public GameObject a; //make a gameobject
public script script; //make a variable where we put in the script
void OnMouseDown() // when the user click
{
script = a.GetComponent<script>(); // get script
if ( script.test == 1) //test or the variable test in the other script is 1
{
Destroy(gameObject); // destroy the object
}
}
}
Can someone please help me?
Change the name of the script class to be capitalised.
public class Script : MonoBehaviour
Then in the NewBehaviourScript1 change everything inside it to:
public class NewBehaviourScript1 : MonoBehaviour
{
public Script script; //Drag the other cube onto this in the inspector.
void OnMouseDown()
{
if ( script.test == 1)
{
Destroy(gameObject);
}
}
}
You should use more descriptive names for both your classes and their instances.
Note: For this to work you will have to have drag the other cube onto the script variable in the inspector and it will have to have a Script attached to it.
Try using a.GetComponent<script>();. You need to pass a Type to GetComponent in order for it to work. I'm not sure that your code even compiles, its very hard to read it because you did not format it properly.