Last active
July 4, 2021 17:47
-
-
Save dinukapj/25931d44c003728a46e6b0cba76da8fa to your computer and use it in GitHub Desktop.
Goal Oriented Action Planning. Simple implementation of GOAP in Unity 3D
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using UnityEngine; | |
using Sirenix.OdinInspector; | |
using System; | |
public class Goaper : MonoBehaviour | |
{ | |
[TitleGroup("Parameters")] | |
[OnValueChanged("OnParameterChanged")] | |
public List<Parameter> parameters = new List<Parameter>(); | |
[TitleGroup("Goals")] | |
public List<Goal> goals = new List<Goal>(); | |
[Serializable] | |
public class Parameter | |
{ | |
public string parameterName; | |
public int value; | |
} | |
[Serializable] | |
public class Goal | |
{ | |
public string ID; | |
public List<Condition> conditions = new List<Condition>(); | |
} | |
[Serializable] | |
public class Condition | |
{ | |
//if value of | |
public string parameter1; | |
//operator | |
public enum Operator { GREATER_THAN, LESS_THAN, EQUAL_TO, NOT_EQUAL_TO } | |
public Operator _operator; | |
//compared to the value of | |
public int value; | |
//do this | |
public Result result; | |
} | |
[Serializable] | |
public class Result | |
{ | |
//perform | |
public enum Outcome { INCREMENT, DECREMENT, EXIT } | |
public Outcome outcome; | |
//on | |
public string parameter; | |
//by a value of | |
public int effectValue; | |
} | |
void OnParameterChanged() | |
{ | |
} | |
private int goalIndex = 0; | |
private Goal currentGoal; | |
void Start() | |
{ | |
ExecuteGoal(); | |
} | |
bool withinCondition; | |
bool completedAll; | |
void ExecuteGoal() | |
{ | |
currentGoal = goals[goalIndex]; | |
Debug.Log("Running: " + currentGoal.ID); | |
foreach (Condition condition in currentGoal.conditions) | |
{ | |
CheckCondition(condition); | |
do | |
{ | |
Debug.Log("Affecting: " + condition.result.parameter); | |
switch (condition.result.outcome) | |
{ | |
case Result.Outcome.INCREMENT: | |
LookupParameter(condition.result.parameter).value += condition.result.effectValue; | |
Debug.Log(condition.result.parameter + ": " + LookupParameter(condition.result.parameter).value); | |
break; | |
case Result.Outcome.DECREMENT: | |
LookupParameter(condition.result.parameter).value -= condition.result.effectValue; | |
Debug.Log(condition.result.parameter + ": " + LookupParameter(condition.result.parameter).value); | |
break; | |
case Result.Outcome.EXIT: | |
completedAll = true; | |
withinCondition = false; | |
break; | |
} | |
CheckCondition(condition); | |
} | |
while (withinCondition); | |
if (!withinCondition) | |
{ | |
Debug.Log("Goal Completed"); | |
if (!completedAll) | |
{ | |
goalIndex++; | |
ExecuteGoal(); | |
} | |
else | |
{ | |
Debug.Log("All Goals Completed"); | |
} | |
} | |
} | |
} | |
void CheckCondition(Condition condition) | |
{ | |
switch (condition._operator) | |
{ | |
case Condition.Operator.EQUAL_TO: | |
if (LookupParameter(condition.parameter1).value.Equals(condition.value)) | |
{ | |
withinCondition = true; | |
} | |
else | |
{ | |
withinCondition = false; | |
} | |
break; | |
case Condition.Operator.LESS_THAN: | |
if (LookupParameter(condition.parameter1).value < condition.value) | |
{ | |
withinCondition = true; | |
} | |
else | |
{ | |
withinCondition = false; | |
} | |
break; | |
case Condition.Operator.GREATER_THAN: | |
if (LookupParameter(condition.parameter1).value > condition.value) | |
{ | |
withinCondition = true; | |
} | |
else | |
{ | |
withinCondition = false; | |
} | |
break; | |
case Condition.Operator.NOT_EQUAL_TO: | |
if (!LookupParameter(condition.parameter1).value.Equals(condition.value)) | |
{ | |
withinCondition = true; | |
} | |
else | |
{ | |
withinCondition = false; | |
} | |
break; | |
} | |
} | |
Parameter LookupParameter(string id) | |
{ | |
foreach (Parameter parameter in parameters) | |
{ | |
if (parameter.parameterName.Equals(id)) | |
{ | |
return parameter; | |
} | |
} | |
return null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment