Benutzer-Werkzeuge

Webseiten-Werkzeuge


godot

Dies ist eine alte Version des Dokuments!


Godot ist eine kostenlose Open Source Game Engine unter MIT Lizenz.

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

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

Button

func _on_button_pressed(extra_arg_0, extra_arg_1):
	print(extra_arg_0 + extra_arg_1)

GDScript

Instantiation

# 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)

Movement

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

Raycast2D

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.")

Raycast3D

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)
        

Signals

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.

Colission

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)

Area

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")

CameraController

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)

CharacterBody

CharacterBody2D

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)

CharacterBody3D

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)

VehicleBody3D

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
godot.1735996883.txt.gz · Zuletzt geändert: 2025/01/04 14:21 von jango