Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 Peterwerd · May 15, 2015 at 06:42 PM · uiinstantiatevariablefunction

Use Instantiated clone in the next function in same class

Hi, my question is probably really stupid but I can't seem to find a general rule for it or better, because sometimes it seem to work and sometimes not. Maybe someone can bring some enlightment to me :)

Here I add my variables in the beginning

     public GameObject attack;
     public GameObject defenseButton;
     GameObject attackClone;
     GameObject defenseButtonClone;

In the inspector I have dragged the prefabs for attack and defenseButton onto the slots in the script.

In the update function I instantiate the attack GameObjekt as affackClone (inside an if statement)

             attackClone = Instantiate(attack);
             attackClone.transform.SetParent(thisIsTheCanvas.transform, false);
             attackClone.tag = "AttackButton";

In the same script a little further down I have a function called AttackButtonClicked which get's called if the AttackButton gets clicked (On Click () of UI Button). Inside this script I want to destroy the attackClone. But in order to do that I have to define the variable attackClone again using FindwithTag.

     public void AttackButtonClicked () {
 
         attackClone = GameObject.FindWithTag ("AttackButton");
         Destroy(attackClone);
         ShowDefenseButton ();
         Debug.Log ("Button Destoryed" + attackClone);
     }

I just don't know why I have to assign the variable again? Shouldn't it work all over this script? If not why? Has it something to do with ActionButtonClicked being called by a UI Button? Maybe someone can explain this to me?

EDIT Here's teh fullcode after changing it from the suggestion from the first answer

 using UnityEngine;
 using System.Collections;
 using UnityEngine.UI;
 
 public class SelectCountry : MonoBehaviour {
 
     public bool attackFromCountry = false;
     public bool attackThisCountry = false;
     public bool buttonIsThere = false;
 
     //GameObject attackingCountry;
     int unitsInAttackingCountry;
 
     //Canvas and Buttons
     GameObject thisIsTheCanvas;
     public Button attack;
     public GameObject defenseButton;
     public Button attackClone;
     GameObject defenseButtonClone;
 
     //Selected Countries to reset
     GameObject firstSelectedCountry;
     GameObject secondSelectedCountry;
     
     void Start (){
     
         thisIsTheCanvas = GameObject.Find("Canvas");
 
     }
 
     void Update() {
         if (Input.GetMouseButtonDown(0)){
             Debug.Log ("LeftClick");
             RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
         if (hit.collider != null) {
                 // Select Country to attack from
                 if (attackFromCountry == false && hit.collider.tag == "Untagged"){
 
                     //attackingCountry = hit.collider.GetComponent<CountryBaseClass>();
                     Debug.Log ("wossers");
                     unitsInAttackingCountry = hit.collider.GetComponent<CountryBaseClass>().unitsCountry;
                     if (unitsInAttackingCountry >= 2){
 
                     hit.collider.tag = "isActiveAttacker";
                     attackFromCountry = true;
                     Debug.Log ("wow");
                     }
                 }
 
                 // Select Country you want to attack and make it possible to deselect country
                 else {
 
                     if (attackThisCountry == false && hit.collider.tag == "Untagged" && attackFromCountry == true){
                         hit.collider.tag = "isActiveDefender";
                         attackThisCountry = true;
                         Debug.Log ("super");
                     }
                     else {
                         if (attackFromCountry == true && hit.collider.tag == "isActiveAttacker" && attackThisCountry == false){
                             hit.collider.tag = "Untagged";
                             attackFromCountry = false;
                         }
                         if (attackThisCountry == true && hit.collider.tag == "isActiveDefender"){
                             hit.collider.tag = "Untagged";
                             attackThisCountry = false;    
                         }
                     }
 
                 }
 
         }
         }
 
 
         // Show Attack Button if a two countrys are selected
         if (attackFromCountry == true && attackThisCountry == true && buttonIsThere == false) {
             attackClone = Instantiate(attack);
             attackClone.transform.SetParent(thisIsTheCanvas.transform, false);
             attackClone.tag = "AttackButton";
             buttonIsThere = true;
              
         }
         // Destroy attack Button if country is deselected
         if (buttonIsThere == true && attackThisCountry == false) {
         
             Destroy(attackClone);
             Debug.Log ("Button Destoryed" + attackClone);
             buttonIsThere = false;
            }
     }
 
 
     // Check if attacked button was klicked and then disable it and show defend button
     public void AttackButtonClicked () {
 
         //attackClone = GameObject.FindWithTag ("AttackButton");
         //Destroy(attackClone);
         attackClone.enabled = false;
         ShowDefenseButton ();
         Debug.Log ("Button Destoryed" + attackClone);
     }
     
     public void ShowDefenseButton () {
 
         defenseButtonClone = Instantiate(defenseButton);
         defenseButtonClone.transform.SetParent(thisIsTheCanvas.transform, false);
         Debug.Log ("Show Defense");
 
     }
 
     public void DefenseButtonClicked () {
     
         defenseButtonClone = GameObject.FindWithTag ("DefenseButton");
         Destroy(defenseButtonClone);
         //reset
         firstSelectedCountry = GameObject.FindWithTag ("isActiveAttacker");
         firstSelectedCountry.tag = "Untagged";
         secondSelectedCountry = GameObject.FindWithTag ("isActiveDefender");
         secondSelectedCountry.tag = "Untagged";
 
     }
 }
 

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 Bonfire-Boy · May 15, 2015 at 06:53 PM 0
Share

$$anonymous$$ore info please!

It's not clear why you think you do have to assign it again. What happens if you don't?

And do you know for sure that the object has been instantiated when the ActionButtonClicked gets called?

avatar image Peterwerd · May 15, 2015 at 07:32 PM 0
Share

If I don't assign it again, meaning "attackClone = GameObject.FindWithTag ("AttackButton");", then the Destroy(attackClone) doesn't work and the attackClone wont get destroyed. This is the output in the console: Button Destoryednull UnityEngine.Debug:Log(Object)

The object it self gets instantiated in the update function and yes it get's instantiated. I can see the clone in the hierarchy.

I thought that the variable attackClone should work in the whole script and not only in the update function.

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by InsertFunnyUsernameHere · May 15, 2015 at 07:44 PM

1

Are you sure you want to destroy that button? Maybe you just want to disable it? I can hardly think of a situation where destroying a GUI button would be helpful... In this case attackClone.enabled=false should do the job and later on you can enable it again without the need to instantiate another button.

2

make attackClone public and check in the inspector if it's initialized (not null). If it is indeed initialized then you shouldn't need to call the FindWithTag function

Comment
Add comment · Show 5 · 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 Peterwerd · May 15, 2015 at 08:37 PM 0
Share

hey thanks for your answer. I made attackClone public and before it is instantiated the field for it in the inspector is empty as soon as it instantiated it appears in the field in the inspector as it should. If i comment this: attackClone = GameObject.FindWithTag ("AttackButton"); out in the AttackButtonClicked function it still says: Button Destoryednull UnityEngine.Debug:Log(Object)

So making it public isn't the solution.

Disabling sounds like a good idea. I changed the GameObject to Button. The instantiation still works fine but now I get: NullReferenceException: Object reference not set to an instance of an object SelectCountry.AttackButtonClicked () (at Assets/Scripts/SelectCountry.cs:118)

I'll try to post the full code in the question

avatar image Peterwerd · May 15, 2015 at 08:39 PM 0
Share

I also want to say that everything works fine if I use the attackClone = GameObject.FindWithTag ("AttackButton");. I just think it is strange and unnecessary. Also if I want to disable the Button I don't know how to find it again, because findwithTag, etc doesn't work on the Type Button :(

avatar image InsertFunnyUsernameHere · May 15, 2015 at 09:58 PM 0
Share

Okay so, I could explain you all the problems your code has but the question is, if trying to repair them is worth your time. Your code is very messy and I don't think you will get much further than this without getting tons of issues. In the end it might prove better to just start from scratch and rewrite everything.

If you are going to start again then here are some quick tips 1) $$anonymous$$eep you current scripts. Save them somewhere so after you're done you can compare your new scripts with the old ones 2) Split your code into smaller parts. $$anonymous$$ake one script handle one task and one method handle one basic action, don't just put everything into the update function. 3) Using "Find" functions should be your last resort. Try to learn different ways of accesing your GameObjects (such as storing them in an array or a List) 4) If you seriously want to develop games then you have to learn inheritance, polymorphism and OOP(search on the web). This is going to save you a lot of work. 5) Before even starting try to draw all your classes, systems and relations on a sheet of paper. If you can't do that that means you probably shouldn't start yet and learn more. 6) Sometimes it might hurt, don't give up.

avatar image Peterwerd · May 16, 2015 at 07:27 AM 0
Share

Thanks for your constructive critisism. I am aware that my code probably sucks :) Since I am a hobbyiest game developer I learned all my coding from webtutorial and using try and error. So sadly nobody taught me how to do stuff right. So I will try to do better and folllow your advice.

But still I would like to get an answer to my question...

avatar image InsertFunnyUsernameHere · May 16, 2015 at 02:45 PM 0
Share

Alright, I also learned everything by myself so I know the pain.

As to the errors in your code...

1

You put Destroy(attackClone) before Debug.Log("Button Destroyed" + attackClone). Doing so will always result in printing "Button Destroyednull" to the console because by the time you call Debug.Log the attackClone is already destroyed (so it returns null). You should put Debug.Log before the Destroy function call.

2

You can find the exact line in your code which causes the NullReferenceException by simply double clicking the message in the console or by using the $$anonymous$$onoDevelop's debugger. This exception is usually caused by requesting a variable or calling a method from a class which has no instance. $$anonymous$$ake sure it is initialized and the problem should be solved.

Hope this helps

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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

How to prevent object (bullet) from instantiating twice ? (It instantiates once for tapping the screen, and once more when beginning to hold touch on screen) ? 1 Answer

Calling a variable 2 Answers

Pressing space calls the wrong function 1 Answer

Setting the variable on a GameObject to be instantiated (not yet existent) cs and js 2 Answers

IEnumerator problem 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