Unity can't acess another class 's instance c# - c#

The first class
public class ArmyManMovement : MonoBehaviour {
public Animator anim;
TextInput check;
// Use this for initialization
void Start () {
anim = GetComponent<Animator> ();
}
The second class
public class TextInput : MonoBehaviour
{
ArmyManMovement check;
void Awake()
{
check = GetComponent<ArmyManMovement> ();
//check.anim.SetBool ("Right", false);
}
//public IEnumerable<string> RemoveWhitespace(string input)
//{
//return new string(input.ToCharArray().Where(c => !Char.IsWhiteSpace(c)).ToArray());
//}
void AcceptStringInput(string userInput)
{
userInput = userInput.ToLower ();
if (userInput == "Open door") {
check.anim.SetBool("Right",true);
}
}
I don't know what 's wrong.I attached the Armyman 's script to the same inspector where textinput is.I don't know what 's wrong,but the value doesn't change and i can't access the animator in armyman 's script.It keeps priniting in the console that the error is (Object refrence not set to instance of object)

If the ArmyManMovement is attached to the-same GameObject the TextInput script is attached to, it should never be null when you perform GetComponent<ArmyManMovement> (); from the TextInput script.
There are really two possible problems here:
1.The TextInput script is also attached to another GameObject. Look in your scene and make sure that it is not. If it is mistakenly attached to another GameObject that that does not have the ArmyManMovement attached to it too, GetComponent<ArmyManMovement> (); will return null which mean that the check variable will be null. See this for how to find this out and fix it.
2.The anim variable is not assigned from the Editor.
First test: Debug.Log(check);.
If it is not null then test: Debug.Log(check.anim);.
If that is null then drag your animator to the anim slot in the ArmyManMovement script.
Note that if Debug.Log(check); is null, you need to go back to #1 and fix that first. Hopefully, you now know how to fix your future Unity null problems.

Related

Assign gameObject of a script via another script?

How do I assign a gameObject of one script through another script's gameObject? For example;
Script_1
public class Script_1 : MonoBehaviour
{
public OVRScript OVR;
}
Script_2
public class Script_2 : MonoBehaviour
{
private Script_1 src_1;
public GameObject Front;
void Start()
{
src_1 = (Script_1) GameObject.FindObjectOfType(typeof(Script_1));
src_1.GetComponent<OVRScript >().OVR = Front //I am facing problem here
}
}
Both GameObjects "OVR" and "Front" contain the OVRScript
src_1.GetComponent<OVRScript>().OVR = Front.GetComponent<OVRScript>().OVR;
I don't know or see the OVRScript class but isn't OVR rather a member of Script_1?
And then you would want to use GetComponent on the Front in order to get a component attached to it.
// If possible rather drag your Script_1 in here directly via the Inspector
[SeializeField] private Script_1 src_1;
void Start()
{
// Now I would use find only as fallback
if(!scr_1) src_1 = GameObject.FindObjectOfType<Script_1>();
// then you want to assign the OVR field of the 'src_1' of type 'Script_1'
// and not use 'src_1.GetComponent<OVRScript>()' which would return
// the reference of an 'OVRScript' component attached to the same GameObject as the Script_1
//
// And you want to fill it with the reference of an 'OVRScript' attached to 'Front'
src_1.OVR = Front.GetComponent<OVRScript>();
}
(see [SerializeField])
It would be even better if you directly define
public OVRScript Front;
now if you drag in a GameObject it a) is checked if this GameObject actually has a OVRScript attached, otherwise you can't drop it and b) instead of the GameObject reference already the OVRScript reference is serialized and stored so there is no need for GetComponent anymore:
[SeializeField] private Script_1 src_1;
public OVRScript Front;
void Start()
{
// Now I would use find only as fallback
if(!scr_1) src_1 = GameObject.FindObjectOfType<Script_1>();
src_1.OVR = Front;
}

How to call a public static variable from another class, change its value and then check that its changed from its original class [duplicate]

So im trying to change a variable in another script by touching a cube.
Current setup
1x Player
1x Enemy
Each with their own script Enemy_Stats & Character_Stats
As you can see in this little snippet it's quite a workaround to access the variable from another script.
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Enemy")
{
collision.gameObject.GetComponent<Enemy_Stats>().Health =
collision.gameObject.GetComponent<Enemy_Stats>().Health
- gameObject.GetComponent<Character_Stats>().AttackDamage;
if (collision.gameObject.GetComponent<Enemy_Stats>().Health <= 0)
{
Destroy(collision.gameObject);
}
}
}
Iam new to Unity, but isn't there a way to just refer it with something like:
collision.Health?
How to access variables/functions from another Class. The variable or function you want to access or called must be public not private.
public class ScriptA : MonoBehaviour{
public int playerScore = 0;
void Start()
{
}
public void doSomething()
{
}
}
Access variable playerScore in ScriptA from ScriptB. First, find the GameObject that the script or component is attached to with the GameObject.Find function then use the GetComponent function to retrieve that script or component that is attached to it.
public class ScriptB : MonoBehaviour{
ScriptA scriptInstance = null;
void Start()
{
GameObject tempObj = GameObject.Find("NameOfGameObjectScriptAIsAttachedTo");
scriptInstance = tempObj.GetComponent<ScriptA>();
//Access playerScore variable from ScriptA
scriptInstance.playerScore = 5;
//Call doSomething() function from ScriptA
scriptInstance.doSomething();
}
}
No since Health is not part of the collision object, but Enemy_Stats. You can cache a Component (that's what Enemy_Stats is) if you use it multiple times to save you some typing (and some performance, but that is rather marginal for this example). Also you can cache "known" components like in this case Player_Stats. You can do this e.g. in Start or with a public variable and the inspector.
What you should probably do though is to make the enemy be responsible for his life and not the player, so move the Destroy-part to Enemy_Stats (into the Health property to be exact).
The first thing to make this shorter (and eventually faster) would be to store this: gameObject.GetComponent<Character_Stats>() on Start() in a private variable (you should avoid calling GetComponent on a frequent basis if you can avoid it).
For the Health variable, a way of avoiding GetComponent calls could be caching: you create a Dictionary<GameObject, Enemy_Stats> and read from that as soon as this gameobject collided once
At the very beginning i mean in Awake() method you can find a game-object with tag
and get it's Heath after that in Collision() method you should just decrease the health but, here the condition is there is only one enemy and only one player.

Enable/disable a GameObject component from a script [Unity3D]

I need to take the value of a boolean (put in a variable called "bouclier") set in one script to enable or disable a GameObject.
The variable is in game object Player (bottom right here):
And I need to enable of disable this game object ("Bouclier01"):
To do this, I attached a script to game object "Bouclier01". Here it is:
using UnityEngine;
using System.Collections;
public class ShowBouclier : MonoBehaviour {
public GameObject Bouclier01;
public bool bouclier;
// Use this for initialization
void Start () {
Bouclier01 = Bouclier01.GetComponent<GameObject>();
}
// Update is called once per frame
void Update () {
Bouclier01.enabled = false;
if (bouclier == true) {
Bouclier01.enabled = true;
}
}
}
I must be missing something, because this comes up with this error message:
Any idea how to properly accomplish this?
You can use GameObject.SetActive() function to activate or deactivate a GameObject (I think GameObject.enabled was in the old API):
Bouclier.SetActive(false);
By the way, if you want to know the current activation state of a GameObject, use GameObject.activeSelf, which is a read only variable:
Debug.Log(Bouclier.activeSelf);
it will works
public GameObject otherobj;//your other object
public string scr;// your secound script name
void Start () {
(otherobj. GetComponent(scr) as MonoBehaviour).enabled = false;
}

Unity3D: Script variables inconsistences using OnTriggerEnter2D

I have the object that have the script component.
public class TeleportReference : MonoBehaviour {
private GameObject reference;
void Start () {
reference = null;
}
public void SetReference(GameObject other){
reference = other;
}
public GameObject GetReference(){
return reference;
}
Now if I search for an object and test the script variables
GameObject test = GameObject.FindGameObjectWithTag("Water");
print(test);
print(test.GetComponent<TeleportReference>());
print(test.GetComponent<TeleportReference>().GetReference());
it works just fine and GetReference() return the variable I stored.
But now if I use it whithin OnTriggerEnter2D
private void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Water")
{
print(other);
print(other.gameObject);
print(other.GetComponent<TeleportReference>());
print(other.GetComponent<TeleportReference>().GetReference());
}
}
GetReference() return null (or other variable that I used during Start() of TeleportReference class).
All other testing outputs remain the same.
Could anyone give a hint why this could happen? Does that mean that GetComponent created new instance of TeleportReference in second case?
GetComponent did not create a new instance of TeleportReference in second case. I have similar code in one of my projects and I haven't had any problems. So in this case I would look to see if the problem is somewhere else. Are you sure it's the same "Water" object? Do you have multiple objects with "Water" tag? Are you colliding before reference is assigned? There could be a myriad of things going on. Just test to narrow it down.
For example try performing an action on the other.gameObject object to verify it's the right object, like deactivating it. Also try using other.gameObject.GetComponent (not sure if this makes a difference).
Found the issue. It was in the order of assigning variables. That is - changes were made apperantly before Start() function was called. Thus at some point of the code the stored value was overritten back to null.
This works fine:
public class TeleportReference : MonoBehaviour {
private GameObject reference;
void Awake () {
reference = null;
}
public void SetReference(GameObject other){
reference = other;
}
public GameObject GetReference(){
return reference;
}
Thanks everyone for comments, that really helped me in debugging.

Why is transform.parent null in Awake() and Start()?

I'm trying to get a reference to the GameObject that the script is attached to. Per docs transform.parent.gameObject is used for this but transform.parent is null in both Awake() and Start(). What do I need to do to get this working? This is probably a total noob question but Google didn't come up with a working answer so far.
using UnityEngine;
using System.Collections;
public class Test : MonoBehaviour
{
private void Awake()
{
var obj = transform.parent;
Debug.Log(obj);
}
private void Start()
{
var obj = transform.parent;
Debug.Log(obj);
}
}
Nevermind! I'm an idiot! It shouldn't be parent but:
var obj = transform or var obj = transform.gameObject
since this script is part of the game object which it should refer to, not any parent. I had the strange assumption that a script is a child of a game object.
Transform.parent tells you what the parent of your current transform is. I.E. if GameObjectA is a child of GameObjectB, a script that accesses transform.gameObject in GameObjectB will return GameObjectA
What you're looking for, in fact, is just gameObject. This implicitly returns the gameObject your script is attached to.
Create two GameObjects in your scene.
Call one GameObjectA, and the other GameObjectB.
Attach this script to GameObjectB and then drag GameObjectB to be under GameObjectA in the hierarchy
public class ExampleBehaviour : MonoBehaviour {
void Awake () {
Debug.Log(gameObject.name); //Prints "GameObjectB" to the console
Debug.Log(transform.parent.name); //Prints "GameObjectA" to the console
}
}

Categories