py4godot

repository·master·Indexed 43 days ago

https://github.com/niklas2902/py4godot

A GDExtension plugin that allows developers to use Python as a scripting language within the Godot engine, similar to GDScript. Version 4.7-alpha21 supports Godot variant types, signal definitions via @signal, and Godot-compatible class creation using the @gdclass decorator. It requires Python 3.11 or higher.

Tokens
2.8K
Snippets
12
Records
13
Agent score
54%

What's inside py4godot

  1. Build py4godot from source on Linux

    master

    To build py4godot on Linux (tested on Ubuntu 20.04.4 LTS), follow these steps:

    1. Set up a virtual environment (optional but recommended):

      python3 -m venv venv
      source venv/bin/activate
      pip install -r requirements.txt

      Note: If using Python 3.12, you must run pip install setuptools and python copy_distutils.py first to resolve distutils dependencies.

    2. Generate files:

      python generate.py

      Note: For faster development builds, use python generate.py -dev_build=True.

    3. Cythonize files:

      python cythonize_files.py

      Note: For faster development builds, use python cythonize_files.py -mode="dev".

    4. Compile the project:

      python build.py --target_platform=linux64 --compiler=gcc

      The compiled output will be located in build/py4godot.

    python build.py --target_platform=linux64 --compiler=gcc
  2. Build py4godot from source on Windows

    master

    To build py4godot on Windows, follow these steps:

    1. Set up a virtual environment (optional but recommended):

      python -m venv virtual_python
      .\virtual_python\Scripts\activate
      pip install -r requirements.txt
    2. Generate files:

      python generate.py

      Note: For faster development builds, use python generate.py -dev_build=True.

    3. Cythonize files:

      python cythonize_files.py

      Note: For faster development builds, use python cythonize_files.py -mode="dev".

    4. Compile the project:

      python build.py --target_platform=windows64 --compiler=msvc

      The compiled output will be located in build/py4godot.

    python build.py --target_platform=windows64 --compiler=msvc
  3. Install py4godot

    master

    To install py4godot in your Godot project, download the .zip file from the project's Releases page, extract the contents, and copy the resulting folder into the addons folder located at the root of your Godot project.

    mkdir addons
    cp -r py4godot addons/
  4. Define a Godot class in Python using @gdclass

    master

    To create a Godot-compatible class in Python, use the @gdclass decorator.

    Important: The class name defined under @gdclass must exactly match the filename.

    You can define:

    • Properties: Using standard Python type hints (e.g., test_int: int = 5).
    • Signals: Using the signal function from py4godot.signals, passing a list of SignalArg objects.
    • Methods: Standard Python methods. Use the @private decorator from py4godot.methods to hide methods from the Godot editor.

    Supported base classes can be imported from py4godot.classes (e.g., Node3D).

    from py4godot.methods import private
    from py4godot.signals import signal, SignalArg
    from py4godot.classes import gdclass
    from py4godot.classes.core import Vector3
    from py4godot.classes.Node3D import Node3D
    
    @gdclass
    class node3d(Node3D):
    
    	# define properties like this
    	test_int: int = 5
    	test_float: float = 5.2
    	test_bool: bool = True
    	test_vector: Vector3 = Vector3.new3(1,2,3)
    
    	# define signals like this
    	test_signal = signal([SignalArg("test_arg", int)])
    
    	def _ready(self) -> None:
    		pass
    
    	def _process(self, delta:float) -> None:
    		pass
    
    	# Hide the method in the godot editor
    	@private
    	def test_method(self):
    		pass
  5. Define signals using the @signal decorator

    master

    You can define a signal within a class by using the @signal decorator. This decorator inspects the function name and its arguments to register the signal with the underlying system. When using this decorator, you can optionally pass a list of SignalArg objects to specify argument names and types.

    from py4godot.signals import signal, SignalArg
    
    class MyClass:
        @signal(args=[SignalArg("value", int)])
        def my_signal(self, value):
            pass
  6. Retrieve a Godot singleton or node with get_singleton()

    master

    Use get_singleton(name: str) to access Godot engine singletons or specific nodes in the scene tree.

    The function follows this lookup priority:

    1. Engine Singletons: It first checks if the provided name is a registered singleton within the Engine instance.
    2. Scene Tree Nodes: If no engine singleton is found, it attempts to find a node with the matching name starting from the root of the scene tree (useful for custom singletons defined in Globals).

    Returns the Object if found, or None if the name does not correspond to a singleton or a node.

    from py4godot.singletons import get_singleton
    
    # Example: Accessing the Input singleton
    input_singleton = get_singleton("Input")
    
    # Example: Accessing a custom node/singleton in the scene tree
    my_node = get_singleton("MyGlobalNode")
    
    if input_singleton:
        # Use the singleton
        pass
  7. Use @gdproperty for property binding

    master

    The gdproperty function is an experimental decorator/helper used to define properties that are bound to Godot. It allows you to specify a type, a default value, and an optional hint. It uses inspection to determine the variable name from the assignment context.

    Note: This is marked as very experimental.

    @gdproperty(int, 0)
    def my_property(self):
        pass
    
    # Or as a direct assignment (experimental behavior):
    my_val = gdproperty(float, 1.0)
  8. Connect and disconnect functions to GDSignal

    master

    A GDSignal (which inherits from Signal) allows you to connect Python functions to a signal. The connect method automatically handles the conversion of the Python function into a Godot-compatible Callable object. You can also use disconnect to remove a connection using the same function reference.

    # Assuming 'sig' is an instance of GDSignal
    def _on_my_signal(value):
        print(f"Signal received: {value}")
    
    sig.connect(_on_my_signal)
    # ... later
    sig.disconnect(_on_my_signal)
  9. Manage connections with BuiltinSignal

    master

    A BuiltinSignal represents a signal that already exists on a Godot object. It provides methods to interact with the signal's connection state on the parent object:

    • connect(function, flags=0): Connects a Python function to the builtin signal.
    • disconnect(function): Disconnects a Python function from the signal.
    • is_connected(callable_obj): Checks if a specific callable is connected to the signal.
    • get_connections(): Returns the list of current connections for this signal.
    • get_object(): Returns the Godot object that owns this signal.
    • get_object_id(): Returns the instance ID of the owner object.
    # Assuming 'builtin_sig' is an instance of BuiltinSignal
    def _on_event(event):
        pass
    
    builtin_sig.connect(_on_event)
    
    if builtin_sig.is_connected(Callable.new2(parent, "_on_event")):
        print("Connected!")
    
    print(f"Owner ID: {builtin_sig.get_object_id()}")
  10. Supported Godot Variant Types

    master

    The py4godot library supports a wide range of Godot variant types, allowing for seamless data exchange between Python and the Godot engine. These types include standard scalars (int, float, bool, str), complex math types (Vector2, Vector3, Color, Transform3D, Quaternion, Basis), and specialized Godot containers (Array, Dictionary, PackedByteArray, PackedInt32Array, etc.).

    # The following types are supported by py4godot:
    core_types = {
        'NodePath', 'StringName', 'float', 'PackedInt64Array', 'Vector3i', 
        'PackedVector4Array', 'PackedColorArray', 'Projection', 'Rect2i', 
        'bool', 'int', 'Vector2', 'Nil', 'Rect2', 'Plane', 'Array', 
        'Signal', 'PackedVector3Array', 'Vector2i', 'Transform3D', 
        'Quaternion', 'Transform2D', 'Color', 'Vector3', 'Dictionary', 
        'RID', 'PackedFloat32Array', 'PackedFloat64Array', 'PackedStringArray', 
        'Basis', 'PackedByteArray', 'AABB', 'PackedVector2Array', 'Vector4', 
        'String', 'Callable', 'Vector4', 'Vector4i', 'PackedInt32Array', 
        'str', 'NoneType'
    }
  11. Use SignalArg to define signal arguments

    master

    The SignalArg class is used to provide metadata about a signal's arguments, specifically the name and the type. The type is automatically converted to a Godot variant type.

    from py4godot.signals import SignalArg
    
    arg = SignalArg("my_arg", int)
    # arg.name is "my_arg"
    # arg.variant_type is the Godot variant type for int