GAKI

05 Typische Probleme

Yannik Brändle - WS25/26

TH Bingen

Hochschulkalenderplan
Grün == Normalbetrieb | Gelb == Projekttermine

Problem 1: Bei duplicate sind gewisse Dinge Linked

Warum???

  • eine Node liefert Funktionalität
  • eine Ressource ist ein Datencontainer
  • Ressourcen werden von Godot nur einmalig geladen und immer wieder refernziert

Vorteile

  • Weniger Datenredundanz
  • Die Möglichkeit mehrere Instanzen "for free" zu haben

Nachteile

  • Bei Kopien oder Duplikaten muss man erstmal die Ressourcen unique machen
  • Nicht wirklich das intuitive Verhalten

Wozu .tres benutzen?

  • Austauschbare Einstellungen von Objekten (siehe Laser/Raketen von E02)
  • Feste Infos die sich nicht oft verändern
    • Materialien
    • Meshes
    • Texturen
    • ...

Floating Point error

(Epilepsiewarnung: Nächste Folie enhtält rapides blinken)

Floating Point error demo

(Epilepsiewarnung: Diese Folie enhtält rapides blinken)

Floating Point error Erklärung

Bei "nur" 72km

Bei 500.000km

  • float hat eine begrenzte Auflösung
  • bei gewissen Schritten kommt es zu den klassischen "floating point error"
  • ganz kleine Zahl addieren macht ggf nichts durch fehler
  • → bei großer Zahl macht das addieren kleiner Zahlen nichts

Lösung?

  • Skalierung des Spiels verändern und Distanz faken
  • Wechseln in lokale Szenen und nur so tun als wäre alles beisammen
  • (Beispiel Outer Wilds:) Welt bewegen und nicht den Spieler
    • → Problem nicht wirklich gelöst
    • → Camera ist aber immer beim Spieler bei (0,0) und "kriegt es nicht mit"
  • Man kann Godot auch mit double precision compilen, verschiebt Problem aber nur

Problem: Rigidbody Clipping

Problem: Rigidbody Clipped durch andere Collider bei hohen geschwindigkeiten

Lösung: CCD (Continous Collision Detection)

Erklärung an Beispiel: Collision berechnung bei SM64

pannenkoek2012: A Press Challenge SM64 - Watch for Rolling Rocks: https://youtu.be/kpk2tdsPh0A

"Forward" Vektoren

Bewegung in Richtung "Forward" (Vector2.UP)

              func _physics_process(delta):
  position.y += -60 * delta
  rotation += 1 * delta
            

Bewegung in lokale UP Richtung

                func _physics_process(delta):
  position += transform.y * -60 * delta
  rotation += 1 * delta
                

In 3D sehr ähnlich mit der basis:

              position += -transform.basis.z * 60 * delta
            

Gamedev Mathe 👀

  • LERP == Linear Interpolation
    • Nützlich um etwas smooth von A nach B zu animieren/bewegen
    • Passiert im Prinzip ständig im Hintergrund
  • Vector Rechnungen

Problem: Schussbahnen ausrechnen und Geschoss animieren

Spiel: Baloon Bonanza

Teilproblem:

Wo ist der Gegner wenn das Geschoss ankommt?

Ansatz:

  • Gegner geschwindigkeit abrufen
  • Gegner Pfad position abrufen
  • Gegner Pfad position + geschwindigkeit * bullet flugzeit
  • Problem: Bullet flugzeit ist abhängig von ausgerechneter Distanz
  • Annäherung: Iterativ öfter drüberrechnen
              
func calculate_lead_aim(from: Vector3, bullet_speed: float, iterations: int = 1) -> Vector3:
	assert(target != null)
	var target_position = target.global_position
	for i in range(iterations):
		var distance = from.distance_to(target_position)
		var time = distance / bullet_speed
		var target_progress = target.progress + target.settings.speed * time * target.speed_mult
		# check if target is overflowing the path
		if target_progress > target.parent_path.curve.get_baked_length():
			target_progress = target.parent_path.curve.get_baked_length()
		target_position = target.parent_path.curve.sample_baked(target_progress)
         ↷ + target.parent_path.global_position
	# t_cl.global_position = target_position
	return target_position
            

LERP - Linear Interpolation

Freye Holmér - The Beauty of Bézier Curves: https://youtu.be/aVwxzDHniEw

Bézier Curves

Freye Holmér - The Beauty of Bézier Curves: https://youtu.be/aVwxzDHniEw

Lösung für Flugbahnberechnung:

  • Start und Endpunkt stehen fest
  • zwei Punkte bei 25% und 75% festlegen
  • beide jeweils um die halbe distanz nach Vector3.UP verschieben
  • Cubic Bézier curve samplen während der Flugbahn und am Ende explodieren
              func shoot_bomb(target_pos: Vector3, tof: float, damage: float):
	var bomb = bullet.instantiate() as Bomb
	get_parent().add_child(bomb)
	bomb.global_position = cannon_node.global_position
	var p1 = cannon_node.global_position
	var p4 = target_pos
	var dist = p1.distance_to(p4)
	var p2 = (p1+(p4-p1)*0.25)
	p2.y += dist*0.5
	var p3 = (p1+(p4-p1)*0.75)
	p3.y += dist*0.5
	bomb.shoot(p1, p2, p3, p4, tof, damage)
            

Speed quiz: Vector Mathe

Folgende Bilder von Wikipedia (english) von Euclidean Vector

https://en.wikipedia.org/wiki/Euclidean_vector

Frage: Zwei Vektoren addieren?

Antwort: $\vec{a} + \vec{b} = \vec{c}$

In Godot: vecc = veca + vecb

Frage: Richtung und Distanz von A nach B?

Antwort: $\vec{a} - \vec{b} = \vec{c}$

In Godot: vecc = veca - vecb

Frage: Einen Vektor mit einem Skalar skalieren?

Antwort: $k \cdot \vec{v} = \vec{w}$

In Godot: myvec * 5

Frage: Die Länge eines Vektors berechnen?

Antwort: $|\vec{v}| = \sqrt{v_x^2 + v_y^2 + v_z^2}$

In Godot: myvec.length()

(Oder myvec.length_squared() bei Vergleichen für Performance)

Frage: Einen Vektor in einen Einheitsvektor umwandeln?

Antwort: $\hat{v} = \frac{\vec{v}}{|\vec{v}|}$

In Godot: myvec.normalized()

Frage: Den Winkel zwischen zwei Vektoren berechnen?

Antwort: $\vec{a} \cdot \vec{b} = |\vec{a}||\vec{b}|\cos\theta \quad \Rightarrow \quad \theta = \cos^{-1}\left(\frac{\vec{a} \cdot \vec{b}}{|\vec{a}||\vec{b}|}\right)$

In Godot: angle = vecA.angle_to(vecB)

(Dot product!)

Frage: Einen Vektor finden, der senkrecht zu zwei gegebenen Vektoren im 3D-Raum ist? (Stichwort: normal)

Antwort: $\vec{a} \times \vec{b} = \vec{n}$

In Godot: normal = vecA.cross(vecB)

Empfehlung als Mathe refresher wenn sinnvoll:

Freya Holmér - Vectors & Dot Product • Math for Game Devs [Part 1] https://youtu.be/MOYiVLEnhrw

Achtung: 3h lang, aber gut erklärt

FIN