Benutzer-Werkzeuge

Webseiten-Werkzeuge


godot

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

godot [2025/11/12 22:16]
jango angelegt
godot [2026/11/04 13:59] (aktuell)
jango [GDScript]
Zeile 1: Zeile 1:
 +[[https://github.com/godotengine/godot|Godot]] ist eine kostenlose Open Source [[gameengine|Game Engine]] unter [[https://github.com/godotengine/godot/blob/master/LICENSE.txt|MIT Lizenz]].
  
 +[[https://www.youtube.com/watch?v=9i6uxm_ioG0|Clipping]]
 +
 +=====Bodies=====
 +
 +In Godot gibt es verschiedene Arten von Körpern (Bodies), die verwendet werden können, um die physikalischen Eigenschaften von Objekten in einer Spielwelt zu simulieren. Hier sind die wichtigsten Körperarten in Godot:
 +
 +  * StaticBody: Ein StaticBody ist ein starrer Körper, der von der Physik-Engine nicht beeinflusst wird. Er bleibt an einem festen Ort und kann nicht bewegt werden. Er wird oft für statische Elemente wie Wände, Böden und Plattformen verwendet.
 +  * RigidBody: Ein RigidBody ist ein dynamischer Körper, der von der Physik-Engine beeinflusst wird. Er reagiert auf Kräfte wie Schwerkraft und Kollisionen mit anderen Körpern. RigidBody-Objekte sind in der Lage, sich zu bewegen und können aufgrund von Kräften beschleunigen.
 +  * KinematicBody: Wie bereits erwähnt, ist ein KinematicBody ein Körper, der Kollisionen erkennt, aber von der Physik-Engine nicht beeinflusst wird. Er kann mithilfe von Code oder Skripten gesteuert werden und ist ideal für Charaktere oder Objekte, die spezielle Bewegungslogik benötigen.
 +  * Area: Ein Area ist ein unsichtbarer Körper, der nur Kollisionen registriert, aber keine physische Interaktion mit anderen Körpern hat. Er wird oft für Trigger-Bereiche oder Bereiche verwendet, die spezielle Ereignisse auslösen sollen, wenn andere Körper sie betreten oder verlassen.
 +  * MultiMeshInstance: Dieser Körper dient dazu, mehrere Instanzen eines Meshes zu erstellen, die individuell positioniert, skaliert und rotiert werden können. Er wird häufig in Szenen mit wiederholenden Elementen verwendet.
 +  * VehicleBody: Ein spezialisierter Körper, der für die Simulation von Fahrzeugen mit Rädern entwickelt wurde.
 +  * Distanz-Gelenk (DistanceJoint2D, DistanceJoint3D): Ermöglicht es, zwei Punkte in einem bestimmten Abstand voneinander zu halten.
 +  * Gelenk mit eingeschränktem Abstand (DampedSpringJoint2D, DampedSpringJoint3D): Ermöglicht es, zwei Punkte in einem bestimmten Abstand zu halten, mit der Möglichkeit, Dämpfung hinzuzufügen.
 +  * Gelenk mit eingeschränktem Winkel (RevoluteJoint2D, PinJoint, HingeJoint): Ermöglicht die Rotation von zwei Körpern um einen gemeinsamen Punkt (wie ein Türscharnier).
 +  * Schiebergelenk (SliderJoint2D, SliderJoint3D): Ermöglicht die lineare Bewegung zwischen zwei Körpern entlang einer bestimmten Achse.
 +  * Gelenk mit konstanter Richtung (GrooveJoint2D, GrooveJoint3D): Begrenzt die Bewegung eines Körpers auf eine bestimmte Richtung, ähnlich wie eine Schiene.
 +  * Können-Gelenk (ConeTwistJoint): Erlaubt komplexe Einschränkungen von Drehungen, insbesondere in 3D-Szenen.
 +  * Gelenk zur Vermeidung von Kollisionen (GearJoint2D, GearJoint3D): Verbindet zwei Gelenke miteinander und ermöglicht komplexe Interaktionen.
 +  * PrismaticJoint2D: Ermöglicht eine eingeschränkte lineare Bewegung zwischen zwei Körpern.
 +
 +=====Mesh=====
 +
 +<code gdscript>
 +extends Node
 +
 +func _ready():
 + _ready1()
 +
 +func _ready1():
 + var myMesh = MeshInstance3D.new()
 + myMesh.mesh = PlaneMesh.new()
 + var size = Vector3(15.0, 1, 15.0)
 + myMesh.scale = size
 + myMesh.create_convex_collision(true, true)
 + add_child(myMesh)
 + var camera = Camera3D.new()
 + camera.position = Vector3(0, 2, 2)
 + add_child(camera)
 +
 +func _ready2():
 + var myMesh = MeshInstance3D.new()
 + var custom_plane = create_custom_plane(Vector3(15, 1, 15), 2, 2) # Größe 5x5, 2x2 Segmente
 + myMesh.mesh = custom_plane
 + myMesh.scale = Vector3(15, 1, 15)
 + myMesh.rotation_degrees = Vector3(180, 0, 0)
 + add_child(myMesh)
 + var camera = Camera3D.new()
 + camera.position = Vector3(0, 2, 2)
 + add_child(camera)
 +
 +func create_custom_plane(size: Vector3, seg_x: int, seg_y: int) -> ArrayMesh:
 + var array_mesh = ArrayMesh.new()
 + var vertices = PackedVector3Array()
 + var indices = PackedInt32Array()
 + var uvs = PackedVector2Array()
 + var half_width = size.x / 2
 + var half_height = size.z / 2
 + # Vertices und UVs erstellen
 + for y in range(seg_y + 1):
 + for x in range(seg_x + 1):
 + var vx = lerp(-half_width, half_width, x / seg_x)
 + var vy = 0
 + var vz = lerp(-half_height, half_height, y / seg_y)
 + vertices.append(Vector3(vx, vy, vz))
 + uvs.append(Vector2(x / seg_x, y / seg_y))
 +
 + # Indices für die Dreiecke erstellen
 + for y in range(seg_y):
 + for x in range(seg_x):
 + var i = y * (seg_x + 1) + x
 + indices.append(i)
 + indices.append(i + seg_x + 1)
 + indices.append(i + seg_x + 2)
 + indices.append(i)
 + indices.append(i + seg_x + 2)
 + indices.append(i + 1)
 +
 + # Mesh-Daten vorbereiten
 + var arrays = []
 + arrays.resize(Mesh.ARRAY_MAX)
 + arrays[Mesh.ARRAY_VERTEX] = vertices
 + arrays[Mesh.ARRAY_INDEX] = indices
 + arrays[Mesh.ARRAY_TEX_UV] = uvs
 +
 + # ArrayMesh hinzufügen
 + array_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays)
 + return array_mesh
 +</code>
 +
 +=====Button=====
 +
 +{{godot_button_pressed_event.png}}
 +
 +<code>
 +func _on_button_pressed(extra_arg_0, extra_arg_1):
 + print(extra_arg_0 + extra_arg_1)
 +</code>
 +=====Lighting=====
 +
 +[[https://www.youtube.com/watch?v=0792U-wuwjA|Why 3D Games Look Bad in Godot]]
 +
 +=====GDScript=====
 +
 +====Instantiation====
 +
 +<code>
 +# Lade die Szene
 +var scene = preload("res://capsule.tscn")
 +
 +# Instanziere die Szene
 +var instance = scene.instantiate()
 +
 +# Füge die instanziierte Szene als Kind zum aktuellen Node hinzu
 +add_child(instance)
 +</code>
 +
 +====Movement====
 +
 +Move/rotate a Node3D
 +<code>
 +extends Node3D
 +
 +# Geschwindigkeit, mit der das Objekt bewegt wird
 +var speed = 5.0
 +
 +func _process(delta):
 +
 + # Bewegung auf der X-Achse
 + # position.x += speed * delta
 + # oder 
 + translate(Vector3(speed * delta, 0, 0))
 +
 + # Bewegung auf der Z-Achse
 + # position.z += speed * delta
 + # oder 
 + translate(Vector3(0, 0, speed * delta))
 +
 + # Rotation um die X-Achse
 + # rotation.x += 10 * deltaTime
 + # oder
 + rotate(Vector3(1, 0, 0), deg_to_rad(abs(speed) * 10 * delta))
 +
 + # Rotation um die Z-Achse
 + #rotation.z += 10 * deltaTime
 + # oder
 + rotate(Vector3(0, 0, 1), deg_to_rad(abs(speed) * 10 * delta))
 +
 + # Umkehrung der Bewegungsrichtung, wenn die X-Position eine bestimmte Grenze erreicht
 + if position.x > 5.0 or position.x < -5.0:
 + speed = -speed
 +</code>
 +
 +Move/rotate a MeshInstance3D
 +<code>
 +extends MeshInstance3D
 +
 +# Geschwindigkeit, mit der das Objekt bewegt wird
 +var speed = 5.0
 +
 +func _process(delta):
 +
 + # Bewegung auf der X-Achse
 + # position.x += speed * delta
 + # oder 
 + translate(Vector3(speed * delta, 0, 0))
 +
 + # Bewegung auf der Z-Achse
 + # position.z += speed * delta
 + # oder 
 + translate(Vector3(0, 0, speed * delta))
 +
 + # Rotation um die X-Achse
 + # rotation.x += 10 * deltaTime
 + # oder
 + rotate(Vector3(1, 0, 0), deg_to_rad(abs(speed) * 10 * delta))
 +
 + # Rotation um die Z-Achse
 + #rotation.z += 10 * deltaTime
 + # oder
 + rotate(Vector3(0, 0, 1), deg_to_rad(abs(speed) * 10 * delta))
 +
 + # Umkehrung der Bewegungsrichtung, wenn die X-Position eine bestimmte Grenze erreicht
 + if position.x > 5.0 or position.x < -5.0:
 + speed = -speed
 +</code>
 +
 +====Raycast2D====
 +
 +<code>
 +extends Raycast2D
 +
 +var raycast_length = 10.0 
 +
 +func _ready():
 +    raycast.target_position = Vector2(0, raycast_length)
 +    raycast.enabled = true
 +
 +func _physics_process(delta):
 +    if is_colliding():
 +        print("Der Raycast kollidiert.")
 +    else:
 +        print("Der Raycast kollidiert nicht.")
 +</code>
 +
 +<code>
 +extends CharacterBody2D
 +
 +var raycast_length = 10.0 
 +var raycast: RayCast2D
 +
 +func _ready():
 +    raycast = RayCast2D.new()
 +    raycast.target_position = Vector2(0, raycast_length)
 +    raycast.enabled = true
 +    add_child(raycast)
 +
 +func _process(delta):
 +    if raycast.is_colliding():
 +        print("Der Raycast kollidiert.")
 +    else:
 +        print("Der Raycast kollidiert nicht.")
 +</code>
 +
 +====Raycast3D====
 +
 +Der Raycast3D-Node muss zuerst im Scenetree hinzugrfügt werden. Z.B als Child der Camera.
 +
 +<code>
 +extends RayCast3D
 +
 +# Called when the node enters the scene tree for the first time.
 +func _ready():
 +    pass # Replace with function body.
 +
 +
 +# Called every frame. 'delta' is the elapsed time since the previous frame.
 +func _process(delta):
 +
 +    # get_collision_point()
 +    # get_collider()
 +    
 +    if is_colliding():
 +        var length = (get_parent().global_position - get_collider().global_position).length()
 +        print("colliding with ", get_collider(), " at position ", get_collider().global_position, " at a dist of ", length)
 +        
 +</code>
 +
 +<code>
 +func shoot():
 +    var space = get_world_3d().direct_space_state
 +    var query = PhysicsRayQueryParameters3D.create(
 +    global_position,
 +    global_position - global_transform.basis.z * 2
 +    )
 +    var collision = space.intersect_ray(query)
 +    if collision:
 +        print(collision.collider.name)
 +</code>
 +=====Signals=====
 +
 +<code>
 +func _on_body_entered(body):
 +    print("on_body_entered:", body.name)
 +
 +func _on_body_exited(body):
 +    print("on_body_exited:", body.name)
 +</code>
 +
 +Um Funktionen im Script mit Signalen aus der Engine zu verknüpfen, Doppelklick auf das entsprechende Signal.
 +
 +{{signals.png}}
 +
 +=====Colission=====
 +
 +3D Kolissionen
 +<code>
 +func _process(delta):
 + var space_state = get_world_3d().direct_space_state
 + var transform = global_transform
 + var query = PhysicsShapeQueryParameters3D.new()
 + query.shape = collision_shape.shape
 + query.transform = transform
 + var results = space_state.intersect_shape(query)
 + for result in results:
 + if result.collider:
 + print("Kollision mit:", result.collider.name)
 +</code>
 +
 +=====Area=====
 +
 +Signale setzen!
 +
 +<code>
 +extends Area2D
 +# or
 +# extends Area3D
 +
 +# Wenn 2 Areas überlappen
 +func _on_area_entered(area):
 + print("on_area_entered:", area.name)
 +
 +# Wenn 2 Areas nicht mehr überlappen
 +func _on_area_exited(area):
 + print("on_area_exited:", area.name)
 +
 +# Wenn eine Area und ein Node überlappen
 +func _on_body_entered(body):
 + print("on_body_entered:", body.name)
 +
 +# Wenn eine Area und ein Node nicht mehr überlappen
 +func _on_body_exited(body):
 + print("on_body_exited:", body.name)
 +
 +# Teste ob ein Player in der Box ist
 +func is_player_in_box():
 + var bodies = get_overlapping_bodies()
 + for body in bodies:
 + if body.name == "CharacterBody3D": 
 + return true
 + return false
 +
 +func _process(delta):
 + if is_player_in_box():
 + print("player is in the box")
 +</code>
 +
 +=====CameraController=====
 +
 +<code>
 +extends Camera3D
 +
 +@export var move_speed: float = 10.0
 +@export var mouse_sensitivity: float = 0.1
 +
 +var rotation_x: float = 0.0
 +var rotation_y: float = 0.0
 +
 +func _ready():
 + Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
 +
 +func _process(delta: float):
 + handle_movement(delta)
 +
 +func _input(event: InputEvent):
 + if event is InputEventMouseMotion:
 + handle_mouse_rotation(event.relative)
 +
 + if Input.is_action_just_pressed("Escape"): 
 + if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
 + Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
 + else:
 + Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
 +
 +func handle_movement(delta: float):
 + var velocity = Vector3.ZERO
 + if Input.is_action_pressed("move_forward"):
 + velocity -= transform.basis.z
 + if Input.is_action_pressed("move_backward"):
 + velocity += transform.basis.z
 + if Input.is_action_pressed("move_left"):
 + velocity -= transform.basis.x
 + if Input.is_action_pressed("move_right"):
 + velocity += transform.basis.x
 + if velocity != Vector3.ZERO:
 + velocity = velocity.normalized() * move_speed * delta
 + global_transform.origin += velocity
 +
 +func handle_mouse_rotation(mouse_motion: Vector2):
 + rotation_y -= mouse_motion.x * mouse_sensitivity
 + rotation_x -= mouse_motion.y * mouse_sensitivity
 + rotation_x = clamp(rotation_x, -90.0, 90.0)
 + rotation_degrees = Vector3(rotation_x, rotation_y, 0.0)
 +</code>
 +
 +<code>
 +extends Node3D
 +
 +@export var move_speed: float = 10.0
 +@export var mouse_sensitivity: float = 0.1
 +
 +var rotation_x: float = 0.0
 +var rotation_y: float = 0.0
 +var camera: Camera3D = null
 +
 +func _ready():
 + camera = Camera3D.new()
 + camera.current = true 
 + add_child(camera)
 + Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
 +
 +func _process(delta: float):
 + if camera:
 + handle_movement(delta)
 +
 +func _input(event: InputEvent):
 + if event is InputEventMouseMotion:
 + handle_mouse_rotation(event.relative)
 +
 + if Input.is_action_just_pressed("Escape"): 
 + if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
 + Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
 + else:
 + Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
 +
 +func handle_movement(delta: float):
 + var velocity = Vector3.ZERO
 + if Input.is_action_pressed("move_forward"):
 + velocity -= camera.transform.basis.z
 + if Input.is_action_pressed("move_backward"):
 + velocity += camera.transform.basis.z
 + if Input.is_action_pressed("move_left"):
 + velocity -= camera.transform.basis.x
 + if Input.is_action_pressed("move_right"):
 + velocity += camera.transform.basis.x
 + if velocity != Vector3.ZERO:
 + velocity = velocity.normalized() * move_speed * delta
 + camera.global_transform.origin += velocity
 +
 +func handle_mouse_rotation(mouse_motion: Vector2):
 + if not camera:
 + return
 + rotation_y -= mouse_motion.x * mouse_sensitivity
 + rotation_x -= mouse_motion.y * mouse_sensitivity
 + rotation_x = clamp(rotation_x, -90.0, 90.0)
 + camera.rotation_degrees = Vector3(rotation_x, rotation_y, 0.0)
 +</code>
 +
 +=====CharacterBody=====
 +
 +====CharacterBody2D====
 +<code>
 +extends CharacterBody2D
 +
 +@onready var collision_shape = $CollisionShape2D
 +
 +var gravity = ProjectSettings.get_setting("physics/2d/default_gravity") 
 +var speed = 50
 +
 +func _physics_process(delta):
 + var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
 + if direction:
 + velocity = direction * speed
 + else:
 + velocity.x = move_toward(velocity.x, 0, speed)
 + velocity.y = move_toward(velocity.y, 0, speed)
 + velocity.y += gravity * delta
 +
 + move_and_slide()
 + #move_and_collide(velocity)
 +
 + #check_collision()
 + var collisions = get_slide_collision_count()
 + if collisions:
 + for collision in collisions:
 + print(get_slide_collision(collision))
 +
 + if $RayCast2D.is_colliding():
 + print("[CharacterBody2D:raycast] Raycast colliding");
 +
 +func check_collision():
 + var space_state = get_world_2d().direct_space_state
 + var transform = global_transform
 + var query = PhysicsShapeQueryParameters2D.new()
 + query.shape = collision_shape.shape
 + query.transform = transform
 + var results = space_state.intersect_shape(query)
 + for result in results:
 + if result.collider and result.collider.name != "CharacterBody2D":
 + print("[CharacterBody2D:intersect_shape] Kollision mit:", result.collider.name)
 +</code>
 +
 +====CharacterBody3D====
 +
 +Player Controller
 +
 +<code>
 +extends CharacterBody3D
 +
 +@onready var head = $SpringArm3D/Head
 +@onready var collision_shape = $CollisionShape3D  
 +@onready var camera = $SpringArm3D/Head
 +
 +var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
 +var speed = 4.0  
 +var jump_speed = 6.0
 +var mouse_sensitivity = 0.002  
 +var vertical_angle = 0.0
 +
 +var is_crouching = false
 +var crouch_height = 0.5 
 +var standing_height = 1.8 
 +
 +func _ready():
 + Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
 +
 +func shoot():
 + var space = get_world_3d().direct_space_state
 + var query = PhysicsRayQueryParameters3D.create(
 + head.global_position,
 + head.global_position - head.global_transform.basis.z * 2
 + )
 + var collision = space.intersect_ray(query)
 + if collision:
 + print(collision.collider.name)
 +
 +func get_input():
 + shoot()
 + var input = Input.get_vector("move_left", "move_right", "move_forward", "move_backward")
 + var movement_dir = transform.basis * Vector3(input.x, 0, input.y)
 + velocity.x = movement_dir.x * speed
 + velocity.z = movement_dir.z * speed
 + if Input.is_action_just_pressed("crouch") and is_on_floor():
 + toggle_crouch()
 + if Input.is_action_just_pressed("Escape"):
 + if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
 + Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
 + else:
 + Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
 + if Input.is_action_pressed("jump") and is_on_floor():
 + velocity.y = jump_speed
 +
 +func _process(delta):
 + pass #check_collision()
 +
 +func check_collision():
 + var space_state = get_world_3d().direct_space_state
 + var transform = global_transform
 + var query = PhysicsShapeQueryParameters3D.new()
 + query.shape = collision_shape.shape
 + query.transform = transform
 + #query.collide_with_areas = true  # Nur Areas berücksichtigen
 + var results = space_state.intersect_shape(query)
 + for result in results:
 + if result.collider:
 + print("Kollision mit:", result.collider.name)
 +
 +
 +func _physics_process(delta):
 + velocity.y += -gravity * delta
 + get_input()
 + move_and_slide()
 +
 +func toggle_crouch():
 + if is_crouching:
 + is_crouching = false
 + collision_shape.shape.height = standing_height
 + head.position.y = standing_height  # Kamera anpassen
 + else:
 + is_crouching = true
 + collision_shape.shape.height = crouch_height
 + head.position.y = crouch_height  # Kamera anpassen
 +
 +func _unhandled_input(event):
 + if event is InputEventMouseMotion:
 + # Horizontale Charakterrotation (um die y-Achse)
 + rotate_y(-event.relative.x * mouse_sensitivity)
 + # Vertikale Kamerarotation (um die x-Achse des SpringArm3D)
 + vertical_angle -= event.relative.y * mouse_sensitivity
 + vertical_angle = clamp(vertical_angle, -PI / 2, PI / 2)  # Begrenzung der vertikalen Rotation auf +-90°
 + head.rotation.x = vertical_angle
 +</code>
 +
 +Plane Controller
 +<code>
 +extends CharacterBody3D
 +
 +@export var maxSpeed :float = 1.0
 +@export var turnRate :float = 0.1
 +@onready var Gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
 +
 +var Speed = 0.0
 +
 +func _physics_process(delta):
 + _rotate()
 + if Input.is_action_just_pressed("move_forward") and (Speed <= maxSpeed):
 + Speed += 1.0
 + if Input.is_action_just_pressed("move_backward"):
 + if (Speed >= 1.0):
 + Speed -= 1.0
 + else:
 + Speed = 0.0
 + if (Speed > 0.0):
 + global_translate(transform.basis.z)
 + move_and_slide()
 +
 +func _rotate():
 + var yaw = Input.get_axis("move_right", "move_left") # Y Axis
 + var roll = Input.get_axis("ui_left", "ui_right") # Z Axis
 + var pitch = Input.get_axis("ui_down", "ui_up") # X Axis
 + var direction = Vector3(pitch, yaw, roll) * turnRate
 + if direction: 
 + var a = Quaternion(transform.basis.from_euler(rotation))
 + var b = Quaternion(transform.basis.from_euler(direction))
 + transform.basis = Basis(a * b)
 +</code>
 +
 +
 +=====VehicleBody3D=====
 +
 +<code>
 +extends VehicleBody3D
 +
 +var steering_smoothness : float = 5.0  # Steuerungsdämpfung
 +
 +func _physics_process(delta: float) -> void:
 +    var target_steering = Input.get_axis("move_right", "move_left") * 0.5
 +    var target_engine_force = Input.get_axis("move_backward", "move_forward") * 80
 +
 +    # Steuerung anwenden (sanft interpolieren)
 +    steering = lerp(steering, target_steering, steering_smoothness * delta)
 +
 +    engine_force = target_engine_force
 +
 +    for child in get_children():
 +        if child is VehicleWheel3D:
 +            if child.steering:
 +                child.set_steering(steering)
 +            else:
 +                child.engine_force = engine_force
 +</code>
 +
 +
 +=====Networking=====
 +
 +====RPC====
 +
 +[[https://www.youtube.com/watch?v=frjU-WC_pwg|Youtube]]
 +
 +<code>
 +func _process():
 +    rpc("rpc_function") # will transfer reliable
 +    rpc_unreliable("rpc_function") # will transfer unreliable
 +    rpc_function.rpc()
 +    rpc_function.rpc_id(peer_id) # call it on a specified peer
 +    
 +@rpc(mode, sync, transfer, channel)
 +func rpc_function():
 +    var sender = multiplayer.get_remote_sender_id()
 +    if sender == get_multiplayer_authority():
 +        do_stuff()
 +</code>
 +
 +===Mode===
 +
 +Von wem kann die Funktion ausgeführt werden. Default ist "authority". Man kann die Multiplayer Authority mit der Funktion
 +
 +<code>
 +Node.set_multiplayer_authority()
 +</code>
 +
 +auf einer per-Peer-Basis konfigurieren.
 +
 +  * authority: Funktion kann **nur von dem Peer der die Multiplayer Authority hat** ausgeführt werden, nicht von anderen peers
 +  * any_peer: Funktion kann **von jedem peer** ausgeführt werden
 +
 +===Sync===
 +
 +Wo wird die Funktion ausgeführt. Nur remote oder auch lokal.
 +
 +  * call_remote: Funktion kann **nur Remote** ausgeführt werden
 +  * call_local: Funktion wird beim Aufruf **remote und auch lokal** ausgeführt
 +
 +===Transfer===
 +
 +  * unreliable: UDP
 +  * unreliable_ordered: UDP
 +  * reliable: TCP
 +
 +===Channel===
 +
 +Muss immer das letzte Argument sein.
 +=====Links=====
 +
 +  * [[https://www.youtube.com/watch?v=BUjCtwLO0S8|Level/Map Editor]]
 +  * [[https://www.youtube.com/watch?v=NlzTmL_eB-U|Learn Godot in 90 Minutes]]
 +  * [[https://www.youtube.com/watch?v=sVsn9NqpVhg|Make your first 3D Platformer in Godot 4: Setup, Movement, and Camera Controls]]
 +  * [[https://www.youtube.com/watch?v=v4IEPi1c0eE|Simple 3d movement]]
 +  * [[https://www.youtube.com/watch?v=Wj1FfilAe2Y|Godot 4 VehicleBody3d Tutorial]]
 +  * [[https://www.youtube.com/watch?v=xIKErMgJ1Yk|First Person CharacterController]]
 +  * [[https://www.youtube.com/watch?v=h8BmeRRGWxI|First-Person Shooter in Godot 4.0 - Overview]]
 +  * [[https://www.youtube.com/watch?v=4nOEVPjVmjc|Bezier Curves und Splines]]
 +  * [[https://github.com/TheDuckCow/godot-road-generator|Godot Road Generator AddOn]]
 +  * [[https://www.youtube.com/watch?v=n8D3vEx7NAE|Godot Multiplayer FPS Tutorial + project source]]
 +  * [[https://www.youtube.com/watch?v=_ItA2r69c-Q|Godot 4 Makes Multiplayer EASY!]]
 +  * [[https://www.youtube.com/watch?v=K62jDMLPToA|ENet Multiplayer in 3 Minutes]]
 +  * [[https://github.com/mohsenph69/Godot-MTerrain-plugin|MTerrain Plugin]]
 +  * [[https://www.youtube.com/watch?v=s1s1zdTGliQ|MTerrain Curve Deformation]]
godot.txt · Zuletzt geändert: 2026/11/04 13:59 von jango