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 Voridian · Jul 22, 2014 at 09:52 AM · c#lagforeach

foreach code causes lag spike C#

sorry about making another question but everytime i fix somthing another thing breaks, in this script, foreach at line 40 is making a huge lag spike any ideas on a fix? btw im sorry about the messy code, i only started learning this less than a week ago by my self.

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 public class PistolRay : MonoBehaviour {
 
     bool canFire = true;
     public GameObject decal;
     public float clipAmmo = 8;
     public float storedAmmo = 80;
     float missingShots = 0;
     GameObject player;
     GameObject characterControler;
     bool reloading = false;
     private List<EnemyAi> enemies = new List<EnemyAi>();
 
     // Use this for initialization
     void Start () {
 
     }
     
     // Update is called once per frame
     void Update () {
         player = GameObject.Find("Player");
         CharacterControler characterControler = player.GetComponent<CharacterControler>();
         characterControler.ammoCount = clipAmmo;
         characterControler.totalAmmo = storedAmmo;
         var enemyObjects = GameObject.FindGameObjectsWithTag("Enemy");
         foreach(GameObject enemyObj in enemyObjects){
             EnemyAi enemyAi = enemyObj.GetComponent<EnemyAi>();
             if(enemyAi != null){
         enemies.Add(enemyAi);
         }
         }
         RaycastHit hit;
         Ray shooterRay = new Ray(transform.position, transform.forward);
 
         if(Input.GetButton("Fire1") && canFire && clipAmmo > 0){
             if(GameObject.Find ("EnemyAi") != null){
                 foreach(EnemyAi enemy in enemies){
             EnemyAi enemyAi = enemy.GetComponent<EnemyAi>();
             enemyAi.couldHearGun = true;
             StartCoroutine (SoundCooldown(1));
             }
         }
         }
         if(Input.GetButton("Fire1") && canFire && clipAmmo > 0){
             Debug.DrawRay (transform.position, transform.forward, Color.green);
                 if(Physics.Raycast(shooterRay, out hit, Mathf.Infinity)){
                 if(hit.collider.tag == "Enemy"){
                     hit.transform.GetComponent<EnemyCC>().health -= 15;
                 }
             }
             var hitRotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
             Instantiate(decal, hit.point, hitRotation);    
             canFire = false;
             clipAmmo -= 1;
             missingShots += 1;
             StartCoroutine(FireRate(1));
             }
         if(Input.GetButtonDown("Fire1") && canFire && clipAmmo == 0 && !reloading){
             reloading = true;
             StartCoroutine(ReloadTime(3));
         }
 
         if(Input.GetButtonDown("Reload") && storedAmmo != 8 && !reloading){
             reloading = true;
             StartCoroutine(ReloadTime(3));
         }
         }
     public IEnumerator FireRate (float delay){
         yield return new WaitForSeconds(delay);
         canFire = true;
     }
     public IEnumerator SoundCooldown(float delay){
         GameObject enemy = GameObject.Find("EnemyAI");
         EnemyAi enemyAi = enemy.GetComponent<EnemyAi>();
         yield return new WaitForSeconds(delay);
         enemyAi.couldHearGun = false;
 
     }
     public IEnumerator ReloadTime (float delay){
         yield return new WaitForSeconds(delay);
         reloading = false;
         if(storedAmmo >= 8){
             storedAmmo -= missingShots;
             clipAmmo += missingShots;
             missingShots = 0;
         }
     }
 }
 

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

Answer by Voridian · Jul 22, 2014 at 10:42 AM

Sorry to waste peoples time but i got it now, StartCoroutine(SoundCooldown(1)); was firing off for every enemy in the scene, all i had to do was move it out of the foreach section. i an such an idiot sometimes :P

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 T27M · Jul 22, 2014 at 10:54 AM 0
Share

It's good you found the cause of your lag, but still take a look at storing references and object pooling ins$$anonymous$$d of getting them each frame. Getting a reference to something you already have a reference of is unnecessary and could also lead to performance issues, especially on mobiles and when using GameObject.Find() with a lot of GameObjects.

avatar image
1

Answer by T27M · Jul 22, 2014 at 10:02 AM

My money would be on your call(s) to GameObject.Find (). GameObject.Find() isn't the most efficient method, plus you are calling it multiple times since you have it in Update(); If you're going to use it do it in Start().

The player for example:

 player = GameObject.Find("Player");

You don't need to do this every frame, but only once at start and the same goes for getting the CharacterController.

If you are creating enemies dynamically and need a reference to all the enemies in the game use some sort of object pooling and store a reference to a List of the enemies rather than trying to find them each frame.

Comment
Add comment · Show 4 · 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 Voridian · Jul 22, 2014 at 10:10 AM 0
Share

when i move those lines then i just get errors for them not not containing a definition when i call them in the update void

avatar image VioKyma · Jul 22, 2014 at 10:21 AM 0
Share

@Voridian I think you misunderstood the answer a little there.

T27$$anonymous$$ means that you get the references to the objects you need to find on Start and store them for later reference.

For example:

 void Start() {
     player = GameObject.Find("Player");
 }

and remove line 24 (the same code)

Also, I noticed you use

 GameObject enemy = GameObject.Find("EnemyAI");

several times. Perhaps this would be a good candidate for the above mentioned object pool, where you could update when adding and remove enemies ins$$anonymous$$d of having to find them every Update.

I hope this clarifies what you need to do a bit

avatar image T27M · Jul 22, 2014 at 10:28 AM 0
Share

Did you declare them in the class? It should look something like

         // ...other variables
         GameObject player;
         CharacterControler characterControler;
         private List<EnemyAi> enemies = new List<EnemyAi>();
     
         // Use this for initialization
         void Start ()
         {
                 player = GameObject.Find ("Player");
                 characterControler = player.GetComponent<CharacterControler> ();
         }
     
         // Update is called once per frame
         void Update ()
         {
                 characterControler.ammoCount = clipAmmo;
                 characterControler.totalAmmo = storedAmmo;
                 var enemyObjects = GameObject.FindGameObjectsWithTag ("Enemy");
                 foreach (GameObject enemyObj in enemyObjects) {
                         EnemyAi enemyAi = enemyObj.GetComponent<EnemyAi> ();
                         if (enemyAi != null) {
                                 enemies.Add (enemyAi);
                         }
                 }
                 RaycastHit hit;
                 Ray shooterRay = new Ray (transform.position, transform.forward);
         
                 if (Input.GetButton ("Fire1") && canFire && clipAmmo > 0) {
                     // What is the "EnemyAI" GameObject?
                     // Try this ins$$anonymous$$d? 
                         if (enemies.Count > 0) {
                                 foreach (EnemyAi enemy in enemies) {
                                         EnemyAi enemyAi = enemy.GetComponent<EnemyAi> ();
                                         enemyAi.couldHearGun = true;
                                         StartCoroutine (SoundCooldown (1));
                                 }
                         }
                 }
         
         }
avatar image Voridian · Jul 22, 2014 at 10:28 AM 0
Share

oh ok, so does:

         CharacterControler characterControler = player.GetComponent<CharacterControler>();


get moved as well? because that causes an error with:

         characterControler.ammoCount = clipAmmo;
         characterControler.totalAmmo = storedAmmo;

EDIT: also the lag spike is still there. only way to get rid of i have found so far is removing everything to do with foreach

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

23 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

Related Questions

A node in a childnode? 1 Answer

Question on Using a Foreach Loop on Nested Children 1 Answer

Distribute terrain in zones 3 Answers

Multiple Cars not working 1 Answer

How can i stop my game from laging during instantiation? C# 2 Answers


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