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
3
Question by thecritter · Mar 05, 2017 at 03:25 PM · simulationupdate functionpythontcp

Unity as a simulation environment - how to delay the Update() loop while big calculation is performed

Dear community,

I am quite new to Unity and i am currently using it as a tool for designing a simple simulated environment for my pilot research study. Here is a simplified explanation:

  1. The main character (agent) scans the environment and sends the state (as a JSON object) via TCP socket to a python server.

  2. On the python server side a big calculation is performed based on the the state. The result is an action that is being sent back via TCP to Unity.

  3. The character needs to perform this action in Unity and then again scan the environment. The new state is sent again to the python server....

  4. This process is being repeated 'till infinity (unless the client or server is stopped) eventually leading to the agent self-developing a behavior based on its learning.

I finished creating the environment in unity as well as programmed the learning algorithm in python. Moreover, i managed to establish TCP connection between the two. However, i stumbled across the problem of the main Update() loop in Unity.

Namely, if i simplify the process to Unity sending ping (being the state) and python sending pong (being the action) i need the following process to be repeated.

  1. freeze simulation

  2. ping

  3. calculation

  4. pong

  5. unfreeze simulation

So in the Unity Start()method i setup the socket and send the initial ping. What i would like in the main Update() loop is to make Unity wait for python's pong answer before updating the frame. I created a script containing a toy example and tried to simulate the calculation-time in python by adding 2 seconds of delay before sending the pong to Unity.

Here is the code for the Unity script (just attach it to the Main Camera):

 using UnityEngine;
 using System;
 using System.IO;
 using System.Net.Sockets;
 
 public class networkSocketPingPong : MonoBehaviour
 {
     public String host = "localhost";
     public Int32 port = 50000;
 
     internal Boolean socket_ready = false;
     internal String input_buffer = "";
 
     TcpClient tcp_socket;
     NetworkStream net_stream;
 
     StreamWriter socket_writer;
     StreamReader socket_reader;
 
     private void Start()
     {
         setupSocket();
         writeSocket("ping");
     }
 
     
      void Update()
      {
         
         string received_data = readSocket();
         
         switch (received_data)
              {
                  case "pong":
                      Debug.Log("Python controller sent: " + (string)received_data);
                      writeSocket("ping");
                      break;
                  default:
                      Debug.Log("Nothing received from Python");
                      break;
          }
     }
 
     void OnApplicationQuit()
     {
         closeSocket();
     }
 
     // Helper methods for:
     //...setting up the communication
     public void setupSocket()
     {
         try
         {
             tcp_socket = new TcpClient(host, port);
             net_stream = tcp_socket.GetStream();
             socket_writer = new StreamWriter(net_stream);
             socket_reader = new StreamReader(net_stream);
             socket_ready = true;
         }
         catch (Exception e)
         {
             // Something went wrong
             Debug.Log("Socket error: " + e);
         }
     }
 
     //... writing to a socket...
     public void writeSocket(string line)
     {
         if (!socket_ready)
             return;
 
         socket_writer.Write(line);
         socket_writer.Flush();
     }
 
     //... reading from a socket...
     public String readSocket()
     {
        if (!socket_ready)
         {
             Debug.Log("Socket is not ready");
             return "";
         }
 
         if (net_stream.DataAvailable)
             return socket_reader.ReadLine();
 
         return "";
     }
 
     //... closing a socket...
     public void closeSocket()
     {
         if (!socket_ready)
             return;
 
         socket_writer.Close();
         socket_reader.Close();
         tcp_socket.Close();
         socket_ready = false;
     }
 }
 

...and here is the python server code:

 import socket
 import time
 
 host = 'localhost' 
 port = 50000
 backlog = 5 
 size = 1024 
 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
 s.bind((host,port)) 
 s.listen(backlog) 
 
 while 1:
     client, address = s.accept() 
     print "Client connected."
     while 1:
         data = client.recv(size)
         if data == "ping":
             time.sleep(2)
             print ("Unity Sent: " + str(data))
             client.send("pong\n")
         else:
             client.send("Bye!")
             print ("Unity Sent Something Else: " + str(data))
             client.close()
             break

I first run the python server and then the simulation (via Unity editor). This results with the following console screenshot: alt text

This proves that the main Update() loop is running while i want it to pause and update only when "pong" is received from the server. Any ideas how to achieve this?

I searched the forum for answers but always stumbled upon questions that ask for the opposite - how to make Unity not to freeze - and answers that suggest using Coroutines or Threads.

Any help will be much appreciated.

Thanks in advance!!!

unityconsole.png (62.4 kB)
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

1 Reply

· Add your reply
  • Sort: 
avatar image
4

Answer by anilhdas · Mar 06, 2017 at 07:06 AM

As I read through your problem, you want to freeze simulation in the client app until your server responds with the necessary action.

You can freeze the Unity app by setting Time.timescale = 0 and resume it when you recieve the response from server by setting timescale back to 1.

But I suggest you to use IEnumerators instead of Update function, since freezing the execution of default functions like Update and FixedUpdate isn't a recommended way to do things.

What I recommend is you can define the task to perform (finding the status, or whatever your client app is supposed to do) in an IEnumerator function and yield a return once your server responds and finally start the coroutine recursively.

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 thecritter · Mar 06, 2017 at 08:15 AM 0
Share

Thanks for the quick reply. However, your suggestion ignores the fact that the Unity simulated environment should wait for the server response before continuing. By using a coroutine the environment keeps changing while the calculation on the python server is taking place. This way the loop including: "scan the environment - pause and send state via TCP to python algorithm - do calculation - send the action back to Unity - unpause" is broken. The coroutine will never interrupt the Update function.

avatar image anilhdas thecritter · Mar 06, 2017 at 02:22 PM 0
Share

Great. What do you mean by the "simulated environment keeps changing". I would see if I can help if you give me further details of how're you simulating the environment in your client app.

avatar image Glurth thecritter · Mar 06, 2017 at 05:43 PM 0
Share

Converted your answer to a comment @thecritter. If your client update routines check Time.timescale and return immediately if == 0, what else about the environment would change? Rigidbodies, or animations, for example, will not be processed when timescale == 0.

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

6 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Unity tcp_client only working on localhost 1 Answer

Combining python and Unity 3D 1 Answer

How to enable each 3D object to run an instance of python based code 0 Answers

Creating Simulator Quick and Fast 1 Answer

Interactive Cloth - Mobile? 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