예제 #1
0
 public AINodeMoveForward CreateComponentData(AINodeStatus nodeStatus)
 {
     return(new AINodeMoveForward {
         Distance = distance,
         DistanceLeft = distance,
     });
 }
예제 #2
0
 public AINodeChase CreateComponentData(AINodeStatus nodeStatus)
 {
     return(new AINodeChase {
         TargetId = targetId,
         SpeedBoost = speedBoost,
         MinimumDistance = minimumDistance,
     });
 }
예제 #3
0
 public AINodeTurn CreateComponentData(AINodeStatus nodeStatus)
 {
     return(new AINodeTurn {
         TurnSpeed = Utility.Math.Vector3ToFloat3(turnSpeed),
         Rotation = Utility.Math.Vector3ToFloat3(rotation),
         RotationRemaining = Utility.Math.Vector3ToFloat3(rotation),
     });
 }
예제 #4
0
        public void CreateEntity(EntityCommandBuffer commandBuffer, int treeId)
        {
            var entity     = commandBuffer.CreateEntity();
            var nodeStatus = new AINodeStatus {
                Type     = Type,
                State    = NodeState.Selecting,
                Id       = Index,
                ParentId = ParentId,
                TreeId   = treeId,
            };

            commandBuffer.AddComponent(entity, nodeStatus);
            commandBuffer.AddSharedComponent(entity, new TreeId {
                Id = treeId
            });

            // TODO add specific node data
            switch (Type)
            {
            case NodeType.Selector:
                commandBuffer.AddComponent(entity, Selector.CreateComponentData(nodeStatus));
                break;

            case NodeType.Sequence:
                commandBuffer.AddComponent(entity, Sequence.CreateComponentData(nodeStatus));
                break;

            case NodeType.MoveForward:
                commandBuffer.AddComponent(entity, MoveForward.CreateComponentData(nodeStatus));
                break;

            case NodeType.DestroyGameObject:
                commandBuffer.AddComponent(entity, DestroyGameObject.CreateComponentData(nodeStatus));
                break;

            case NodeType.Turn:
                commandBuffer.AddComponent(entity, Turn.CreateComponentData(nodeStatus));
                break;

            case NodeType.Chase:
                commandBuffer.AddComponent(entity, Chase.CreateComponentData(nodeStatus));
                break;

            default:
                break;
            }
        }
예제 #5
0
 public AINodeSequence CreateComponentData(AINodeStatus nodeStatus)
 {
     return(new AINodeSequence());
 }
예제 #6
0
        protected override JobHandle OnUpdate(JobHandle handle)
        {
            var commandBuffer = commandBufferSystem.CreateCommandBuffer();

            EntityManager.GetAllUniqueSharedComponentData(trees);

            // TODO find a way to delegate some of the work to jobs
            for (int x = 0; x < trees.Count; x++) // MEMO the first item will be default(TreeId), so ignore it // MEMO2 they seemed to have changed that
            {
                var treeId = trees[x];
                treeQuery.SetFilter(treeId);
                rootQuery.SetFilter(treeId);

                var count              = Mathf.Max(treeQuery.CalculateEntityCount(), 0);
                var nodeStatus         = new NativeArray <AINodeStatus>(count, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var entities           = new NativeArray <Entity>(count, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var unsortedNodeStatus = treeQuery.ToComponentDataArray <AINodeStatus>(Allocator.TempJob);
                var unsortedEntities   = treeQuery.ToEntityArray(Allocator.TempJob);
                for (int y = 0; y < count; y++)
                {
                    AINodeStatus status = unsortedNodeStatus[y];
                    if (status.Id >= count)
                    {
                        continue;
                    }
                    Entity entity = unsortedEntities[y];
                    nodeStatus[status.Id] = status;
                    entities[status.Id]   = entity;
                }
                unsortedNodeStatus.Dispose();
                unsortedEntities.Dispose();

                var roots        = rootQuery.ToComponentDataArray <AIRoot>(Allocator.TempJob);
                var rootEntities = rootQuery.ToEntityArray(Allocator.TempJob);

                if (roots.Length <= 0)
                {
                    nodeStatus.Dispose();
                    entities.Dispose();
                    roots.Dispose();
                    rootEntities.Dispose();
                    continue;
                }

                var root       = roots[0];
                var rootEntity = rootEntities[0];
                roots.Dispose();
                rootEntities.Dispose();


                // Update NodeState for control nodes
                int          lastControlNode = nodeStatus.Length - 1;
                AINodeStatus node;

                for (int y = nodeStatus.Length - 1; y >= 0; y--)
                {
                    node = nodeStatus[y];
                    if (node.Type == NodeType.Selector)
                    {
                        node.State = NodeState.Failure;
                        for (int z = node.Id + 1; z <= lastControlNode; z++)
                        {
                            var child = nodeStatus[z];
                            if (child.ParentId != node.Id)
                            {
                                continue;
                            }
                            if (child.State != NodeState.Failure)
                            {
                                node.State = child.State;
                                break;
                            }
                        }
                        EntityManager.SetComponentData <AINodeStatus>(entities[y], node);
                        lastControlNode = node.Id;
                    }

                    if (node.Type == NodeType.Sequence)
                    {
                        node.State = NodeState.Success;
                        for (int z = node.Id + 1; z <= lastControlNode; z++)
                        {
                            var child = nodeStatus[z];
                            if (child.ParentId != node.Id)
                            {
                                continue;
                            }
                            if (child.State != NodeState.Success)
                            {
                                node.State = child.State;
                                break;
                            }
                        }
                        EntityManager.SetComponentData <AINodeStatus>(entities[y], node);
                        lastControlNode = node.Id;
                    }
                }

                // Find node to run, and update root
                int idx      = 0;
                int parentId = 0;
                node = nodeStatus[idx];
                if (node.State != NodeState.Ready)
                {
                    root.State           = node.State;
                    root.RunningNodeType = NodeType.Root;
                    root.RunningNodeId   = idx;
                    EntityManager.SetComponentData <AIRoot>(rootEntity, root);
                    nodeStatus.Dispose();
                    entities.Dispose();
                    continue;
                }

                for (; idx < nodeStatus.Length; idx++)
                {
                    node = nodeStatus[idx];
                    if (node.ParentId != parentId)
                    {
                        continue;
                    }

                    if (node.State != NodeState.Ready)
                    {
                        continue;
                    }

                    if (node.Type == NodeType.Selector || node.Type == NodeType.Sequence)
                    {
                        parentId = idx;
                        continue;
                    }

                    node.State = NodeState.Running;
                    EntityManager.SetComponentData <AINodeStatus>(entities[idx], node);

                    if (root.RunningNodeType == node.Type && root.RunningNodeId == node.Id)
                    {
                        break;
                    }

                    root.RunningNodeType = node.Type;
                    root.RunningNodeId   = node.Id;
                    root.State           = NodeState.Running;
                    EntityManager.SetComponentData <AIRoot>(rootEntity, root);

                    var selectNodeMessage = new SelectAINodeMessage {
                        From    = node.TreeId,
                        To      = node.TreeId,
                        Payload = new SelectAINodePayload {
                        },
                    };
                    selectNodeMessage.Send(commandBuffer);

                    break;
                }

                nodeStatus.Dispose();
                entities.Dispose();
            }

            trees.Clear();
            return(handle);
        }
예제 #7
0
 public AINodeSelector CreateComponentData(AINodeStatus nodeStatus)
 {
     return(new AINodeSelector());
 }
예제 #8
0
 public AINodeDestroyGameObject CreateComponentData(AINodeStatus nodeStatus)
 {
     return(new AINodeDestroyGameObject {
         Destroy = true, // gives error if empty
     });
 }