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 dgaag91 · May 25, 2020 at 02:22 AM · mathsimulationsimulatorsimulateslot

I'm having Unity go through a large number of iterations using for loops. How can I do this without Unity "freezing up" while the for loop is running?

I'm running slot math simulations in Unity using for loops which iterate through a large number of random screens. I typically run 10 to 100 million simulations in a single run which, depending on the game rules, can take from 1 minute to 30 minutes or more. As I'm waiting for the sims to finish, the Unity project freezes up and becomes unusable, i.e. everything becomes unclickable (scenes, game tab, inspector, etc). How can I make Unity run those sims in the background while still being able to interact with other things within the project? The code running the sims lives in the Update method in a Monobehavior class, and start once a button is clicked. Maybe it can be done differently?

EDIT: The simulations inside the for loop only include mathematical calculations. After reading the example here, I tried the following using Burst:

 protected void Simulate(int _runs)
 {
     for (int run = 0; run < _runs; run++)
     {
         InitializeMachine();

         float time1 = Time.realtimeSinceStartup;
         stats = new StatsHandler(trials, this);

         SimJob sim = new SimJob { _game = this, _trials = trials, };
         sim.Execute();

         float time2 = Time.realtimeSinceStartup;
         float dt = time2 - time1;
         elapsedTime = string.Format("{0:00}h:{1:00}m:{2:00.000}s", (int)dt / 3600, (int)dt / 60, dt % 60);
         stats.ComputeRTP();

         Debug.Log("game rtp: " + stats.GameRTP);
         Debug.Log(trials + " trials completed in " + elapsedTime);

         SetCustomStats();
         stats.GenerateAndPrintStats(elapsedTime);            
     }
     
 }

And this is how I defined my job struct:

 [BurstCompile]
 public struct SimJob : IJob
 {
     public SlotMachine _game;
     public int _trials;
 
     public void Execute()
     {
         for (int i = 0; i < _trials; i++)
         {
             int win = 0;
             win = _game.Spin();
 
             if (win > 0) _game.Stats.HitRateCount++;
             if (win > _game.Bet) _game.Stats.WinRateCount++;
             if (win >= _game.Bet * 10) _game.Stats.GoodWinRateCount++;
             _game.Stats.AddToTotalWin(win);
         }
     }
 }

... but the computation time is exactly the same as without using Burst...

EDIT: So, before I decide to infuse burst into my ocean of code, I want to make sure I understand how to implement it (and see the value of compiling with burst myself). To do this, I created a class that simulates the probability of getting one side of a fair coin after flipping it with and without using the burst compiler.

 using UnityEngine;
 using Unity.Jobs;
 using Unity.Burst;
 using Unity.Collections;
 
 public class Sim : MonoBehaviour
 {
     [SerializeField] private int trials = 50000000;
     [SerializeField] private bool usingBurst = false;
 
     void Start()
     {
   
     }
 
     void Update()
     {
         if (Input.GetKeyDown(KeyCode.Space))
         {
             float time1 = Time.realtimeSinceStartup;
             if (usingBurst)
             {
                 var trialsArray = new NativeArray<int>(1, Allocator.Persistent);
                 trialsArray[0] = trials;
                 var successesArray = new NativeArray<int>(1, Allocator.Persistent);
                 var rng = new NativeArray<Unity.Mathematics.Random>(1, Allocator.Persistent);
                 rng[0] = new Unity.Mathematics.Random((uint)Random.Range(1, 1000000));
 
                 SimJob simJob = new SimJob { _trials = trialsArray, _successes = successesArray, _rng = rng };
                 simJob.Run();                
                 Debug.Log((double)successesArray[0] / trials);
                 trialsArray.Dispose();
                 successesArray.Dispose();
                 rng.Dispose();
             }
             else
             {                
                 int successes = 0;
                 for (int i = 0; i < trials; i++)
                 {
                     if (Random.Range(0, 2) == 0)
                     {
                         successes++;
                     }
                 }
                 
                 Debug.Log((double)successes / trials);
             }
 
             float time2 = Time.realtimeSinceStartup;
             Debug.Log("execution time in seconds "+ (usingBurst ? "with " : "without ") + "burst: "  + (time2 - time1));
         }
     }
 }
 
 [BurstCompile]
 public struct SimJob : IJob
 {   
     public NativeArray<int> _trials;
     public NativeArray<int> _successes;
     public NativeArray<Unity.Mathematics.Random> _rng;
 
     public void Execute()
     {        
         int t = _trials[0];
         int s = 0;
         for (int i = 0; i < t; i++)
         {            
             if (_rng[0].NextInt(0,2) == 0)
             {
                 s++;
             }
         }
         _successes[0] = s;       
     }
 }
 

Since I don't want to use the Random class in my struct, I decided to go with using Mathematics.Random, but it looks like I need to seed it before each coin flip? The code above gives the same value each random trial when executed with burst, is there a way to only have to seed rng[0] once per simulation?

Comment
Add comment · Show 11
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 Captain_Pineapple · May 27, 2020 at 08:04 AM 0
Share

depends. What exactly do you do in the job? If it's just mathematical calculations you can use the job system and the burst compiler to move this to another thread at 10x speed. With this you would not have any impact on the "playability" of your game. Can you share some insight on your actual task?

avatar image dgaag91 Captain_Pineapple · May 28, 2020 at 03:26 AM 0
Share

@Captain_Pineapple Thank you for your response. Wow! I didn't know I could decrease my computation time by 10x. I have just become more interested in optimizing computation time than running "background" sims hahah! Please read my update above. I'd be happy to provide more insight if necessary. All the methods used for simulations only perform mathematical computations.

avatar image Captain_Pineapple dgaag91 · May 28, 2020 at 12:55 PM 0
Share

Hey, well for your current code that is no wonder. If you really want to use burst you have to take care of a lot of things. $$anonymous$$ost importantly for this is your data setup. Since your data has to be thread safe you have to prepare it accordingly. The User guide your referenced does contain all information on allowed data types. For your case that means: Everything that is done in Slot$$anonymous$$achine has to be moved to the job or a struct since you can not have a class in a job. (that is because a class is a so called "reference type")


So what would be the best for you?

As i can not tell that from the code you posted you have to make a call here: are "runs" in the for loop dependend or independend of each other? so does the second run use data from the first run?


also what is the set of data needed to start the job? what is the set of data that comes out of it? can you list this up?

Show more comments
avatar image Captain_Pineapple · Jun 01, 2020 at 10:20 PM 0
Share

Well that basically looks like the thing you want to do. About the random generator i sadly cannot help you.


would you $$anonymous$$d sharing the results of this regarding the needed time? Be carefull though that the needed Time can be heavily influenced by running this in the editor. A built version will result in more accurate times.


This job should now also be able to run in parallel in other threads if you change the used Job interface. This will then as i wrote you in my last comment enable you to do the same action mutliple times in parallel with $$anonymous$$imal additional overhead.

you can change the Allocator used for the Native Arrays to TempJob. This allocator will provide more speed.

Also since the the random generator of Unity.$$anonymous$$athematics is a struct you do not need a native array here as long as you just have one job. I am not sure here if the same generator can be used accross multiple parallel jobs or if you'd have to create a generator for each job. You'll have to test that for youself.


other then that looks good, let us know how you progress.

avatar image Captain_Pineapple Captain_Pineapple · Jun 06, 2020 at 11:42 AM 0
Share

did you manage to solve this?

avatar image dgaag91 Captain_Pineapple · Jun 06, 2020 at 09:33 PM 0
Share

I was able to run coin flip sims both ways. The sims run 25x faster with burst which is pretty insane. Though, I realized it would take a lot of time and patience to redesign the current code in my original project, so I won't be implementing burst anytime soon. Using coroutines partially solves my original question because it slows down my sims a lot. Regarding the question I posted, my inquiry turned in a different direction, and you've provided me satisfactory answers, so I wish I could accept one of your comments as the answer and close this question hahah.

Show more comments

2 Replies

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

Answer by RLord321 · Jun 02, 2020 at 02:11 AM

Lookup StartCoroutine. If you make a function return type IEnumerator and use yield return null, it will return control back to Unity so it won't freeze:

 private bool completedTask;
 
 void Start()
 {
   StartCoroutine(LongLoopFunction);
 }
 
 void Update()
 {
   if( completedTask)
   {
     Debug.Log("All Done");
   }
 }
 
 private IEnumerator LongLoopFunction()
 {
   for(int i = 0; i < 100000; i++)
   {
     expensiveStatement;
     yield return null;
   }
   completedTask = true;
 }
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 shaderLab2 · Jun 09, 2020 at 03:44 AM

The nvoke() method is a delegation mechanism of Unity3D

void Start()

 {

     InvokeRepeating("Iktest", 0, 2); 
 }

 void Update()
 {

     if (Input.GetKeyDown(KeyCode.I))
     {
         if (IsInvoking("Iktest"))
         {
             CancelInvoke("Iktest");
             Debug.Log("cancel");
         }
     }
 }

 void Iktest()
 {
     Debug.Log("At work");
 }

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

141 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

Related Questions

Simulate canvas button click 2 Answers

Applying velocity to non rigid body object? By math? 2 Answers

Unity Store Asset has no collision? 1 Answer

Simulating Combat Results 1 Answer

How police games simulator coding,how police simulator games coding and building ? 0 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