Archive:Communication en UDP entre un script python et Blender Game Engine

Ce wiki a été archivé en 2018.

Le nouveau wiki se trouve à: ressources.labomedia.org

Les fonctionnalités sont désactivées: vous pouvez faire une recherche sur Google site:https://wiki.labomedia.org et découvrir La Labomedia.

De Centre de Ressources Numériques - Labomedia
Aller à : navigation, rechercher


Ressources

Exemple 1 : Entre 2 fichiers Blender

Cet exemple permet de copier la position et l'orientation d'un cube du fichier server au fichier client: le cube pourrait être une voiture dans un jeu en réseau.

Blender 2.49 et python 2.6

Fichier:Udp example2.6.zip

Script python 2.6 Server

import socket
import cPickle # serializing and de-serializing

# Get owner
controller = GameLogic.getCurrentController()
owner = controller.owner

# Set server
Host = 'localhost'
ServerPort = 10000

# Set socket server only one time at the first frame
if not owner['OneTime']:
     # Set UDP socket
     GameLogic.sServer = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
     
     # Bind the socket to host
     GameLogic.sServer.bind((Host, ServerPort))
     
     # If no data are found, pass
     GameLogic.sServer.setblocking(0)
     
     # Set prop to pass test
     owner['OneTime'] = True
     
# Get Position and Orientation
PosCar = owner.worldPosition
OriCar = owner.worldOrientation

# Serialize data
Data = cPickle.dumps((PosCar,OriCar))

# Send Data to client
GameLogic.sServer.sendto(Data, (Host, 10001))

Script python 2.6 Client

import socket
import cPickle # serializing and de-serializing

# Get owner
controller = GameLogic.getCurrentController()
owner = controller.owner

# Set Client
host = "localhost"
ClientPort = 10001

# Set socket client only one time at the first frame
if not owner['OneTime'] :
    # Set UDP socket
    GameLogic.socketClient = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    
    # Bind the socket to host
    GameLogic.socketClient.bind((host, ClientPort))
    
    # Set Buffer size
    GameLogic.socketClient.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 1024)
    
    # If no data are found, pass
    GameLogic.socketClient.setblocking(0)
    
    # Set prop to pass test
    owner['OneTime'] = True
    
#------------if RECEIVE UDP --------------#
try:
    # Get data in buffer
    UpData, SRIP = GameLogic.socketClient.recvfrom(1024)
    
    # De-serialize, return tuples
    msg = cPickle.loads(UpData)
    
    # Set Position and orientation
    owner.worldPosition = (msg[0][0], msg[0][1], msg[0][2])
    owner.worldOrientation = ( (msg[1][0], msg[1][1], msg[1][2]) )
    
except :
    pass

Blender 2.6 et python 3

Fichier:Udp example3.zip

Script python 3 Server

# python 3
import GameLogic
import socket
import pickle # serializing and de-serializing

# Get owner
controller = GameLogic.getCurrentController()
owner = controller.owner
Host = 'localhost'
ServerPort = 10000

# Set socket server only one time at the first frame
if not owner['OneTime']:
    # Set UDP socket
    GameLogic.sServer = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    
    # Bind the socket to host
    GameLogic.sServer.bind((Host, ServerPort))
    
    # If no data are found, pass
    GameLogic.sServer.setblocking(0)
    
    # Set prop to pass test
    owner['OneTime'] = True
    
# Get Position and Orientation
PosCar = owner.worldPosition
OriCar = owner.worldOrientation

# New in python 3
stupid = (PosCar[0], PosCar[1], PosCar[2], OriCar[0][0], OriCar[0][1], OriCar[0][2], OriCar[1][0], OriCar[1][1], OriCar[1][2], OriCar[2][0], OriCar[2][1], OriCar[2][2])

# Serialize data
Data = pickle.dumps(stupid)

# Send Data to client
GameLogic.sServer.sendto(Data, (Host, 10001))

Script python 3 Client

# python 3
import GameLogic
import mathutils
import socket
import pickle # serializing and de-serializing

# Get owner
controller = GameLogic.getCurrentController()
owner = controller.owner
host = "localhost"
ClientPort = 10001

# Set socket client only one time at the first frame
if not owner['OneTime'] :
    # Set UDP socket
    GameLogic.socketClient = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    
    # Bind the socket to host
    GameLogic.socketClient.bind((host, ClientPort))
    
    # Set Buffer size
    GameLogic.socketClient.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 1024)
    
    # If no data are found, pass
    GameLogic.socketClient.setblocking(0)
    
    # Set prop to pass test
    owner['OneTime'] = True
     
#------------if RECEIVE UDP --------------#
try:
    # Get data in buffer
    UpData, SRIP = GameLogic.socketClient.recvfrom(1024)
    
    # De-serialize, return tuples
    test = pickle.loads(UpData)
    
    # Set Position and orientation
    owner.worldPosition = (test[0], test[1], test[2])
    
    # Orientation must be a matrix
    owner_ori = mathutils.Matrix(((test[3], test[4], test[5]) , (test[6], test[7], test[8]) , (test[9], test[10], test[11])))
    owner.worldOrientation = owner_ori
except :
    pass

Problème du buffer UDP

Dans les fichiers ci-dessus, les scripts sont lancés avec un actuator qui pulse à 0. Si le client pulse moins vite que le server, le buffer se rempli. La latence est expliquée plus en détail. Si le client pulse à 2, soit 15 fps, le mouvement est haché: pour qu'un jeu soit fluide, il doit tourner à beaucoup plus que 30 fps.

Dans les scripts, le buffer est limité, il n'y a pas de retard sur le client, mais cela correspond à des valeurs qui sont perdues et un mouvement haché du client.

Exemple 2: entre un script et Blender

Le jeu Land_Of_Love lie un script et Blender: Blender 2.49 et python 2.6.