public virtual void InitializePathfindingSearch(Vector3 startPosition, Vector3 goalPosition)
        {
            this.StartPosition = startPosition;
            this.GoalPosition = goalPosition;
            this.StartNode = this.Quantize(this.StartPosition);
            this.GoalNode = this.Quantize(this.GoalPosition);

            //if it is not possible to quantize the positions and find the corresponding nodes, then we cannot proceed
            if (this.StartNode == null || this.GoalNode == null) return;

            //I need to do this because in Recast NavMesh graph, the edges of polygons are considered to be nodes and not the connections.
            //Theoretically the Quantize method should then return the appropriate edge, but instead it returns a polygon
            //Therefore, we need to create one explicit connection between the polygon and each edge of the corresponding polygon for the search algorithm to work
            ((NavMeshPoly)this.StartNode).AddConnectedPoly(this.StartPosition);
            ((NavMeshPoly)this.GoalNode).AddConnectedPoly(this.GoalPosition);

            this.InProgress = true;
            this.TotalExploredNodes = 0;
            this.TotalProcessingTime = Time.time;
            this.MaxOpenNodes = 0;

            var initialNode = new NodeRecord
            {
                gValue = 0,
                hValue = this.Heuristic.H(this.StartNode.Position, this.GoalNode.Position),
                node = this.StartNode
            };

            initialNode.fValue = AStarPathfinding.F(initialNode);

            this.Open.Initialize();
            this.Open.AddToOpen(initialNode);
            this.Closed.Initialize();
        }
예제 #2
0
        protected override void ProcessChildNode(NodeRecord bestNode, NavigationGraphEdge connectionEdge, int edgeIndex)
        {
            float g;
            float h;
            float f;

            var childNode       = connectionEdge.ToNode;
            var childNodeRecord = this.NodeRecordArray.GetNodeRecord(childNode);

            if (childNodeRecord == null)
            {
                //this piece of code is used just because of the special start nodes and goal nodes added to the RAIN Navigation graph when a new search is performed.
                //Since these special goals were not in the original navigation graph, they will not be stored in the NodeRecordArray and we will have to add them
                //to a special structure
                //it's ok if you don't understand this, this is a hack and not part of the NodeArrayA* algorithm, just do NOT CHANGE THIS, or your algorithm will not work
                childNodeRecord = new NodeRecord
                {
                    node   = childNode,
                    parent = bestNode,
                    status = NodeStatus.Unvisited
                };
                this.NodeRecordArray.AddSpecialCaseNode(childNodeRecord);
            }

            /* Here we calculate the cost so far, the heuristic value and the f value */
            Vector3 childNodePosition = childNode.Position;

            g = bestNode.gValue + (childNodePosition - bestNode.node.Position).magnitude;
            h = base.Heuristic.H(childNodePosition, this.GoalNode.Position);
            f = AStarPathfinding.F(g, h);

            /* Set values of first node */
            if (childNodeRecord.status == NodeStatus.Unvisited)
            {
                // Set values of child node
                childNodeRecord.gValue = g;
                childNodeRecord.hValue = h;
                childNodeRecord.fValue = f;
                childNodeRecord.parent = bestNode;

                this.Open.AddToOpen(childNodeRecord);
            }
            else if (childNodeRecord.status == NodeStatus.Open && f < childNodeRecord.fValue)
            {
                childNodeRecord.gValue = g;
                childNodeRecord.fValue = f;
                childNodeRecord.parent = bestNode;
            }
            else if (childNodeRecord.status == NodeStatus.Closed && f < childNodeRecord.fValue)
            {
                childNodeRecord.gValue = g;
                childNodeRecord.fValue = f;
                childNodeRecord.parent = bestNode;

                this.Open.AddToOpen(childNodeRecord);
            }
            this.MaxOpenNodes = Mathf.Max(this.MaxOpenNodes, this.Open.CountOpen());
        }
 public NodeAStarDecomposer(AStarPathfinding aStarPathFinding)
 {
     this.aStarPathFinding = aStarPathFinding;
 }
예제 #4
0
        public void Start()
        {
            this.draw = true;
            this.navMesh = NavigationManager.Instance.NavMeshGraphs[0];
            this.Character = new DynamicCharacter(this.gameObject);

            //initialization of the movement algorithms
            this.aStarPathFinding = new NodeArrayAStarPathFinding(this.navMesh, new EuclideanDistanceHeuristic());
            this.aStarPathFinding.NodesPerSearch = 100;

            var steeringPipeline = new SteeringPipeline
            {
                MaxAcceleration = 40.0f,
                MaxConstraintSteps = 2,
                Character = this.Character.KinematicData,
            };

            this.decomposer = new PathFindingDecomposer(steeringPipeline, this.aStarPathFinding);
            this.Targeter = new FixedTargeter(steeringPipeline);
            steeringPipeline.Targeters.Add(this.Targeter);
            steeringPipeline.Decomposers.Add(this.decomposer);
            steeringPipeline.Actuator = new FollowPathActuator(steeringPipeline);

            this.Character.Movement = steeringPipeline;

            //initialization of the GOB decision making
            //let's start by creating 4 main goals
            //the eatgoal is the only goal that increases at a fixed rate per second, it increases at a rate of 0.1 per second
            this.SurviveGoal = new Goal(SURVIVE_GOAL, 2.0f);
            this.EatGoal = new Goal(EAT_GOAL, 1.0f)
            {
                ChangeRate = 0.1f
            };
            this.GetRichGoal = new Goal(GET_RICH_GOAL, 1.0f)
            {
                InsistenceValue = 5.0f,
                ChangeRate = 0.2f
            };
            this.RestGoal = new Goal(REST_GOAL, 1.0f);

            this.Goals = new List<Goal>();
            this.Goals.Add(this.SurviveGoal);
            this.Goals.Add(this.EatGoal);
            this.Goals.Add(this.GetRichGoal);
            this.Goals.Add(this.RestGoal);

            //initialize the available actions

            var restAction = new Rest(this);
            this.Actions = new List<Action>();
            this.Actions.Add(restAction);

            foreach (var chest in GameObject.FindGameObjectsWithTag("Chest"))
            {
                this.Actions.Add(new PickUpChest(this, chest));
            }

            foreach (var tree in GameObject.FindGameObjectsWithTag("Tree"))
            {
                this.Actions.Add(new GetArrows(this, tree));
            }

            foreach (var bed in GameObject.FindGameObjectsWithTag("Bed"))
            {
                this.Actions.Add(new Sleep(this, bed));
            }

            foreach (var boar in GameObject.FindGameObjectsWithTag("Boar"))
            {
                this.Actions.Add(new MeleeAttack(this, boar));
                this.Actions.Add(new Shoot(this, boar));
            }

            var worldModel = new CurrentStateWorldModel(this.GameManager, this.Actions, this.Goals);

            this.GOAPDecisionMaking = new DepthLimitedGOAPDecisionMaking(worldModel,this.Actions,this.Goals);
        }
 public PathFindingDecomposer(SteeringPipeline pipeline, AStarPathfinding pathfindingAlgorithm)
     : base(pipeline)
 {
     this.PathfindingAlgorithm = pathfindingAlgorithm;
 }
예제 #6
0
        public void Start()
        {
            this.draw = true;
            this.influenceMapDebugMode = 0;

            this.navMesh = NavigationManager.Instance.NavMeshGraphs[0];
            this.Character = new DynamicCharacter(this.gameObject);

            //initialization of the movement algorithms
            this.aStarPathFinding = new NodeArrayAStarPathFinding(this.navMesh, new EuclideanDistanceHeuristic(), this);
            this.aStarPathFinding.NodesPerSearch = 500;

            var steeringPipeline = new SteeringPipeline
            {
                MaxAcceleration = 40.0f,
                MaxConstraintSteps = 2,
                Character = this.Character.KinematicData,
            };

            this.decomposer = new PathFindingDecomposer(steeringPipeline, this.aStarPathFinding);
            this.Targeter = new FixedTargeter(steeringPipeline);
            steeringPipeline.Targeters.Add(this.Targeter);
            steeringPipeline.Decomposers.Add(this.decomposer);
            steeringPipeline.Actuator = new FollowPathActuator(steeringPipeline);

            this.Character.Movement = steeringPipeline;

            //initialization of the Influence Maps
            this.RedInfluenceMap = new InfluenceMap(this.navMesh,new SimpleUnorderedList(), new ClosedLocationRecordDictionary(), new LinearInfluenceFunction(), 0.1f);
            this.GreenInfluenceMap = new InfluenceMap(this.navMesh, new SimpleUnorderedList(), new ClosedLocationRecordDictionary(), new LinearInfluenceFunction(), 0.1f);
            this.ResourceInfluenceMap = new InfluenceMap(this.navMesh, new SimpleUnorderedList(), new ClosedLocationRecordDictionary(), new LinearInfluenceFunction(), 0.1f);
            this.CombinedInfluence = new Dictionary<LocationRecord, float>();
            this.SecurityMap = new Dictionary<LocationRecord, float>();

            //initialization of the GOB decision making
            //let's start by creating 5 main goals
            //the eat goal is the only goal that increases at a fixed rate per second, it increases at a rate of 0.1 per second
            this.SurviveGoal = new Goal(SURVIVE_GOAL, 2.0f);
            this.EatGoal = new Goal(EAT_GOAL, 1.0f)
            {
                ChangeRate = 0.1f
            };
            this.GetRichGoal = new Goal(GET_RICH_GOAL, 1.0f)
            {
                InsistenceValue = 5.0f,
                ChangeRate = 0.2f
            };
            this.RestGoal = new Goal(REST_GOAL, 1.0f);
            this.ConquerGoal = new Goal(CONQUER_GOAL, 1.5f)
            {
                InsistenceValue = 5.0f
            };

            this.Goals = new List<Goal>();
            this.Goals.Add(this.SurviveGoal);
            this.Goals.Add(this.EatGoal);
            this.Goals.Add(this.GetRichGoal);
            this.Goals.Add(this.RestGoal);
            this.Goals.Add(this.ConquerGoal);

            //initialize the available actions

            var restAction = new Rest(this);
            this.Actions = new List<Action>();
            this.Actions.Add(restAction);
            this.Actions.Add(new PlaceFlag(this));

            this.ActiveResources = new Dictionary<NavigationGraphNode, IInfluenceUnit>();
            int boars = 0;
            int chests = 0;
            int trees = 0;
            int beds = 0;

            foreach (var chest in GameObject.FindGameObjectsWithTag("Chest"))
            {
                chests++;
                this.Actions.Add(new PickUpChest(this, chest));
                this.AddResource(new Resource(this.navMesh.QuantizeToNode(chest.transform.position, 1.0f)));
            }

            foreach (var tree in GameObject.FindGameObjectsWithTag("Tree"))
            {
                trees++;
                this.Actions.Add(new GetArrows(this, tree));
                this.AddResource(new Resource(this.navMesh.QuantizeToNode(tree.transform.position, 1.0f)));
            }

            foreach (var bed in GameObject.FindGameObjectsWithTag("Bed"))
            {
                beds++;
                this.Actions.Add(new Sleep(this, bed));
                this.AddResource(new Resource(this.navMesh.QuantizeToNode(bed.transform.position, 1.0f)));
            }

            foreach (var boar in GameObject.FindGameObjectsWithTag("Boar"))
            {
                boars++;
                this.AddResource(new Resource(this.navMesh.QuantizeToNode(boar.transform.position, 1.0f)));
                this.Actions.Add(new MeleeAttack(this, boar));
                this.Actions.Add(new Shoot(this, boar));
            }

            this.ResourceInfluenceMap.Initialize(this.ActiveResources.Values.ToList());

            //flags used for the influence map
            this.RedFlags = new List<IInfluenceUnit>();
            foreach (var redFlag in GameObject.FindGameObjectsWithTag("RedFlag"))
            {
                this.RedFlags.Add(new Flag(this.navMesh.QuantizeToNode(redFlag.transform.position, 1.0f), FlagColor.Red));
            }

            this.GreenFlags = new List<IInfluenceUnit>();
            foreach (var greenFlag in GameObject.FindGameObjectsWithTag("GreenFlag"))
            {
                this.GreenFlags.Add(new Flag(this.navMesh.QuantizeToNode(greenFlag.transform.position, 1.0f), FlagColor.Green));
            }

            this.RedInfluenceMap.Initialize(this.RedFlags);
            this.GreenInfluenceMap.Initialize(this.GreenFlags);

            var worldModel = new CurrentStateWorldModelFEAR(this.GameManager, this.Actions, this.Goals);
            worldModel.InitArrays( boars, trees,  beds,  chests);

            this.GOAPDecisionMaking = new DepthLimitedGOAPDecisionMaking(worldModel,this.Actions,this.Goals);
        }
        public void Start()
        {
            this.draw = true;
            this.influenceMapDebugMode = 0;
            this.navMesh = NavigationManager.Instance.NavMeshGraphs[0];
            this.Character = new DynamicCharacter(this.gameObject);

            //initialization of the movement algorithms
            this.aStarPathFinding = new NodeArrayAStarPathFinding(this.navMesh, new EuclideanDistanceHeuristic());
            this.aStarPathFinding.NodesPerSearch = 100;

            var steeringPipeline = new Assets.Scripts.IAJ.Unity.SteeringPipeline.SteeringPipeline
            {
                MaxAcceleration = 40.0f,
                MaxConstraintSteps = 2,
                Character = this.Character.KinematicData,
            };

            this.decomposer = new Assets.Scripts.IAJ.Unity.SteeringPipeline.NodeAStarDecomposer(this.aStarPathFinding);
            this.Targeter = new Assets.Scripts.IAJ.Unity.SteeringPipeline.TargetPosition();
            steeringPipeline.Targeters.Add(this.Targeter);
            steeringPipeline.Decomposers.Add(this.decomposer);
            steeringPipeline.Actuator = actuator = new Assets.Scripts.IAJ.Unity.SteeringPipeline.PathFollowingActuator()
            {
                movement = new DynamicFollowPath()
                {
                    MaxAcceleration = 40.0f,
                    PathOffset = 0.05f,
                    Movement = new DynamicCarSeek()
                    {
                        MaxSpeed = this.Character.MaxSpeed,
                        MinSpeed = 4f
                    }
                },
                SecondsToSmooth = 2f
            };

            this.Character.Movement = steeringPipeline;

            //initialization of the Influence Maps
            this.RedInfluenceMap = new InfluenceMap(this.navMesh,new SimpleUnorderedList(), new ClosedLocationRecordDictionary(), new LinearInfluenceFunction(), 0.1f);
            this.GreenInfluenceMap = new InfluenceMap(this.navMesh, new SimpleUnorderedList(), new ClosedLocationRecordDictionary(), new LinearInfluenceFunction(), 0.1f);

            //initialization of the GOB decision making
            //let's start by creating 4 main goals
            //the eatgoal is the only goal that increases at a fixed rate per second, it increases at a rate of 0.1 per second
            this.SurviveGoal = new Goal(SURVIVE_GOAL, 2.0f);
            this.EatGoal = new Goal(EAT_GOAL, 1.0f)
            {
                ChangeRate = 0.1f
            };
            this.GetRichGoal = new Goal(GET_RICH_GOAL, 1.0f)
            {
                InsistenceValue = 5.0f,
                ChangeRate = 0.2f
            };
            this.RestGoal = new Goal(REST_GOAL, 1.0f);
            this.ConquerGoal = new Goal(CONQUER_GOAL, 1.5f)
            {
                InsistenceValue = 5.0f
            };

            this.Goals = new List<Goal>();
            this.Goals.Add(this.SurviveGoal);
            this.Goals.Add(this.EatGoal);
            this.Goals.Add(this.GetRichGoal);
            this.Goals.Add(this.RestGoal);
            this.Goals.Add(this.ConquerGoal);

            //initialize the available actions

            var restAction = new Rest(this);
            this.Actions = new List<Action>();
            this.Actions.Add(restAction);

            foreach (var chest in GameObject.FindGameObjectsWithTag("Chest"))
            {
                this.Actions.Add(new PickUpChest(this, chest));
            }

            foreach (var tree in GameObject.FindGameObjectsWithTag("Tree"))
            {
                this.Actions.Add(new GetArrows(this, tree));

            }

            foreach (var bed in GameObject.FindGameObjectsWithTag("Bed"))
            {
                this.Actions.Add(new Sleep(this, bed));

            }

            foreach (var boar in GameObject.FindGameObjectsWithTag("Boar"))
            {
                this.Actions.Add(new MeleeAttack(this, boar));
                this.Actions.Add(new Shoot(this, boar));
            }

            //flags used for the influence map
            this.RedFlags = new List<IInfluenceUnit>();
            foreach (var redFlag in GameObject.FindGameObjectsWithTag("RedFlag"))
            {
                this.RedFlags.Add(new Flag(this.navMesh.QuantizeToNode(redFlag.transform.position, 1.0f), FlagColor.Red));
            }

            this.GreenFlags = new List<IInfluenceUnit>();
            foreach (var greenFlag in GameObject.FindGameObjectsWithTag("GreenFlag"))
            {
                this.GreenFlags.Add(new Flag(this.navMesh.QuantizeToNode(greenFlag.transform.position, 1.0f), FlagColor.Green));
            }

            this.RedInfluenceMap.Initialize(this.RedFlags);
            this.GreenInfluenceMap.Initialize(this.GreenFlags);

            var worldModel = new CurrentStateWorldModel(this.GameManager, this.Actions, this.Goals);

            this.GOAPDecisionMaking = new DepthLimitedGOAPDecisionMaking(worldModel,this.Actions,this.Goals);
        }
        public void Start()
        {
            this.draw = true;
            this.navMesh = NavigationManager.Instance.NavMeshGraphs [0];
            this.Character = new DynamicCharacter(this.gameObject) { Drag = 0.3f};

            //initialization of the movement algorithms
            this.aStarPathFinding = new NodeArrayAStarPathFinding(this.navMesh, new EuclideanDistanceHeuristic());
            this.aStarPathFinding.NodesPerSearch = 100;

            var steeringPipeline = new Assets.Scripts.IAJ.Unity.SteeringPipeline.SteeringPipeline
            {
                MaxAcceleration = 40.0f,
                MaxConstraintSteps = 2,
                Character = this.Character.KinematicData,
            };

            this.decomposer = new Assets.Scripts.IAJ.Unity.SteeringPipeline.NodeAStarDecomposer(this.aStarPathFinding);
            this.Targeter = new Assets.Scripts.IAJ.Unity.SteeringPipeline.TargetPosition();
            steeringPipeline.Targeters.Add(this.Targeter);
            steeringPipeline.Decomposers.Add(this.decomposer);
            var obstacles = GameObject.FindGameObjectsWithTag("Obstacle");
            steeringPipeline.Constraints.Add(
                new Assets.Scripts.IAJ.Unity.SteeringPipeline.ConstraitColisionWithWalls(obstacles, 500.0f)
                {
                AvoidMargin = 7f,
                MaxLookAhead = 5f,
                MaxWhiskersLookAhead = 7f
            });
            steeringPipeline.Actuator = actuator = new Assets.Scripts.IAJ.Unity.SteeringPipeline.PathFollowingActuator()
            {
                movement = new DynamicFollowPath()
                {
                    MaxAcceleration = 40.0f,
                    PathOffset = 0.05f,
                    Movement = new DynamicCarSeek()
                    {
                        MaxSpeed = this.Character.MaxSpeed,
                        MinSpeed = 4f
                    }
                },
                SecondsToSmooth = 2f
            };

            this.Character.Movement = steeringPipeline;

            //initialization of the GOB decision making
            //let's start by creating 4 main goals
            //the eatgoal is the only goal that increases at a fixed rate per second, it increases at a rate of 0.1 per second
            this.SurviveGoal = new Goal(SURVIVE_GOAL, 2.0f);
            this.EatGoal = new Goal(EAT_GOAL, 1.0f)
            {
                ChangeRate = 0.1f
            };
            this.GetRichGoal = new Goal(GET_RICH_GOAL, 1.0f)
            {
                InsistenceValue = 5.0f,
                ChangeRate = 0.2f
            };
            this.RestGoal = new Goal(REST_GOAL, 1.0f);

            this.Goals = new List<Goal>();
            this.Goals.Add(this.SurviveGoal);
            this.Goals.Add(this.EatGoal);
            this.Goals.Add(this.GetRichGoal);
            this.Goals.Add(this.RestGoal);

            //initialize the available actions

            var restAction = new Rest(this);
            this.Actions = new List<Action>();
            this.Actions.Add(restAction);

            foreach (var chest in GameObject.FindGameObjectsWithTag("Chest"))
            {
                this.Actions.Add(new PickUpChest(this, chest));
            }

            foreach (var tree in GameObject.FindGameObjectsWithTag("Tree"))
            {
                this.Actions.Add(new GetArrows(this, tree));
            }

            foreach (var bed in GameObject.FindGameObjectsWithTag("Bed"))
            {
                this.Actions.Add(new Sleep(this, bed));
            }

            foreach (var boar in GameObject.FindGameObjectsWithTag("Boar"))
            {
                this.Actions.Add(new MeleeAttack(this, boar));
                this.Actions.Add(new Shoot(this, boar));
            }
        }
 public NodeAStarDecomposer()
 {
     this.navMesh = NavigationManager.Instance.NavMeshGraphs[0];
     this.aStarPathFinding = new NodeArrayAStarPathFinding(this.navMesh, new EuclideanHeuristic());
     this.aStarPathFinding.NodesPerSearch = 100;
 }