Dies ist eine alte Version des Dokuments!
Godot ist eine kostenlose Open Source Game Engine unter MIT Lizenz.
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:
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
# 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)
Move/rotate a Node3D
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
Move/rotate a MeshInstance3D
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
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 is_on_ground(): return raycast.is_colliding() func _physics_process(delta): if is_on_ground(): print("Der Spieler steht auf dem Boden.") else: print("Der Spieler ist in der Luft.")
Der Raycast3D-Node muss zuerst im Scenetree hinzugrfügt werden. Z.B als Child der Camera.
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)
func _on_body_entered(body): print("on_body_entered:", body.name) func _on_body_exited(body): print("on_body_exited:", body.name)
Um Funktionen im Script mit Signalen aus der Engine zu verknüpfen, Doppelklick auf das entsprechende Signal.
3D Kolissionen
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)
Signale setzen!
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")
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)
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)
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)
Player Controller
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
Plane Controller
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)
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