本日はBlender枠です。
以前Blenderでサーバーを立ててUnityへデータを送信しました。
この記事で使用した通信プロトコルはUDPと呼ばれるものを使用しました。
今回はTCPのプロトコルを使用してUnityとBlenderで通信を行っていきます。
〇UDPとTCPの違い
UDPもTCPもどちらも通信を行うプロトコルです。
UDPはリアルタイム通信や大規模データの送信に向いており、送信元のデバイスでは送信先がデータを受け取ったことを確認せずにデータを送り続けます。
デメリットとしては通信のデータロスが発生する可能性があります。
逆にTCPは通信相手とのコネクションを確立している状態で通信を行います。
つまり通信データの確実性があります。
今回はこのTCPの仕組みでBlenderとUnityで通信を行います。
〇参考
〇Blenderサーバー
BlenderではSocketを使用しています。
次のコードを実行します。
import bpy import socket import threading class ClientHandler(threading.Thread): def __init__(self, client_socket): threading.Thread.__init__(self) self.client_socket = client_socket def run(self): while True: request = self.client_socket.recv(1024) if not request: break print("[*] Received: %s" % request.decode()) self.client_socket.close() class ServerThread(threading.Thread): def __init__(self, bind_ip, bind_port): threading.Thread.__init__(self) self.bind_ip = bind_ip self.bind_port = bind_port def run(self): server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind((self.bind_ip, self.bind_port)) server.listen(5) print("[*] Listening on %s:%d" % (self.bind_ip, self.bind_port)) while True: client, addr = server.accept() print("[*] Accepted connection from: %s:%d" % (addr[0], addr[1])) client_handler = ClientHandler(client) client_handler.start() self.client_socket = client # Run the server in a new thread server_thread = ServerThread("0.0.0.0", 9999) server_thread.start() def send_message_to_unity(message): server_thread.client_socket.send(message.encode()) class SimpleOperator(bpy.types.Operator): """Tooltip""" bl_idname = "object.send_message" bl_label = "Send Message" def execute(self, context): send_message_to_unity("Hello, Unity!") return {'FINISHED'} class CustomPanel(bpy.types.Panel): """Creates a Panel in the Object properties window""" bl_label = "Send Message Panel" bl_idname = "OBJECT_PT_hello" bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_context = "object" def draw(self, context): layout = self.layout layout.operator("object.send_message") bpy.utils.register_class(SimpleOperator) bpy.utils.register_class(CustomPanel)
コードを実行するとオブジェクトプロパティウィンドウにSend Messageが表示されます。
このボタンを押すことでUnityにメッセージを送信します。
〇Unity
Unity側は次のコードを使用します。
このコードではHキーを押すことでBlender側にメッセージを送ります。
using System.Net.Sockets; using System.Text; using System.Threading; using UnityEngine; public class TCPClient : MonoBehaviour { private TcpClient _client; private NetworkStream _stream; void Start() { _client = new TcpClient("localhost", 9999); _stream = _client.GetStream(); // Start a new thread to listen for incoming messages new Thread(() => { var responseBytes = new byte[1024]; while (true) { var bytesRead = _stream.Read(responseBytes, 0, responseBytes.Length); Debug.Log("Received: " + Encoding.ASCII.GetString(responseBytes, 0, bytesRead)); } }).Start(); } void Update() { // Send a message when the H key is pressed if (Input.GetKeyDown(KeyCode.H)) { var bytes = Encoding.ASCII.GetBytes("Hello, Blender!"); _stream.Write(bytes, 0, bytes.Length); } } private void OnDestroy() { _stream.Close(); _client.Close(); } }
〇実行
実行しそれぞれの送信ボタンを押すことでメッセージを送りあうことができます。
以上でTCPの双方向通信が行えました。
細かいコードの解説は後日行います。本日は以上です。