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 NewbieJD · Nov 09, 2017 at 11:22 AM · gameobjectupdatecomponentdeactivate

Reactivating a GameObject that was deactivated from another script

Hi all, I am making a game which uses power ups. The game is based off the unity tutorial - survival shooter. I've added in a power up which changes the appearance, damage, lighting of the gun bullets by deactivating the regular bullet component 'GunBarrelEnd' and activating 'SuperGunBarrelEnd'. This works perfectly when the powerup object (a cube with a script attached to it) is activated. The script attached to the cube tells unity to disable the 'SuperGunBarrelEnd' unless the player collides with the cube. It then deactivates the regular barrel end and activates the super one for a set period of time. However, when the cube object with the script attached is not active in the game, the gun shoots both types of bullets at once (as there is nothing to deactivate 'SuperGunBarrelEnd'. I am trying to tell unity to deactivate the super bullets unless the cube with the script attached is active in the game. I've done this by attaching the following code to void Update in another script that is always active in the game:

 SuperGun = GameObject.FindWithTag ("SuperGun");            
             
         void Update ()
         {    
 if (GameObject.FindGameObjectWithTag ("PickupGun") == null) {
                 SuperGun.SetActive (false);
             } 
             else 
             {
                 SuperGun.SetActive(true);
             }

This successfully deactivates the super bullets when the cube 'PickupGun' isn't present in the game but when it is activated, the original script is no longer able to activate the 'SuperGunBarrelEnd' component. I've tried multiple ways of getting around this but can't find a solution to it. Am I perhaps using void Update wrong? The code that manages the powerup (attached to the cube) is also below incase this gives any clue as to what is going on. Any help would be really appreciated, thanks!

 public class BulletPickup : MonoBehaviour {
 
         private Renderer rend; 
         private BoxCollider coll;
         private Light light;
         private GameObject StandardGun;
         private GameObject SuperGun;
         private GameObject player;
 
         void Start()
         {
             rend = GetComponent<Renderer> ();                                                    
             coll = GetComponent<BoxCollider> ();
             light = GetComponent<Light> ();
             StandardGun = GameObject.FindWithTag("StandardGun");
             SuperGun = GameObject.FindWithTag("SuperGun");                                    
             SuperGun.SetActive(false);
         }
 
         void OnTriggerEnter(Collider other)
         {
             if (other.gameObject.CompareTag("Player"))                                            
             {
                 AudioSource audio = GetComponent<AudioSource>();                                
                 audio.Play();                                                                    
                 rend.enabled = false;                                                            
                 coll.enabled = false;                                                            
                 light.enabled = false;
                 StandardGun.SetActive(false);
                 SuperGun.SetActive(true);
                 StartCoroutine (DeactivateSuper ());
 
             }
         }
 
         IEnumerator DeactivateSuper()
         {
             yield return new WaitForSeconds (10);
             StandardGun.SetActive (true);
             SuperGun.SetActive (false);
         }
     }
Comment
Add comment
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

2 Replies

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

Answer by Daemonhahn · Nov 09, 2017 at 11:52 AM

Why not have one gun start as disabled and the other start as active (the one they are meant to start with).

When you enable one, disable the other, and vice versa. As long as for the two guns one of them starts disabled and one enabled, then it will always work.

You could use a method like this:

 void EnableGuns(bool super)
 {
    if(super)
 {
      SuperGun.SetActive(true);
 StandardGun.SetActive(false);
 }
 else
 {
 SuperGun.SetActive(false);
 StandardGun.SetActive(true);
 }
 }

also don't use a co-routine.

Instead use a timer, something like this:

 float timer = 0f;
 public float timerInterval; // set this to whatever you want in the inspector
 
 void Update()
 {
    if(timer > 0f)
 {
 if(!SuperGun.isActiveInHeirarchy) EnableGuns(true);
 timer += Time.deltaTime;
 if(timer <= 0)
 {
    // disable gun here as powerup has run out
 EnableGuns(false);
 }
 }
 
 }

Then when you want the powerup, just set the timer to a number such as 5. It will then count down and the power will last for 5 seconds. you can use the public timerInterval variable as this value if you want.

This is a cleaner better way to do this. P.S my code was done off by heart, I haven't checked it in an editor so there will be errors so do not copy and paste

' EDIT: Example usage, if you wanted to start the powerup:

 void StartPowerup(float secondsActive)
 {
    timer = secondsActive;
 }


Comment
Add comment · Show 18 · 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 NewbieJD · Nov 09, 2017 at 11:59 AM 0
Share

Thanks for the response! That did occur to me but I've actually got two versions of the super gun (so three bullet types), I don't think a boolean would work? (I didn't mention the third gun barrel end originally to simplify things!). The third gun barrel end works exactly the same besides different effects. As for the float timer over the co-routine, what's the advantage of this? Is it less resource intensive?

avatar image Daemonhahn NewbieJD · Nov 09, 2017 at 12:03 PM 0
Share

Co-routines do not necessarily stop or start when you expect them to, and they can interact with each other in weird ways or even stall / not finish.

They are simply not dependable, we have a major client project that we have mainly used co-routines in for over a year and we are having to change the entire project to take them out due to unforeseen errors linked to them.

As for the Boolean, that's fine just make an enum:

 public enum GunType
 {
    standard,
 super1,
 super2
 }
 
 
 public GunType type;


then set the type to whatever you want at start, and pass that into the change gun method ins$$anonymous$$d:

 void EnableGuns(GunType type)
  {
     if(type == GunType.standard)
  {
       SuperGun.SetActive(false);
  StandardGun.SetActive(true);
 SuperGun2.SetActive(false);
  }
  else if(type == GunType.super1)
 {
  SuperGun.SetActive(false);
  StandardGun.SetActive(true);
  SuperGun2.SetActive(false);
  }
  else if(type == GunType.super2)
 {
  SuperGun.SetActive(false);
  SuperGun2.SetActive(true);
  StandardGun.SetActive(false);
  }
  }

etc etc

avatar image Daemonhahn Daemonhahn · Nov 09, 2017 at 12:04 PM 0
Share

Please select my answer as the correct one if I have been helpful! :)

Show more comments
Show more comments
avatar image
0

Answer by Harinezumi · Nov 09, 2017 at 12:33 PM

I think you have an organization problem (instead of a programming problem).

First off, please don't use GameObject.FindGameObjectWithTag() in Update(), it is a relatively slow operation and calling it on every frame within Update() is not recommended. Instead you could put a script on the PickUpGun object that deactivates all SuperGuns when it gets created.

What I would do is that the player would have the StandardGun and the SuperGun already attached, and let the script on the player control what is active. For example, BulletPickup.OnCollisionEnter() could look for a Player component, and tell it to Player.ActivateSuperGun(). This would do the switch and start a timer in Player (btw, in my opinion using coroutines for this is fine), and at the end it would switch back.

Maybe I didn't catch all the details of the issue, but I think this would work.

Comment
Add comment · Show 10 · 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 NewbieJD · Nov 09, 2017 at 01:34 PM 0
Share

Thanks for the response. I think I'm nearly there using Daemonhahn's method but I do appreciate the help! Incidentally, I was having a problem with spawning enemies in another script. I had three GameObject.FindGameObjectWithTag() operations running in my Update function that is designed to check if there are any active enemies in the level (it stops spawning when it finds an enemy present. This lead to a huge number of enemies being spawned. Reading what you've said suggests to me that the find with tag is slowing down the update function meaning that a large number of enemies are spawned before update has had chance to stop them. Does that make sense? Can you suggest there a more efficient means of finding the enemy game objects?

avatar image Bonfire-Boy NewbieJD · Nov 09, 2017 at 03:56 PM 1
Share

Not sure that that does make sense, no. Your Update function will be running on the same thread as the spawning code, so the former being slow wouldn't normally mean there's more time for the latter.

I'd recommend getting rid of the Find calls entirely. Your collection of enemies should only change when they're created or destroyed (or maybe when they change state in some other way), right? So maintain a list yourself and change it as required. $$anonymous$$ost people would probably put this into some kind of enemymanager class that handles the spawning/destroying as well as maintaining the collection.

avatar image NewbieJD Bonfire-Boy · Nov 09, 2017 at 04:00 PM 0
Share

Apologies, it's been a long day haha! I've changed my code to get rid of the find with tags but am still getting an endless stream of enemies spawning. I'm sure there's something simple that's causing it but I'm struggling to see it! alt text

screen-shot-2017-11-09-at-160128.png (214.8 kB)
Show more comments

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

105 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 avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Deactivate an object - and all scripts in that object deactivated? 1 Answer

Vehicle Enter Script Errors HELP! 0 Answers

How to activate/deactivate a component(Animator) when a specific game object was activated 0 Answers

Sharing components amongst different gameobjects 1 Answer

How to trigger udpate in editor mode only when I modify component parameters 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