Game Engine Math

KWEngine, Teil 20: Sichtbereiche von Objekten

Fall #1: Blickt eine Spielfigur direkt auf ein Objekt?

Beispiel: Look-At-Vector schneidet gegnerische Hitbox

Mit der Methode IsLookingAt() kann eine Spielfigur prüfen, ob ihr Look-At-Vector (kurz: LAV) durch die (für den Test kugelförmige) Hitbox einer anderen Spielfigur verläuft:

public class Player : GameObject
{
    public override void Act()
    {
        // Angenommen, die Spielfigur sucht den Gegner "Hans":
        Enemy e = CurrentWorld.GetGameObjectByName<Enemy>("Hans");

        // Wenn der Gegner mit diesem Namen in der Welt existiert, 
        // dann enthält die Variable e nun dieses Objekt und ist somit
        // 'ungleich null' (null bedeutet: leer):
        if(e != null)
        {
            bool result = IsLookingAt(
                e.Center,       // Mittelpunkt von Hans
                1.5f);          // Durchmesser der Testkugel
            if(result == true)
            {
                // Spielfigur blickt auf das Enemy-Objekt
            }
        }
    }
}

Fall #2: Befindet sich ein Gegner im Sichtfeld?

Ist der Winkel (rot) zwischen LAV (blau) und der Luftlinie zwischen Spielfigur und Gegner (grün) klein genug, befindet sich der Gegner in deren Sichtfeld.

Um den Winkel auszurechnen benötigt man folgende Formel:

using System;
using KWEngine3;
using KWEngine3.GameObjects;
using KWEngine3.Helpers;
using OpenTK.Mathematics;

public class Player : GameObject
{
    public override void Act()
    {
        // Und wieder einmal "Hans":
        Enemy e = CurrentWorld.GetGameObjectByName<Enemy>("Hans");
        
        // Luftlinie zwischen Spielfigur und Hans berechnen (grüner Pfeil):
        Vector3 luftlinie = e.Center - this.Center;

        // Look-At-Vektor der Spielfigur (blauer Pfeil):
        Vector3 lav = this.LookAtVector;

        // Math.Acos() berechnet den Arcuscosinus im Bogenmass statt in Grad:
        double winkelImBogenmass = Math.Acos(
                Vector3.Dot(lav, luftlinie) / (lav.Length * luftlinie.Length)
            );

        // Deshalb müssen wir hier noch in Grad umrechnen:
        double winkelInGrad = MathHelper.RadiansToDegrees(winkelImBogenMass);
        
        if(winkelInGrad <= 50)
        {
            // Gegner befindet sich im 100° Sichtfeld der Spielfigur
        }
    }
}

Beitrag veröffentlicht

in

von

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.