-
Search Results
-
Hello all,
I’ve been following along @CodersExpo ‘s tutorials and had no issues until the last and final tutorial.
I seem to be having issues with the custom action and the wander.
Basically, I am able to get the character to run at the hero, wave (instead of punch) when within the “near” detector range, and whilst within his normal patrol route, idle randomly within the timer intervals set in BT.
Afterwards, we had been advised to get the custom action created to allow the character to wander after the Hero takes cover and removes himself from line of sight. At that point, I have the parallel node showing a failure and the waypoint path node showing a failure as well. It seems odd because it states that the execution of the previous “WanderLocation” custom action is succeeding as needed.
For reference,
BT:
->PAR-RPT:Never, Fail:Any, Succeed:Any, TieBreaker:Fail ->->Detect-Sensor:"eyes", Aspect:"aHero", FormVariable:varHero ->->Detect-Sensor:"close", Aspect:"aHero", FormVariable:varNear ->->Selector ->->->Constraint(TreeHereWorksPerfectly) ->->->Constraint(TreeHereWorksPerfectly) ->->->Constraint-Constraint:varHero == null && isSearching (shows fail) ->->->->Custom Action - Name:WanderLocation, Assembly:(global), Class:WanderLocation (Succeeds) ->->->->PAR - RPT:Never, Fail:Any, Succeed:Any, TieBreaker:Succeed (Fails) ->->->->->WaypointPath - WaypointNetwork:"Wander", PathTarget:varNext, MoveTargetVariable:varMoveTo (Fails) ->->->->->->Move-MoveTarget:varMoveTo, MoveSpeed:3 (NeverCalled) ->->->->->Animate - AnimationState:Walk (fails)
Custom Action Script “WanderLocation”:
using UnityEngine; using System.Collections; using System.Collections.Generic; using RAIN.Action; using RAIN.Core; using RAIN.Navigation; using RAIN.Navigation.Graph; [RAINAction] public class WanderLocation : RAINAction { private static float _time = 0f; public override void Start (RAIN.Core.AI ai) { base.Start (ai); _time += Time.time; } public WanderLocation () { actionName = "WanderLocation"; } public override ActionResult Execute (RAIN.Core.AI ai) { Vector3 loc = Vector3.zero; List<RAINNavigationGraph> found = new List<RAINNavigationGraph> (); do { loc = new Vector3 (ai.Kinematic.Position.x + Random.Range (-8f, 8f), ai.Kinematic.Position.y, ai.Kinematic.Position.z + Random.Range (-8f, 8f)); found = NavigationManager.Instance.GraphsForPoints (ai.Kinematic.Position, loc, ai.Motor.StepUpHeight, NavigationManager.GraphType.Navmesh, ((BasicNavigator)ai.Navigator).GraphTags); } while((Vector3.Distance(ai.Kinematic.Position, loc)<2f)||(found.Count == 0)); ai.WorkingMemory.SetItem<Vector3> ("varMoveTo", loc); if (_time > 5000f) { ai.WorkingMemory.SetItem ("isSearching", false); } return ActionResult.SUCCESS; } public override void Stop (RAIN.Core.AI ai) { base.Stop (ai); } }
So essentially, the character will run on the spot after losing detection and is set to “isSearching”, and after 5 seconds or so, he will then return to the normal patrol route. This is unexpected behaviour, simply because he should instead be wandering around searching on the waypoint network for signs of the hero.
Would really appreciate the assistance to wrap my head around RAIN AI.
Cheers.
Topic: How can this AI shoot?
I am trying to get the AI to shoot the player. I have set up the sensors so that the player can be detected. Then, the AI moves towards the player. When the player is in range of the AI, the AI should raycast the player and print that it has hit the player. However, I get a NULL REFERENCE EXCEPTION at line 47, where the code raycasts. Could someone please help me with this? Here is the code:
import RAIN.Core; import RAIN.Action; @RAINAction class aiShootPlayer extends RAIN.Action.RAINAction { private var woodenImpactParticle : GameObject; private var concreteImpactParticle : GameObject; private var dirtImpactParticle : GameObject; private var metalImpactParticle : GameObject; private var bodyImpactParticle : GameObject; private var shootPos : GameObject; private var dist : float = 50; private var showBlood : int = 0; function newclass() { actionName = "aiShootPlayer"; } function Start(ai:AI):void { super.Start(ai); } function Execute(ai:AI):ActionResult { showBlood = PlayerPrefs.GetInt("GraphicsShowBlood", 0); shootPos = ai.WorkingMemory.GetItem("ShootPos") as GameObject; woodenImpactParticle = ai.WorkingMemory.GetItem("WoodenImpactParticle") as GameObject; concreteImpactParticle = ai.WorkingMemory.GetItem("ConcreteImpactParticle") as GameObject; dirtImpactParticle = ai.WorkingMemory.GetItem("DirtImpactParticle") as GameObject; metalImpactParticle = ai.WorkingMemory.GetItem("MetalImpactParticle") as GameObject; bodyImpactParticle = ai.WorkingMemory.GetItem("BodyImpactParticle") as GameObject; Shoot(); return ActionResult.SUCCESS; } function Stop(ai:AI):void { super.Stop(ai); } function Shoot() { var hit : RaycastHit; if (Physics.Raycast(this.transform.position, Vector3.forward, hit, 50))//shootPos.transform.position, Vector3.forward, hit, 50)) { if (hit.gameObject.tag.ToLower() == "player") { print("Hit player"); Object.Instantiate(bodyImpactParticle, hit.point, bodyImpactParticle.transform.rotation); } } } }
and here is the XML Behaviour Tree:
<behaviortree version="1.1" repeatuntil="" name="soldierAITree"><parallel tiebreaker="fail" succeed="all" repeatuntil="" name="root" fail="any"><detect sensor=""eyes"" repeatuntil="running" name="detectEyes" entityobjectvariable="entityPlayerPos" aspectvariable="" aspectobjectvariable="" aspect=""entityPlayerVisual"" /><detect sensor=""shootRange"" repeatuntil="running" name="detectShootRange" entityobjectvariable="entityPlayerTarget" aspectvariable="" aspectobjectvariable="" aspect=""entityPlayerVisual"" /><selector usepriorities="False" repeatuntil="" name="ExecuteAll"><constraint repeatuntil="" priority="" name="IfTargetNull" constraint="entityPlayerPos == null && entityPlayerTarget == null"><parallel tiebreaker="fail" succeed="all" repeatuntil="" name="ExecuteAll" fail="any"><waypointpatrol waypointsetvariable="PatrolRoute" waypointactiontype="patrol" traversetype="pingpong" traverseorder="forward" repeatuntil="" pathtargetvariable="" name="patrol" movetargetvariable="nextPos"><move turnspeed="" repeatuntil="" name="move" movetarget="nextPos" movespeed="2" facetarget="" closeenoughdistance="" closeenoughangle="" /></waypointpatrol></parallel></constraint><constraint repeatuntil="" priority="" name="If PlayerFound" constraint="entityPlayerPos != null"><parallel tiebreaker="fail" succeed="all" repeatuntil="" name="parallel" fail="any"><constraint repeatuntil="" name="IfInRange" constraint="entityPlayerTarget != null "><parallel tiebreaker="fail" succeed="all" repeatuntil="" name="ExecuteAll" fail="any"><action repeatuntil="" parametervalues="" parameters="" namespace="(global)" name="ShootPlayer" classname="aiShootPlayer" /></parallel></constraint><constraint repeatuntil="" name="IfNotInRange" constraint="entityPlayerTaget == null"><parallel tiebreaker="fail" succeed="all" repeatuntil="" name="ExecuteAll" fail="any"><move turnspeed="" repeatuntil="" name="move" movetarget="entityPlayerPos" movespeed="2" facetarget="" closeenoughdistance="" closeenoughangle="" /></parallel></constraint></parallel></constraint></selector></parallel></behaviortree>
Cheers,
Stormy102