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
1
Question by omarXgame · Nov 29, 2020 at 11:45 AM · raycastaienemyienumeratorvar

[SOLVED] using var from another method?

i'm making a small top down open world zombie game and testing out if a player is in range of the zombie and if true then the zombie can attack the player.

|

i need the script to not be taxing as much as possible because worst case scenario the server has to render 460 zombies.

|

as far as i understand it (which is not much), raycast is taxing so i started testing other methods, this is the code i'm trying to test, i haven't tested the rest so it won't work as it is but wanted to include it to give an idea of what i'm trying to do

 using UnityEngine;
 using System.Collections;
 
 public class ZombieAttack : MonoBehaviour
 {
     public Transform zombieTransform;
     public int damage = 1;
     public float attackRange = 0.7f;
     public GameObject hitEffect;
     public LayerMask player;
 
 
 
     void Start()
     {
         StartCoroutine(attack());
     }
 
 
     public void Update()
     {
         //want the var in update to check constantly if the player is in range or not
         var attackingZone = Physics2D.OverlapCircle(zombieTransform.position, attackRange, player);
     }
 
     IEnumerator attack()
     {
         while (attackingZone)
         {
             //Calling "Health" class on the player
             Health playerHealth = attackingZone.transform.GetComponent<Health>();
             if (playerHealth = null)
             {
                 yield break;
             }
             else
             {
                 //play animation here
                 //wait 0.2 seconds
                 playerHealth.TakeDamage(damage);
             }
             //this is just a place holder piece of code for now
             Instantiate(hitEffect, Vector2.zero, Quaternion.identity);
             //2 seconds till the zombie can attack again
             yield return new WaitForSeconds(2f);
         }
     }
 }



|

so now my question is "what is the least taxing way/code i can do this with? and if this code is good then how do i make it work?"

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
1
Best Answer

Answer by Bunny83 · Nov 29, 2020 at 02:03 PM

what is the least taxing way/code i can do this with?

Uhm if you don't need the "attackingZone" information anywhere else than inside your attack coroutine, why don't you put that line inside your coroutine? Of course if you want to use it for some other thing inside Update, Envans solution would work fine.

Note that your current code would not work at all because you start the coroutine in Start which runs before Update. So when the coroutine is started you certainly don't have any information yel. Since your while loop terminates when you have no overlap, the coroutine would terminate immediately.

If this behaviour should control the zombie attack behaviour, you should use something like this without any Update method:

 IEnumerator attack()
 {
     var waitForNextScan = new WaitForSeconds(0.1f);
     var attackCooldown = new WaitForSeconds(2f);
     while (true)
     {
         yield return waitForNextScan;
         var target = Physics2D.OverlapCircle(zombieTransform.position, attackRange, player);
         if (target == null)
             continue;
         Health playerHealth = target.GetComponent<Health>();
         if (playerHealth == null)
             continue;
         playerHealth.TakeDamage(damage);
         Instantiate(hitEffect, Vector2.zero, Quaternion.identity);
         yield return attackCooldown;
     }
 }

This will check every 0.1 seconds if the zombie has anything in range. If not, we wait for 0.1 seconds. If something is in range then we check if the "thing" in range has a Health script on it. If not we just jump back up and wait another 0.1 seconds. However if we made it through so we do have a Health script on the target, we apply the attack and wait for the specified cool down time before we try attacking again.


Note that if you want a faster reaction time of the zombie, you may lower the "waitForNextScan" time or replace it with "null" if you want it scan for the player every frame. However as you asked for the least taxing way, doing roughly 10 checks per second should be enough.


Don't forget to remove the Update method completely. Even an empty Update method requires CPU time.


Finally I would recommend you refactor your "attack" method and name it "Attack" to use default convention and be consistent.

Comment
Add comment · Show 3 · 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 Bunny83 · Nov 29, 2020 at 02:21 PM 1
Share

ps: Please do not call "a method" "a void". You wouldn't call "a cat" "a small" just because it's a small cat because no one would know what you're talking about while the usage of the void type is kinda restricted most people probably can infer that you talk about a method, but there are also void pointers (which are rarely used in C# but still exist). The "void" in front of the method declaration just specifies that this method does not have a return type (void / invalid).

So this:

 int Some$$anonymous$$ethod()
 {
     return 0;
 }

is a method returning an int, while this:

 void SomeOther$$anonymous$$ethod()
 {
 }

is a method that doesn't return anything. I know I'm fighting against windmills as in the recent years I've come across countless of example of this misleading usage, even in some "tutorial" videos. Though I thought I should bring it up from time to time -.- (hope dies last)

avatar image Glurth Bunny83 · Nov 30, 2020 at 09:43 PM 0
Share

Battle-on Don Q-Bunny, your cause is honorable!

avatar image omarXgame · Nov 29, 2020 at 02:35 PM 0
Share

sorry for calling method a void, i corrected it in the title

also thanks! your solution worked flawlessly, i've been on this for 2 days, i can't thank you enough.

avatar image
1

Answer by Envans · Nov 29, 2020 at 12:36 PM

Make the attackingZone a global variable like this

 using UnityEngine;
 using System.Collections;
  
 public class ZombieAttack : MonoBehaviour
  {
      public Transform zombieTransform;
      public int damage = 1;
      public float attackRange = 0.7f;
      public GameObject hitEffect;
      public LayerMask player;
 
      private Collider2D attackingZone;
  
  
      void Start()
      {
          StartCoroutine(attack());
      }
  
  
      public void Update()
      {
          //want the var in update to check constantly if the player is in range or not
          attackingZone = Physics2D.OverlapCircle(zombieTransform.position, attackRange, player);
      }
  
      IEnumerator attack()
      {
          while (attackingZone)
          {
              //Calling "Health" class on the player
              Health playerHealth = attackingZone.transform.GetComponent<Health>();
              if (playerHealth = null)
              {
                  yield break;
              }
              else
              {
                  //play animation here
                  //wait 0.2 seconds
                  playerHealth.TakeDamage(damage);
              }
              //this is just a place holder piece of code for now
              Instantiate(hitEffect, Vector2.zero, Quaternion.identity);
              //2 seconds till the zombie can attack again
              yield return new WaitForSeconds(2f);
          }
      }
  }


Comment
Add comment · Show 2 · 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 sacredgeometry · Nov 29, 2020 at 04:00 PM 0
Share

Just an aside. That isn't a global variable It's a member of the ZombieAttack class.

avatar image Envans sacredgeometry · Nov 29, 2020 at 04:47 PM 0
Share

You are right!, but what I meant was global variable in the ZombieAttack class such that it can be used in any function of the class or anywhere in the class, if you define the variable in a function that variable is local and cant be used anywhere else except that function, so in that sense it is a "global" variable. I think the OP being new in game developing would better understand the term "global" variable rather than using confusing definitions.

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

279 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 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 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

Enemy raycast detection 0 Answers

Programming an enemy to shoot upwards 1 Answer

Enemy AI Script Acting Abnormal 0 Answers

AI script works, when we add a blocked function it stops working HELP 0 Answers

Enemy AI Running Through Wall With Raycast 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