UP-Viagg-io/Viagg-io/Assets/Packages/MyBT/Readme.md

184 lines
5.2 KiB
Markdown
Raw Normal View History

2024-01-19 16:30:05 +01:00
# My Behaviour Tree
## Lizenz
check the License.md file.
## Was macht ein Behaviourtree
Behaviour Trees sind eine High-Level Struktur zum steuern von künstlichen Intelligenzen oder Abläufen.
MyBT ist keine exakte abbildung von Behaviour Trees sondern Arbeitet mit ähnlichen Methoden welche ich für sinnvoll erachtet habe.
Neben dem Behaviour Tree muss man auch die aufgerufenen Funktionen definieren.
## Grundstruktur
Ein GameObject mit folgenden Komponenten:
- TaskController
- Ein Behaviour Tree Script auf "TaskScript" legen
- Weitere Monobehaviours die vom Behaviour Tree aufgerufen werden.
## Aufbau Behaviour Tree Script
Ein neues Unity Text Asset erstellen.
zBsp. Name.bt.txt
```
Tree("Root") {
Composite (Sequence) {
RunTree ("Player")
}
}
Tree ("Player") {
Composite (Sequence) {
SimpleController.SetRandomTarget (0, 0, 10)
Composite (Race) {
SimpleController.NearTarget (2)
SimpleController.RotateTowards (90)
SimpleController.MoveForward (4)
}
}
}
```
Kommentare sind moeglich, gegenwaertig sie aber nicht im editor dargestellt
Einzeilige Kommentare mittels //
Mehrzeilige Kommentare mittels /* und */
## Composite Typen:
// --- Sequence node ---
Starts all Children in sequence:
- any child running -> return running
- any child success -> continue in loop
- any child failed -> return failed
- finally -> exit success (there is no looping)
// ---
// --- Selector (fallback) node ---
Starts all Children in sequence:
- any child running -> continue in loop
- any child success -> return success
- any child failed -> continue in loop
- finally -> exit failed (there is no looping)
// ---
// --- Race Node, first finishes ---
Starts all Children in parallel:
- any child running -> continue in loop
- any child success -> return success, abort all remaining running
- any child failed -> continue in loop
- return after 1 iteration
- if all fail, fail.
// ---
// --- Marathon Node, wait for everyone ---
Starts all Children in parallel:
- any child running -> continue in loop
- any child success -> continue in loop
- any child failed -> continue in loop
- return after 1 iteration
- succeed when all are succeeded or failed
// ---
## Einen Task erstellen
## Decorator Typen:
Ein Decorator veraendert das resultat eines umschlossenen tasks oder composites
// --- Inverter ---
- return succeeded when failed
- return failed when succeeded
// ---
// --- ReturnSucceed ---
- returns succeeded when failed or succeeded
// ---
// --- Repeat ---
- returns running when failed or succeeded
// ---
// --- RepeatUntilFailed ---
- returns running when succeeded
// ---
##
Ein Unity Monobehaviour erstellen und auf das Objekt legen.
Alle Funktionen mit `[Task]` können durch MyBT aufgerufen werden.
Es gibt 2 Varianten wie ein Task aufgebaut werden kann:
### Ausführung der Tasks
* Ein Task wird einmal im Zustand "FirstRun" ausgeführt
* Danach im Zustand "Running"
* Beim Abbrechen wird der Task noch einmal mit dem Zustand "Aborting" Ausgeführt. Aborting wird nicht generell ausgeführt, sondern wenn ein Task, zBsp. aufgrund eines Races nicht mehr weiter ausgeführt wird.
### Task Code Variante 1
Prüfe mit `Task.Running(this)` ob der Task im Running oder Starting Zustand ist:
```c#
[Task]
public void MoveBy(float x, float y, float z) {
if (Task.isStartingOrRunning) {
transform.position += new Vector3(x, y, z) * Time.deltaTime;
}
}
```
### Task Code Variante 2
Nutze einen `Switch(Task.GetState(this))` um zu Prüfen in welchem Zustand der Task Ist:
```c#
[Task]
public void MoveByTimed(float x, float y, float z, float timer) {
switch (Task.getState) {
case NodeState.FirstRun:
Task.data = Time.time;
break;
case NodeState.Running:
float startTime = (float)Task.data;
float elapsed = Time.time - startTime;
if (elapsed > timer) {
Task.Succeeded(this);
}
transform.position += new Vector3(x, y, z) * Time.deltaTime;
break;
case NodeState.Aborting:
break;
}
}
```
### Task Return Fail or Succeess
Mittels `Task.Succeeded(this);` und `Task.Failed(this);` kann der Task ein Signal zurückgeben.
### Daten zum Task speichern
Mit `Task.SetData(object)` können Daten gespeichert und mit `Task.GetData()` wieder geladen werden. Diese sind nur mit der Instanz der Methode verbunden, nicht mit der Klasse. Wird der Composite unterbrochen, werden auf die daten gelöscht.
Ein Task kann natürlich auch Daten in der Klasse speichern und unter den Tasks austauschen.
### Einschränkungen für Tasks
Es gibt Einschränkungen bezüglich der möglichen Parameter der Tasks. Es können keine Funktionen als Parameter übergeben werden, so ist es z.Bsp. nicht möglich einen Vector3 als Parameter anzugeben.
Folgende Parameter sind unterstützt.
- Bool
- Int
- Float
- Char
- String
- Enum