Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Ljrnet · Apr 20, 2017 at 06:54 PM · c#scripting problemaccessing scripts

Troubles with accessing other variables in other scripts on other Gameobjects

Hi, as the title suggests I am having troubles with accessing other variables in other scripts on other GameObjects. I have a player script for the health of my player(playerShield) and another script for enemy damage(EnemyScript). What I would like to happen is when the player hits the enemy collider the player takes damage. But the reverse happens, the player doesn't take any damage and it comes up with this error: NullReferenceException: Object reference not set to an instance of an object EnemyScript.Damage () (at Assets/Scripts/AI/EnemyScript.cs:73).

When I click on the error it directs me to line 73 on the EnemyScript.

Here is my EnemyScript:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.UI;
 
 public class EnemyScript : MonoBehaviour 
 {
     public float enemyShield;
     public DestroyRange destroyRadius;
     public PlayerShield shieldValue;
     public GameObject player;
     public Text EnemyHealth;
     public GameObject enemy;
     public bool random = true;
     public bool damage = false;
     public bool textTrigger = true;
     public float damageAmount;
 
     void Awake () 
     {
         if(random == true)
         {
             enemyShield = Random.Range( 0.1f, 6.0f );
         }
         shieldValue = GetComponent<PlayerShield>();
         destroyRadius = GetComponent<DestroyRange>();
         Debug.Log("Enemy Spawned!!!");
         
     }
     
     // Update is called once per frame
     void Update ()
     {
         if(textTrigger == true)
         {
             EnemyHealth.text = enemyShield.ToString();
         }
 
         enemyShield = Mathf.Round(enemyShield * 10f) / 10f;
     }
 
     private GameObject GetGameObject()
     {
         return gameObject;
     }
 
     void OnTriggerEnter2D(Collider2D other)
     {
         Debug.Log("Enemy Hit!!!");
 
         if(other.CompareTag("Player"))
         {
             Debug.Log("Enemy Hit Player!!!");
 
             if(damage == true)
             {
                 Debug.Log("Damage =  true");
                 Invoke("Damage", 0.1f);
             }
 
             if(other.gameObject.GetComponent<PlayerShield>().shieldValue > enemyShield)
             {
                 Destroy(enemy);
 
                 Debug.Log("Enemy Destroyed!!!");
             }
         }
     }
     void Damage()
     {
         Debug.Log("Damage invoked!!");
 
         transform.Find("Player").GetComponent<PlayerShield>().shieldValue = transform.Find("Player").GetComponent<PlayerShield>().shieldValue - damageAmount;
 
         Invoke("DamageTrue", 3.0f);
         
         Debug.LogError("ERROR: Damage Invoke didn't Cancel.");
     }
 
     void DamageTrue()
     {
         damage = false;
         CancelInvoke("Damage");
         CancelInvoke("DamageTrue");
     }
 }

And here is the PlayerShield script:

 using UnityEngine;
 using UnityEngine.UI;
 using System.Collections;
 using Image=UnityEngine.UI.Image;
  
 public class PlayerShield : MonoBehaviour
 {
     public float maxShields = 5.0f;
     public float shieldValue = 1.0f;
     public float powerUpValue = 0.1f;
     public float enemyPowerUpValue;
     public float pHealth;
     public bool objective;
     public Image Healthbar;
     public Text shieldNumber;
     public EnemyScript enemyShield;
     public EnemyScript damage;
 
     public void start()
     {
         objective = false;
 
         shieldValue = 1.0f;
 
         enemyShield = GetComponent<EnemyScript>();
 
         damage = GetComponent<EnemyScript>();
     }
 
     void Update()
     {
         if(shieldValue == 5.0f)
         {
             objective = true;
             Debug.Log("shieldValue = 5.0f");
         }
 
         pHealth = shieldValue / maxShields;
 
         Healthbar.fillAmount = pHealth;
 
         shieldNumber.text = shieldValue.ToString();
 
         if(shieldValue > maxShields)
         {
             shieldValue = maxShields;
         }
 
         if(shieldValue <= 0)
         {
             Invoke("Respawn", 0.1f);
         }
 
         shieldValue = Mathf.Round(shieldValue * 10f) / 10f;
     }
 
     void OnTriggerEnter2D(Collider2D other)
     {
         if(other.CompareTag("PowerUp"))
         {
             shieldValue =  shieldValue + powerUpValue;
             Debug.Log("you got a power UP!");
         }
 
         if(other.CompareTag("Enemy"))
         {
             if(other.gameObject.GetComponent<EnemyScript>().enemyShield > shieldValue)
             {
                 if(other.gameObject.GetComponent<EnemyScript>().damage == false)
                 {
                     Invoke("Respawn", 0.1f);
 
                     Debug.Log("Player Destroyed!!!");
                 }
 
             }
             if(other.gameObject.GetComponent<EnemyScript>().enemyShield < shieldValue)
             {
                 shieldValue = shieldValue + enemyPowerUpValue;
             }
         }
     }
      void Respawn()
      {
         Application.LoadLevel(Application.loadedLevel);
      }
 }


Any form of help is greatly appreciated and thankyou in advance.

Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image absconsus · Apr 24, 2017 at 12:03 AM 0
Share

FindObjectOfType<"nameofthescript">()."variables"

avatar image Ljrnet · Apr 24, 2017 at 01:48 AM 0
Share

In what context do I put that code in? I tried replacing this: void Damage() { Debug.Log("Damage invoked!!");

         transform.Find("Player").GetComponent<PlayerShield>().shieldValue = transform.Find("Player").GetComponent<PlayerShield>().shieldValue - damageAmount;
 
         Invoke("DamageTrue", 3.0f);
         
         Debug.LogError("ERROR: Damage Invoke didn't Cancel.");
     }

with this:

     void Damage()
     {
         Debug.Log("Damage invoked!!");
 
         FindObjectOfType<"PlayerShield">()."shieldValue" = FindObjectOfType<"playerShield">()."shieldValue" - damageAmount;
 
         Invoke("DamageTrue", 3.0f);
         
         Debug.LogError("ERROR: Damage Invoke didn't Cancel.");
     }

but it comes up with this error: Assets/Scripts/AI/EnemyScript.cs(77,35): error CS1525: Unexpected symbol `)'

4 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by bobisgod234 · Apr 24, 2017 at 02:31 AM

transform.find will only find objects that are a child of that transform, and I doubt that the player is a child of a component called "EnemyScript". Use GameObject.Find instead of transform.find

I would also suggest breaking up the problematic line to make it easier to debug.

 GameObject.Find("Player").GetComponent<PlayerShield>().shieldValue = GameObject.Find("Player").GetComponent<PlayerShield>().shieldValue - damageAmount;
 

Would become:

 GameObject player = GameObject.Find("Player");
 PlayerShield playerShield = player.GetComponent<PlayerShield>();
 playerShield.shieldValue -= damageAmmount;

However, Gameobject.find is very slow, and I would strongly suggest comming up with some other solution to getting player scripts e.g. by using the player's collider2d.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Ljrnet · Apr 24, 2017 at 03:25 AM 0
Share

Thank you so much it worked although with one side effect, the damage is doubled but I can work around that by halving the damage amount.

avatar image
0

Answer by LoneWolfSwat · Apr 25, 2017 at 02:37 PM

Your error is: The game can't find the player's script. You can fix this in your enemy script: Add a new float variable: "ShieldValue"

   //this must be updated every frame (So put it on Update function)
     ShieldValue = GameObject.FindObjectOfType<PlayerShield>().shieldValue;
     //this can't be updated every frame, so this must be on your OnTriggerEnter2D funtion.
         GameObject.FindObjectOfType<PlayerShield>().shieldValue = ShieldValue -= damageAmount;

Instead of what you've done:

 transform.Find("Player").GetComponent<PlayerShield>().shieldValue =transform.Find("Player").GetComponent<PlayerShield>().shieldValue - damageAmount;












Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by sdclark79 · Apr 24, 2017 at 07:52 AM

Your problem is the lower-case transform.Find you are using. First, lower-case transform refers to the transform of the current object (upper-case Transform would mean another object). You should be using GameObject.Find (not to be confused with gameObject, which again would refer to your current object). So line73 in your first script should be something like:

 GameObject.Find("Player").GetComponent<YourComponent>();

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Eno-Khaon · Apr 24, 2017 at 02:53 AM

You're likely seeing a problem with your use of "Transform.Find()" -- More specifically, the problem is that you're using it at all in this case. Transform.Find() is intended to search for children of your GameObject's Transform. Since you're looking for a different GameObject entirely, you would normally use something like "GameObject.Find()" or "GameObject.FindWithTag()" instead.

However, that's not actually a solution to the problem. That simply mitigates the symptoms.

The real problem comes from not making use of information you have available.

Let's use "OnTriggerEnter2D()" as an example. When it's called, it's passing through more information (Namely, Collider2D other). You check whether it's the player that you hit, then you attempt to damage the player... and throw out all the useful information you had in the process.

 void OnTriggerEnter2D(Collider2D other)
 {
     // ...
     
     if(other.CompareTag("Player"))
     {
     PlayerShield playerShield = other.GetComponent<PlayerShield>();
     
     // Just to be sure, verify that it exists
     if(playerShield != null)
         {
             DamagePlayer(player, damageAmount);
         }
         else
         {
             Debug.LogError("ERROR: Target with tag \"Player\" does not have PlayerShield attached to it.");
         }
     }

     // ...
 }


 public void DamagePlayer(PlayerShield player, float damageAmount)
 {
     player.shieldValue -= damageAmount;
 }

Additionally, the way your Awake() function is set up, your player and enemies have inner conflicts. They look to themselves in lines such as...

 enemyShield = GetComponent<EnemyScript>();

... rather than getting information about another GameObject. With everything arranged more cleanly, however, you won't need those at all, since you get up-to-date information from OnTriggerEnter2D().


Further notes: To improve the flow of damage being dealt, you might consider converting health/shield values into Properties. That way, you can check immediately upon dealing damage whether they're dead.

For example, in the PlayerShield script...

 private float _shieldValue = 1.0f;
 public float shieldValue
 {
     get
     {
         return _shieldValue;
     }
     set
     {
         _shieldValue = value;
         if(_shieldValue <= 0.0f)
         {
             // You are dead.
             Respawn();
         }
     }
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

11 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Change the alpha of a gameobject with multiple childs 1 Answer

HoloLens - Smooth Rotation doesn't work 0 Answers

Setting gameobject to null 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges