Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Martin Mundorf

Treue Seele

  • »Martin Mundorf« ist der Autor dieses Themas

Beiträge: 262

Wohnort: Waldorf, Kr. Ahrweiler

Beruf: Althistoriker

  • Private Nachricht senden

11

17.11.2017, 15:11

:wacko:


ich verzweifel wirklich... habe nun für einen nichtmenschlichen Bot eine KI geschrieben -
es funktioniert auch:

patroullieren: check.
wenn Ziel gesichtet, verfolgen: check.
wenn Ziel tot, zurück in den patrol-Status: check.

Aber dann findet der Durchlauf durch die Wegpunkte nicht mehr statt. Er bleibt einfach am nächsten Wegpunkt stehen.

Ich hoffe dieser Code-Ausschnitt (nur so ca 120 Zeilen) ist übersichtlich und für eure Augen ordentlich genug.
Ich finde diesen verka.... Fehler nicht ;( ;( ;(

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
void Start()
    {
        
        navigation.agent = this.GetComponent <NavMeshAgent > ();
        gun.timerB = gun.timer;
        navigation.agent.updatePosition = true;
        navigation.agent.updateRotation = true;  // tut= false;
        zustand.zstd = Hogan1.Zustand.ZSTD.PATROL;
        aktiv = true;
        StartCoroutine ("FSM");

    }

    IEnumerator FSM()
    {
        while (aktiv) 
        {
            switch (zustand.zstd) 
            {
            case Zustand .ZSTD .PATROL:
                Patrol ();
                break;
            case Zustand .ZSTD .CHASE:
                Chase ();
                break;
            }
            yield return null;
        }


    }

    void Update()
    {
        if (!navigation.on_hunt) 
        {
            RaycastHit hit;
            Vector3 dir = this.transform.forward;

            if (Physics.Raycast (gun.Mündung.position, dir, out hit, navigation.Sichtweite)) 
            {
                if (hit.transform.CompareTag ("Player") || hit.transform.CompareTag ("Humanoid")) 
                {
                    if (hit.transform.GetComponent <CharacterStats > ().egS.team.ToString () != set.team.ToString ()) 
                    {
                        zustand.zstd = Hogan1.Zustand.ZSTD.CHASE;
                        navigation.Ziel = hit.transform;
                        navigation.on_hunt = true;
                    } 

                } 

            }
        }
    }


    void Patrol()
    {
        navigation.agent.speed = waypoint_mngr.patrolSpeed;



        if (Vector3.Distance (this.transform .position , waypoint_mngr.waypoints [waypoint_mngr .WP_inx].transform .position ) >= 2) // zu weit
        {
            navigation.agent.SetDestination (waypoint_mngr .waypoints [waypoint_mngr .WP_inx ].transform .position );
        }
        else if  (Vector3.Distance (this.transform .position , waypoint_mngr.waypoints [waypoint_mngr .WP_inx].transform .position ) <= 2 ) // zu nah
        {
            waypoint_mngr.WP_inx += 1;
                if (waypoint_mngr.WP_inx > waypoint_mngr.waypoints.Length - 1) 
            {
                    waypoint_mngr.WP_inx = 0;
            }
        }

    }


    void Chase()
    {
        if (navigation.Ziel.GetComponent <CharacterStats> ().egS.health <= 0) 
        {

            Debug.Log ((Vector3.Distance (this.transform.position, waypoint_mngr.waypoints [waypoint_mngr.WP_inx].transform.position)));
            navigation.agent.SetDestination (waypoint_mngr .waypoints [waypoint_mngr .WP_inx ].transform .position );
            navigation.on_hunt = false;
            zustand.zstd = Hogan1.Zustand.ZSTD.PATROL;
            Patrol ();
            navigation.agent.speed = waypoint_mngr.patrolSpeed;
            return;
        } 
        else 
        {
            navigation.distance = Vector3.Distance (navigation.Ziel.position, this.transform.position);
            navigation.agent.stoppingDistance = navigation.Stop_at;
            navigation.agent.speed = navigation.movSPD;
            navigation.agent.SetDestination (navigation.Ziel.position);

        
            if (navigation.distance < navigation.Sichtweite && navigation.distance > navigation.agent.stoppingDistance)
    
            gun.timerB -= Time.deltaTime;
            if (gun.timerB <= 0) 
            {
                if (gun.Vorrat > 0)
                {
                    Feuer ();
                    gun.Vorrat--;
                }
                gun.timerB = gun.timer;
            }
        }
    }
"Eine Signatur ist das Buchstaben-Zahlen-Zettelchen unten an ein einem Buch in der Bibliothek!"



was ich zur Zeit ausprobiere: 3rd person Shooter <- hierfür suche ich noch Unterstützung.


"Lehrjahre": Im Lande der Hasen
mein ewiges Spielprojekt "Straights & Rows".
meine Grafiken "ohne Verwendungszweck"

Martin Mundorf

Treue Seele

  • »Martin Mundorf« ist der Autor dieses Themas

Beiträge: 262

Wohnort: Waldorf, Kr. Ahrweiler

Beruf: Althistoriker

  • Private Nachricht senden

12

17.11.2017, 21:44

:thumbsup: :dash: :thumbsup: :dash: :thumbsup:

also so manchmal wünschte ich, ich wär innerlich ausgeglichener... ich hab tatsächlich "nur" vergessen, an der richtigen Stelle einen Bool zurückzuschalten :golly: :dash: :D

Der "Panzerklein" fährt und folgt jetzt so, wie er soll

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
    void Chase()
    {
        if ((navigation.Ziel.GetComponent <CharacterStats> ().egS.health <= 0) || navigation .Ziel == null || gun.Vorrat ==0) 
        {
            navigation.on_hunt = false;
            navigation.Ziel = null;
            navigation.distance = Vector3.Distance (this.transform.position, waypoint_mngr.waypoints [waypoint_mngr.WP_inx].transform.position);
            zustand.zstd = Hogan1.Zustand.ZSTD.PATROL;
            navigation.agent.SetDestination (waypoint_mngr.waypoints [waypoint_mngr.WP_inx].transform .position );
        
        }
"Eine Signatur ist das Buchstaben-Zahlen-Zettelchen unten an ein einem Buch in der Bibliothek!"



was ich zur Zeit ausprobiere: 3rd person Shooter <- hierfür suche ich noch Unterstützung.


"Lehrjahre": Im Lande der Hasen
mein ewiges Spielprojekt "Straights & Rows".
meine Grafiken "ohne Verwendungszweck"

13

17.11.2017, 22:05

habe nun für einen nichtmenschlichen Bot eine KI geschrieben -

Gibt es auch menschliche bots? :D

Martin Mundorf

Treue Seele

  • »Martin Mundorf« ist der Autor dieses Themas

Beiträge: 262

Wohnort: Waldorf, Kr. Ahrweiler

Beruf: Althistoriker

  • Private Nachricht senden

14

17.11.2017, 22:27

orrr jaa... das ist wie mit dem "wLan-Kabel" :D
...ich meinte damit: keine menschliche Figur, sondern eine Art "Roboter"_Figur ^^
"Eine Signatur ist das Buchstaben-Zahlen-Zettelchen unten an ein einem Buch in der Bibliothek!"



was ich zur Zeit ausprobiere: 3rd person Shooter <- hierfür suche ich noch Unterstützung.


"Lehrjahre": Im Lande der Hasen
mein ewiges Spielprojekt "Straights & Rows".
meine Grafiken "ohne Verwendungszweck"

Martin Mundorf

Treue Seele

  • »Martin Mundorf« ist der Autor dieses Themas

Beiträge: 262

Wohnort: Waldorf, Kr. Ahrweiler

Beruf: Althistoriker

  • Private Nachricht senden

15

03.02.2018, 11:19

Ein paar grundsätzliche Fragen zur KI

Hallo zusammen-anstatt im Projektthread möcht ich hier ein paar Fragen loswerden, die sich um die Funktionalität der KI drehen.

Zu allererst: Es ist mir gelungen, das meine KI in meinem 3D-Projekt sich endlich weitestgehend so verhält wie sie soll. (d.h. animiert wird, sich dreht, geradeaus guckt etc.)

Aber ich habe die Befürchtung, ich "übertreibe" es ein wenig.
So habe ich zB es so eingestellt, das sich die Verbündeten meines Player-Charakters zu diesem hindrehen, wenn er in Sichtweite ist. Soweit so gut.
Wenn aber eine gegnerische KI in Sichtweite ist, dann dreht sie sich dieser zu (und greift diese an). Auch jut.

Beides habe ich an zwei Bedingungen geknüpft: 1. ist Objekt in Sichtweite (Radius Distanz Abfrage) UND 2. schicke ich einen Raycast aus dem Kopf der KI auf den Player / Gegner. Und nur dann, wenn dieser raycast hittet ("Sichtkontakt"), nimmt die KI diese Person wahr.

Jetzt habe ich aber auch noch weiterhin eingebaut "Suche nächsten Verbündeten". Dh. die KI sucht außerdem das nächstgelegene Teammitglied.
(funktioniert nach dem gleichen Prinzip). Die Idee dahinter war, "wenn nächsterVerbündeter != null , und der hat ein Ziel, dann ist das auch mein Ziel"). Die KI soll sich also gegenseitig "helfen" können.

Und jetzt wirds kriminell: Wem dreht sich die KI zu und wen schaut sie an?
Wenn der Player (als Team-Kapitän von Team Verbündete) in Sichtweite ist, dreht sich die KI diesem zu, wenn er außer Sichtweite ist, dreht sie sich dem nächsten Verbündeten zu.
Ist auch der nächste Verbündete außer Sichtweite, dann guckt die KI einfach gerade aus.

ich frage mich, ob das "notwendig" ist und nicht etwa schon zu überfrachtet ist? Im übrigen findet diese ganze Such, Find und Rotieren Geschichte im Update statt, und ich würde eigentlich gerne den Prozesser schonen, damit es flüssig läuft...
(Ich habe gerade mein ganzes AI-Skript komplett neu umgekrempelt, und hab Angst, das ich es mit riiieeesigen if / else / elseif Abfragen im update wieder zum Hemmschuh meines Projektes mache)

Wie intelligent soll die KI sein?
So habe ich zB auch implementiert, das sich pro getroffenem Gegner die Trefferwahrscheinlichkeit für den nächsten Schuß erhöht, d.h. die KI "lernt" im Spielverlauf besser zu schießen. (nur ein von mehreren Skills der sich im Spiel verbessern/verschlechtern können soll...)

Noch ne Frage: Es gibt in meinem Spiel ne Funktion,das der Player Verbündete sich folgen lassen kann.
In Spielen wie zB "Vietcong" liefen dann die Squad-mitglieder in einer Reihe hinter dem Spieler her.
Bei mir "knubbeln" sie sich hinter mirauf möglichst einem Punkt, teilweise "laufen" sie noch, obwohl sie nicht vorwärts kommen, da ihnen der Weg durch andere KIs versperrt ist. Alle drängeln also um den nächsten Platz am Spieler.

Wie sieht da die Lösung aus? Muß der Spieler eine (in der Länge variable?) Kette von unsichtbaren Transforms, die mit Hinge(?)Joints verbunden sind hinter sich herziehen? Und die KI sich dann ihren Platz in der kette suchen???
"Eine Signatur ist das Buchstaben-Zahlen-Zettelchen unten an ein einem Buch in der Bibliothek!"



was ich zur Zeit ausprobiere: 3rd person Shooter <- hierfür suche ich noch Unterstützung.


"Lehrjahre": Im Lande der Hasen
mein ewiges Spielprojekt "Straights & Rows".
meine Grafiken "ohne Verwendungszweck"

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

16

03.02.2018, 12:45

Ich hatte dich ja schonmal auf den Profiler von Unity hingewiesen. Anstatt als zu vermuten und zu befürchten, dass diese Logik der "Hemmschuh" ist, solltest du es einfach messen. Dann hast du Gewissheit und musst dich nicht auf das Bauchgefühl (das bei solchen Dingen ordentlich daneben liegen kann) verlassen.

Wie sieht da die Lösung aus? Muß der Spieler eine (in der Länge variable?) Kette von unsichtbaren Transforms, die mit Hinge(?)Joints verbunden sind hinter sich herziehen? Und die KI sich dann ihren Platz in der kette suchen???

Nein, das würde zu sehr seltsamem Verhalten führen, als ob die Figuren an einem unsichtbaren Gelenk verbunden wären. Keine dynamische Veränderung der Transform-Hierarchie oder Joints verwenden! Da käme nur Quatsch bei raus. Die Figur sollte sich einfach ihren Zielplatz suchen (in einer Reihe) und hinlaufen. Wenn schon einer da ist, wo ich hin will, dann bleibe ich einfach hinter ihm. So entsteht von selbst eine Kette.

Martin Mundorf

Treue Seele

  • »Martin Mundorf« ist der Autor dieses Themas

Beiträge: 262

Wohnort: Waldorf, Kr. Ahrweiler

Beruf: Althistoriker

  • Private Nachricht senden

17

03.02.2018, 18:01

Ja, den Profiler habe ich auch im Auge...

aber meine Frage war mehr theoretischer Natur: macht es in einem Spiel überhaupt Sinn, für jede eventuell eintretende Möglichkeit Code zu schreiben, oder ist es besser, man unterbindet die Frage irgendwo "weiter oben" im Code, damit die möglichen Unterscheidungen gar nicht erst auftauchen? Denn das solche "Haarspalterei"* irgendwann im Code und in der Ausführung toplastig wird, dh den Prozessor verlangsamt, kann man sich auch ohne Profiler denken...
(gleichwohl benutze ich ihn!)

*KI fragt sich: wohin gucke ich?

- habe ich einen teamKapitän? ja/nein
- habe ich einen nächsten verbündeten ja/nein
- habe ich ein Ziel ja/nein

für jeden dieser Fälle: Liegt das in meiner Sichtweite?

Und dann noch: was, wenn zwei oder drei Fälle gleichzeitig auftreten? (inkl. dem Fall "nein"?)

Bsp: KI hat einen teamKapitän, der ist aber außer Sicht-Reichweite, aber einen verbündeten und ein Ziel habe ich ...etc.etc.

ich stoße hier etwas an die grenzen meines abstrakten Denkvermögens :hmm:
"Eine Signatur ist das Buchstaben-Zahlen-Zettelchen unten an ein einem Buch in der Bibliothek!"



was ich zur Zeit ausprobiere: 3rd person Shooter <- hierfür suche ich noch Unterstützung.


"Lehrjahre": Im Lande der Hasen
mein ewiges Spielprojekt "Straights & Rows".
meine Grafiken "ohne Verwendungszweck"

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

18

03.02.2018, 18:09

*KI fragt sich: wohin gucke ich?

- habe ich einen teamKapitän? ja/nein
- habe ich einen nächsten verbündeten ja/nein
- habe ich ein Ziel ja/nein

für jeden dieser Fälle: Liegt das in meiner Sichtweite?

Und dann noch: was, wenn zwei oder drei Fälle gleichzeitig auftreten? (inkl. dem Fall "nein"?)

Bsp: KI hat einen teamKapitän, der ist aber außer Sicht-Reichweite, aber einen verbündeten und ein Ziel habe ich ...etc.etc.

ich stoße hier etwas an die grenzen meines abstrakten Denkvermögens


Du musst halt in irgendeiner Form bewerten was welche Priorität hat. Wenn es dir um die allgemeine Strukturierung geht dann guck doch mal nach Behavior Trees.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Martin Mundorf

Treue Seele

  • »Martin Mundorf« ist der Autor dieses Themas

Beiträge: 262

Wohnort: Waldorf, Kr. Ahrweiler

Beruf: Althistoriker

  • Private Nachricht senden

19

03.02.2018, 21:27

ich ahbs jetzt mal so gelöst: eine permanente bool -Abfrage wird aufgerufen, und die dann an entsprechender Stelle verarbeitet.
Jetzt ist es wesentlich kürzer als vorher - ich denke das macht sich auch in der Performance bemerkbar.


C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    public bool CanISeeCaptain()
    {
        if (teamS.Kapitän == null)
            return false;
        
        Vector3 start = cM.other_Setup.Kopf.transform.position;
        Vector3 dir = (teamS .Kapitän  .position + transform.up) - start;
        float dist = Vector3.Distance (teamS .Kapitän  .position, this.transform .position );

        RaycastHit hit;
        Ray ray = new Ray(start, dir);
        Debug.DrawRay(start, dir, Color.yellow);

        if (Physics.Raycast (start, dir, out hit, sight.sightRange)) 
        {
            if (hit.transform == teamS.Kapitän && dist < sight .sightRange ) 
            {
                return true;
            }
                
        }
        return  false;
    }


(Für next Ally gilt natürlich das gleiche Prinzip...)

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
        if (target == null) 
        {
            
            if (currentState == AIState.Follow) 
            {
                if (teamS.ISeeCaptain) 
                {
                    BlickToKapitän ();
                }
                else 
                {
                    if (teamS.ISeeNextAlly) 
                    {
                        BlickToAlly ();
                    } 
                    else 
                    {
                        DrehAufRichtung (this.transform.forward + Vector3.up);
                        Blickrichtung = this.GetComponent <CharacterMovement > ().other_Setup.Kopf.transform.forward;
                    }
                }
            } 
        }
"Eine Signatur ist das Buchstaben-Zahlen-Zettelchen unten an ein einem Buch in der Bibliothek!"



was ich zur Zeit ausprobiere: 3rd person Shooter <- hierfür suche ich noch Unterstützung.


"Lehrjahre": Im Lande der Hasen
mein ewiges Spielprojekt "Straights & Rows".
meine Grafiken "ohne Verwendungszweck"

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

20

03.02.2018, 22:58

Kurzer Code ist nicht unbedingt schneller als langer Code. Wie gesagt, ohne richtige Messung ist nichts bewiesen und alles nur Mutmaßen. Das Bauchgefühl ist bei solchen Dingen fast immer falsch. Oft kommt es sogar vor, dass man denkt etwas sei schneller (weil man es erwartet), in Wahrheit ist es jedoch genauso schnell oder gar langsamer.
Übrigens vermischst du immer noch munter deutsche und englische Bezeichner (BlickToKapitän etc.) ...

Werbeanzeige