public override void UpdateSensor() { Collider2D col = Physics2D.OverlapCircle(transform.position, SensorRange, foodLayer); worldState.Set("foodInRange", col != null); if (col) { worldState.Set("food", col.gameObject); } }
public void TestReGoapStateMissingDifference() { var state = new ReGoapState(); state.Set("var0", true); state.Set("var1", "string"); state.Set("var2", 1); var otherState = new ReGoapState(); otherState.Set("var1", "stringDifferent"); otherState.Set("var2", 1); var differences = new ReGoapState(); var count = state.MissingDifference(otherState, ref differences); Assert.That(count, Is.EqualTo(2)); Assert.That(differences.Get <bool>("var0"), Is.EqualTo(true)); Assert.That(differences.Get <string>("var1"), Is.EqualTo("string")); Assert.That(differences.HasKey("var2"), Is.EqualTo(false)); }
public void TestReGoapStateAddOperator() { var state = new ReGoapState(); state.Set("var0", true); state.Set("var1", "string"); state.Set("var2", 1); var otherState = new ReGoapState(); otherState.Set("var2", "new2"); // 2nd one replaces the first otherState.Set("var3", true); otherState.Set("var4", 10.1f); var sum = state + otherState; Assert.That(state.Count + otherState.Count, Is.EqualTo(6)); Assert.That(sum.Count, Is.EqualTo(5)); // var2 on first is replaced by var2 on second Assert.That(sum.Get <bool>("var0"), Is.EqualTo(true)); Assert.That(sum.Get <string>("var1"), Is.EqualTo("string")); Assert.That(sum.Get <string>("var2"), Is.EqualTo("new2")); Assert.That(sum.Get <bool>("var3"), Is.EqualTo(true)); Assert.That(sum.Get <float>("var4"), Is.EqualTo(10.1f)); }
public static ReGoapTestGoal GetCustomGoal(GameObject gameObject, string name, Dictionary <string, bool> goalState, int priority = 1) { var customGoal = gameObject.AddComponent <ReGoapTestGoal>(); customGoal.Name = name; customGoal.SetPriority(priority); customGoal.Init(); var goal = new ReGoapState(); foreach (var pair in goalState) { goal.Set(pair.Key, pair.Value); } customGoal.SetGoalState(goal); return(customGoal); }
public static ReGoapTestAction GetCustomAction(GameObject gameObject, string name, Dictionary <string, bool> preconditionsBools, Dictionary <string, bool> effectsBools, int cost = 1) { var effects = new ReGoapState(); var preconditions = new ReGoapState(); var customAction = gameObject.AddComponent <ReGoapTestAction>(); customAction.Name = name; customAction.Init(); foreach (var pair in effectsBools) { effects.Set(pair.Key, pair.Value); } customAction.SetEffects(effects); foreach (var pair in preconditionsBools) { preconditions.Set(pair.Key, pair.Value); } customAction.SetPreconditions(preconditions); customAction.Cost = cost; return(customAction); }
private static void _AddIntoReGoapState(ReGoapState <string, object> st, string key, object v) { if (key.StartsWith("Int")) { st.SetStructValue(key, StructValue.CreateIntArithmetic((int)v)); } else if (key.StartsWith("Float")) { st.SetStructValue(key, StructValue.CreateFloatArithmetic((float)v)); } else if (key.StartsWith("NInt")) { st.SetStructValue(key, StructValue.CreateIntArithmetic((int)v, neg: true)); } else if (key.StartsWith("NFloat")) { st.SetStructValue(key, StructValue.CreateFloatArithmetic((float)v, neg: true)); } else { st.Set(key, v); } }
public void TestDynamicAction() { var gameObject = new GameObject(); // settings these value to make sure that the planning chooses weaponA, since the pathing // weaponA -> ammoA -> enemy is actually cheaper, even if weaponC is very close to the enemy // without dynamic cost weaponC would always be chosen // we also add weaponB and ammoB to show the reconcileStartPosition logic // with this requirement in the goal and this action, we push as cost a goto to the player position // this effectively makes the plan: weaponB -> ammoB -> enemy more expensive, without reconciling with the starting position this plan would have been the best. var playerPosition = Vector2.zero; var enemyPosition = new Vector2(0, 100); var weaponAPosition = new Vector2(0, 50); var ammoAPosition = new Vector2(0, 60); var weaponBPosition = new Vector2(0, 115); var ammoBPosition = new Vector2(0, 115); var weaponCPosition = new Vector2(-5, 100); var weaponRange = 20.0f; ReGoapTestsHelper.GetCustomAction(gameObject, "ShootEnemy", new Dictionary <string, object> { { "weaponReady", true }, { "isAt", enemyPosition }, { "inRange", weaponRange } }, new Dictionary <string, object> { { "shootEnemy", true } }, 100); ReGoapTestsHelper.GetCustomAction(gameObject, "ReloadWeapon", new Dictionary <string, object> { { "hasWeapon", true }, { "hasAmmo", true } }, new Dictionary <string, object> { { "weaponReady", true } }, 20); #region getWeapon var getWeapon = ReGoapTestsHelper.GetCustomAction(gameObject, "GetWeapon", new Dictionary <string, object> { }, new Dictionary <string, object> { { "hasWeapon", true } }, 5); getWeapon.CustomPreconditionsGetter = (ref ReGoapState <string, object> preconditions, GoapActionStackData <string, object> stackData) => { preconditions.Clear(); if (stackData.settings.HasKey("weaponPosition")) { preconditions.Set("isAt", (Vector2)stackData.settings.Get("weaponPosition")); } }; getWeapon.CustomEffectsGetter = (ref ReGoapState <string, object> effects, GoapActionStackData <string, object> stackData) => { effects.Clear(); if (stackData.settings.HasKey("weaponPosition")) { effects.Set("hasWeapon", true); } }; getWeapon.CustomSettingsGetter = (GoapActionStackData <string, object> stackData) => { var results = new List <ReGoapState <string, object> >(); if (stackData.currentState.HasKey("weaponPositions") && stackData.currentState.HasKey("isAt")) { var currentPosition = (Vector2)stackData.currentState.Get("isAt"); foreach (var objectPosition in (List <Vector2>)stackData.currentState.Get("weaponPositions")) { ReGoapState <string, object> settings = ReGoapState <string, object> .Instantiate(); settings.Set("weaponPosition", objectPosition); results.Add(settings); } } return(results); }; #endregion #region getAmmo var getAmmo = ReGoapTestsHelper.GetCustomAction(gameObject, "GetAmmo", new Dictionary <string, object> { }, new Dictionary <string, object> { { "hasAmmo", true } }, 3); getAmmo.CustomPreconditionsGetter = (ref ReGoapState <string, object> preconditions, GoapActionStackData <string, object> stackData) => { preconditions.Clear(); if (stackData.settings.HasKey("ammoPosition")) { preconditions.Set("isAt", (Vector2)stackData.settings.Get("ammoPosition")); } }; getAmmo.CustomEffectsGetter = (ref ReGoapState <string, object> effects, GoapActionStackData <string, object> stackData) => { effects.Clear(); if (stackData.settings.HasKey("ammoPosition")) { effects.Set("hasAmmo", true); } }; getAmmo.CustomSettingsGetter = (GoapActionStackData <string, object> stackData) => { var results = new List <ReGoapState <string, object> >(); if (stackData.currentState.HasKey("ammoPositions") && stackData.currentState.HasKey("isAt")) { var currentPosition = (Vector2)stackData.currentState.Get("isAt"); foreach (var objectPosition in (List <Vector2>)stackData.currentState.Get("ammoPositions")) { ReGoapState <string, object> settings = ReGoapState <string, object> .Instantiate(); settings.Set("ammoPosition", objectPosition); results.Add(settings); } } return(results); }; #endregion #region dynamicGoTo var dynamicGoTo = ReGoapTestsHelper.GetCustomAction(gameObject, "GoTo", new Dictionary <string, object> { }, new Dictionary <string, object> { }); dynamicGoTo.CustomCostGetter = (ref float cost, GoapActionStackData <string, object> stackData) => { // base value to avoid free action cost = 1.0f; var inRange = 0.0f; if (stackData.settings.HasKey("inRange")) { inRange = (float)stackData.settings.Get("inRange"); } if (stackData.settings.HasKey("isAt") && stackData.currentState.HasKey("isAt")) { var wantedPosition = (Vector2)stackData.settings.Get("isAt"); var currentPosition = (Vector2)stackData.currentState.Get("isAt"); cost = (wantedPosition - currentPosition).magnitude - inRange; if (cost < 0) { cost = 0; } } }; dynamicGoTo.CustomEffectsGetter = (ref ReGoapState <string, object> effects, GoapActionStackData <string, object> stackData) => { effects.Clear(); if (stackData.settings.HasKey("isAt")) { var wantedPosition = (Vector2)stackData.settings.Get("isAt"); effects.Set("isAt", wantedPosition); } if (stackData.settings.HasKey("inRange")) { var inRange = (float)stackData.settings.Get("inRange"); effects.Set("inRange", inRange); } }; dynamicGoTo.CustomSettingsGetter = (GoapActionStackData <string, object> stackData) => { var newSettings = ReGoapState <string, object> .Instantiate(); Vector2 wantedPosition = Vector2.zero; float inRange = 0.0f; if (stackData.goalState.HasKey("isAt")) { wantedPosition = (Vector2)stackData.goalState.Get("isAt"); } if (stackData.goalState.HasKey("inRange")) { inRange = (float)stackData.goalState.Get("inRange"); } newSettings.Set("isAt", wantedPosition); newSettings.Set("inRange", inRange); return(new List <ReGoapState <string, object> > { newSettings }); }; #endregion #region reconcileStartPosition var reconcileStartPosition = ReGoapTestsHelper.GetCustomAction(gameObject, "ReconcileStartPosition", new Dictionary <string, object> { }, new Dictionary <string, object> { }, 1); reconcileStartPosition.CustomPreconditionsGetter = (ref ReGoapState <string, object> preconditions, GoapActionStackData <string, object> stackData) => { preconditions.Clear(); // this could be fetched from the world memory, in a custom action class preconditions.Set("isAt", playerPosition); }; reconcileStartPosition.CustomEffectsGetter = (ref ReGoapState <string, object> effects, GoapActionStackData <string, object> stackData) => { effects.Clear(); // we want this action to work only if no other goal has to be archived if (stackData.goalState.HasKey("reconcileStartPosition") && stackData.goalState.Count == 1) { effects.Set("reconcileStartPosition", true); } }; #endregion var theGoal = ReGoapTestsHelper.GetCustomGoal(gameObject, "ShootEnemy", new Dictionary <string, object> { { "shootEnemy", true }, { "reconcileStartPosition", true } }); var memory = gameObject.AddComponent <ReGoapTestMemory>(); memory.Init(); memory.SetValue("enemyPosition", enemyPosition); memory.SetValue("ammoPositions", new List <Vector2> { ammoAPosition, ammoBPosition }); memory.SetValue("weaponPositions", new List <Vector2> { weaponAPosition, weaponBPosition, weaponCPosition }); var agent = gameObject.AddComponent <ReGoapTestAgent>(); agent.Init(); var plan = GetPlanner(dynamicActions: true).Plan(agent, null, null, null); }
public override void UpdateSensor() { worldState.Set("objectivePosition", lastKnownPlayerPosition.position != null ? lastKnownPlayerPosition.position : transform.position); base.UpdateSensor(); }