extends CharacterBody3D class_name Player ## Ein Wesen aus der Traumwelt. In der Traumwelt läuft es, auf der Erde schwebt ## es als unsichtbarer Geist durch Wände. enum Mode { TRAUM, GEIST } const SPEED_TRAUM := 8.0 const SPEED_GEIST := 11.0 const GRAVITY := 24.0 const JUMP := 9.0 const MAUS := 0.0026 var mode: int = Mode.TRAUM var yaw := 0.0 var pitch := -0.25 var look_enabled := true var pivot: Node3D var arm: SpringArm3D var cam: Camera3D var body: Node3D var _kern: MeshInstance3D var _ringe: Array = [] func _ready() -> void: var cs := CollisionShape3D.new() var shape := CapsuleShape3D.new() shape.radius = 0.45 shape.height = 1.9 cs.shape = shape cs.position.y = 0.95 add_child(cs) body = Node3D.new() add_child(body) _kern = Prims.capsule(body, Vector3(0, 1.0, 0), 0.42, 1.6, Color(0.55, 0.85, 1.0)) _kern.material_override = Prims.mat(Color(0.55, 0.85, 1.0), 0.9) var kopf := Prims.sphere(body, Vector3(0, 2.0, 0), 0.28, Color(0.80, 0.92, 1.0), 0.6) kopf.name = "Kopf" for i in range(2): var r := Prims.cyl(body, Vector3(0, 0.5 + i * 0.9, 0), 0.75 + i * 0.15, 0.06, Color(0.6, 0.9, 1.0), false, 1.6) r.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF _ringe.append(r) # kleiner Blick nach vorn, damit man die Laufrichtung sieht Prims.box(body, Vector3(0, 1.55, -0.36), Vector3(0.5, 0.12, 0.12), Color(1, 1, 1), false, 2.0) pivot = Node3D.new() pivot.position.y = 1.5 add_child(pivot) arm = SpringArm3D.new() arm.position.x = 0.75 arm.spring_length = 6.5 arm.margin = 0.3 pivot.add_child(arm) cam = Camera3D.new() cam.fov = 74.0 arm.add_child(cam) set_mode(Mode.TRAUM) func set_mode(m: int) -> void: mode = m if m == Mode.GEIST: collision_layer = 0 collision_mask = 0 arm.collision_mask = 0 arm.spring_length = 5.0 pivot.position.y = 2.1 body.scale = Vector3.ONE * 0.72 _kern.material_override = Prims.mat(Color(0.65, 0.9, 1.0, 0.26), 0.5) for r in _ringe: r.material_override = Prims.mat(Color(0.7, 0.95, 1.0, 0.20), 0.8) r.scale = Vector3(0.55, 1.0, 0.55) else: collision_layer = 1 collision_mask = 1 arm.collision_mask = 1 arm.spring_length = 6.5 pivot.position.y = 1.5 body.scale = Vector3.ONE _kern.material_override = Prims.mat(Color(0.55, 0.85, 1.0), 0.9) for r in _ringe: r.material_override = Prims.mat(Color(0.6, 0.9, 1.0), 1.6) r.scale = Vector3.ONE velocity = Vector3.ZERO func _unhandled_input(event: InputEvent) -> void: if not look_enabled: return if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED: yaw -= event.relative.x * MAUS pitch = clampf(pitch - event.relative.y * MAUS, -1.3, 0.6) func _physics_process(delta: float) -> void: pivot.rotation.y = yaw arm.rotation.x = pitch for i in range(_ringe.size()): var r: MeshInstance3D = _ringe[i] r.rotation.y += delta * (0.8 + 0.5 * i) r.position.y = 0.5 + i * 0.9 + sin(Time.get_ticks_msec() * 0.001 * (1.2 + i * 0.4)) * 0.12 var input := Vector2.ZERO if look_enabled: input.x = Input.get_axis("links", "rechts") input.y = Input.get_axis("vor", "zurueck") var dir := Vector3.ZERO if input.length() > 0.01: var basis_yaw := Basis(Vector3.UP, yaw) dir = (basis_yaw * Vector3(input.x, 0, input.y)).normalized() if mode == Mode.GEIST: var v := dir * SPEED_GEIST if look_enabled: if Input.is_action_pressed("steigen"): v.y += SPEED_GEIST * 0.75 if Input.is_action_pressed("sinken"): v.y -= SPEED_GEIST * 0.75 velocity = velocity.lerp(v, 1.0 - pow(0.001, delta)) move_and_slide() if global_position.y < 0.4: global_position.y = 0.4 if global_position.y > 45.0: global_position.y = 45.0 else: velocity.x = lerpf(velocity.x, dir.x * SPEED_TRAUM, 1.0 - pow(0.0005, delta)) velocity.z = lerpf(velocity.z, dir.z * SPEED_TRAUM, 1.0 - pow(0.0005, delta)) if is_on_floor(): if look_enabled and Input.is_action_pressed("steigen"): velocity.y = JUMP else: velocity.y = -1.0 else: velocity.y -= GRAVITY * delta move_and_slide() if global_position.y < -400.0: global_position.y = 2.0 if dir.length() > 0.01: var ziel := atan2(-dir.x, -dir.z) body.rotation.y = lerp_angle(body.rotation.y, ziel, 1.0 - pow(0.0005, delta)) func blickrichtung() -> Vector3: return -Vector3(sin(yaw), 0, cos(yaw))