I have some code for sending a command from external software, for example Blender Python, to Unreal Engine editor. This is what I got so far which is working:
import sys
sys.path.append(r'C:\UnrealEngine5\Engine\Plugins\Experimental\PythonScriptPlugin\Content\Python')
import remote_execution as remote
def executeCommand(command):
remote_exec = remote.RemoteExecution()
remote_exec.start()
remote_exec.open_command_connection(remote_exec.remote_nodes)
exec_mode = 'EvaluateStatement'
rec = remote_exec.run_command(command, exec_mode=exec_mode)
return rec
command = "print('hello')"
result = executeCommand(command)
This will print "hello" in running UE editor output log.
My question is how would I send an entire script to the executeCommand() function? It expects a string and not a .py file. Here is the function & documentation for the remote_exec.run_command:
def run_command(self, command, unattended=True, exec_mode=MODE_EXEC_FILE, raise_on_failure=False):
'''
Run a command remotely based on the current command connection.
Args:
command (string): The Python command to run remotely.
unattended (bool): True to run this command in "unattended" mode (suppressing some UI).
exec_mode (string): The execution mode to use as a string value (must be one of MODE_EXEC_FILE, MODE_EXEC_STATEMENT, or MODE_EVAL_STATEMENT).
raise_on_failure (bool): True to raise a RuntimeError if the command fails on the remote target.
Returns:
dict: The result from running the remote command (see `command_result` from the protocol definition).
'''
data = self._command_connection.run_command(command, unattended, exec_mode)
if raise_on_failure and not data['success']:
raise RuntimeError('Remote Python Command failed! {0}'.format(data['result']))
return data
And the definition of Execution modes:
# Execution modes (these must match the names given to LexToString for EPythonCommandExecutionMode in IPythonScriptPlugin.h)
MODE_EXEC_FILE = 'ExecuteFile' # Execute the Python command as a file. This allows you to execute either a literal Python script containing multiple statements, or a file with optional arguments
MODE_EXEC_STATEMENT = 'ExecuteStatement' # Execute the Python command as a single statement. This will execute a single statement and print the result. This mode cannot run files
MODE_EVAL_STATEMENT = 'EvaluateStatement' # Evaluate the Python command as a single statement. This will evaluate a single statement and return the result. This mode cannot run files
The remote_execution.py file is located in UnrealEngine5\Engine\Plugins\Experimental\PythonScriptPlugin\Content\Python
UPDATE:
Changing Evaluate Statement to Execute file, and running this script give me another error:
Python: Traceback (most recent call last):
File "\test_remote_import.py", line 19, in <module>
result = executeCommand(command)
^^^^^^^^^^^^^^^^^^^^^^^
File "\test_remote_import.py", line 11, in executeCommand
rec = remote_exec.run_command(command, exec_mode=exec_mode)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\UnrealEngine5\Engine\Plugins\Experimental\PythonScriptPlugin\Content\Python\remote_execution.py", line 124, in run_command
data = self._command_connection.run_command(command, unattended, exec_mode)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\UnrealEngine5\Engine\Plugins\Experimental\PythonScriptPlugin\Content\Python\remote_execution.py", line 429, in run_command
self._send_message(_RemoteExecutionMessage(_TYPE_COMMAND, self._node_id, self._remote_node_id, {
File "C:\UnrealEngine5\Engine\Plugins\Experimental\PythonScriptPlugin\Content\Python\remote_execution.py", line 444, in _send_message
self._command_channel_socket.sendall(message.to_json_bytes())
^^^^^^^^^^^^^^^^^^^^^^^
File "C:\UnrealEngine5\Engine\Plugins\Experimental\PythonScriptPlugin\Content\Python\remote_execution.py", line 551, in to_json_bytes
json_str = self.to_json()
^^^^^^^^^^^^^^
File "C:\UnrealEngine5\Engine\Plugins\Experimental\PythonScriptPlugin\Content\Python\remote_execution.py", line 542, in to_json
return _json.dumps(json_obj, ensure_ascii=False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Program Files\Blender Foundation\Blender 4.2\4.2\python\Lib\json\__init__.py", line 238, in dumps
**kw).encode(obj)
^^^^^^^^^^^
File "C:\Program Files\Blender Foundation\Blender 4.2\4.2\python\Lib\json\encoder.py", line 200, in encode
chunks = self.iterencode(o, _one_shot=True)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Program Files\Blender Foundation\Blender 4.2\4.2\python\Lib\json\encoder.py", line 258, in iterencode
return _iterencode(o, 0)
^^^^^^^^^^^^^^^^^
File "C:\Program Files\Blender Foundation\Blender 4.2\4.2\python\Lib\json\encoder.py", line 180, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type module is not JSON serializable
While running this updated script:
import sys
sys.path.append(r'C:UnrealEngine5\Engine\Plugins\Experimental\PythonScriptPlugin\Content\Python')
import remote_execution as remote
import test_print as test
def executeCommand(command):
remote_exec = remote.RemoteExecution()
remote_exec.start()
remote_exec.open_command_connection(remote_exec.remote_nodes)
exec_mode = 'ExecuteFile'
rec = remote_exec.run_command(command, exec_mode=exec_mode)
return rec
command = test
result = executeCommand(command)
test_print.py simply contains
print("success")
If I understand your question correctly, you can pass the script as a string by putting it in triple quotations: your_script = """ your script """
if you are loading a script you should be able to open the file using a standard method:
def read_py_script(filepath):
with open(filepath, 'r') as file:
return file.read()
script_string = read_py_script('your_script.py')
print(script_string)