< All Topics
Print

IQT User Guide

Welcome to the user guide for the IQT – Insane Queue & Task Plugin for Unreal Engine! This plugin is designed to simplify complex task and AI behavior management in your games and simulations. With IQT, you can create robust task queue systems and seamlessly integrate with Unreal’s Gameplay Ability System (GAS), allowing your actors to react intelligently and orchestrate their actions.

1. Introduction to IQT

IQT is a powerful solution for developers who need a flexible system to manage the execution of tasks or “work items” within the engine. It is ideal for:

  • Artificial Intelligence (AI): Managing action sequences for NPCs, pathfinding, prioritized attack targets, etc.
  • Quest/Objective Systems: Orchestrating quest steps, sub-tasks, and dynamic objectives.
  • Simulations: Managing real-time events, production processes, or entity lifecycles.
  • Asynchronous Behaviors: Triggering actions and waiting for their results before proceeding to the next task.

The plugin primarily consists of two main components: the UIQT_Queue (an actor component to manage queues of items) and the UIQT_WaitForAction (a GAS Ability Task that allows waiting for events).

2. Fundamental Concepts

Before we dive into usage, let’s understand the key concepts of IQT.

2.1. FIQT_QueueItem (The Queue Item)

This is the central data structure that represents a “task” or “work item” to be managed by the queue. You can think of it as the information describing what needs to be done.

Important Properties:

  • Name: A descriptive name for the item (e.g., “CollectItemsQuest”, “AttackEnemy”).
  • TaskID: A unique ID automatically generated for each item, useful for searches.
  • Priority: An integer that defines the item’s priority. The higher the number, the higher the priority (in PriorityOrder mode).
  • bIsOpen: A generic boolean flag you can use to indicate the item’s status (e.g., true for “active” or false for “completed”).
  • UserPayload: The most powerful feature. It allows you to attach any UObject (a character, an inventory item, a complex struct with additional data) to this queue item. This makes FIQT_QueueItem extremely flexible.
  • AbilityTriggerTag: A FGameplayTag that the system can use to trigger a GameplayAbility when this item is processed.
  • AbilityEndTag: A FGameplayTag that the system (via UIQT_WaitForAction) can wait for to indicate that the action associated with this item has been successfully completed.
  • AbilityFailTag: A FGameplayTag that the system can wait for to indicate that the action associated with this item has failed.

2.2. UIQT_Queue (The Queue Manager)

This is a UActorComponent that you add to any Actor in your game to manage a queue of FIQT_QueueItems. It handles queuing, dequeuing, ordering, and searching for items.

Queuing Modes (EnqueueMode):

  • PriorityOrder: The default mode. Items are inserted into the queue based on their Priority property. Items with higher priority are processed first.
  • FIFO (First In, First Out): The first item that enters the queue is the first to leave. Useful for linear task sequences.
  • FILO (First In, Last Out): The first item that enters the queue is the last to leave. Useful for “stacks” of tasks.

Other Settings:

  • bIgnoreDuplicatesOnEnqueue: If enabled, the system will not add an item if an identical item (compared by Name, AbilityTriggerTag, and bIsOpen) is already in the queue.
  • MaxQueueSize: Defines the maximum number of items the queue can hold. If set to 0, there is no limit.

2.3. UIQT_WaitForAction (The GAS Wait Task)

This is a UAbilityTask (part of the Gameplay Ability System) that allows a GameplayAbility to “pause” its execution and wait for specific events (FGameplayTag) before continuing. It is the bridge between your queue tasks and the actions executed by your GameplayAbilities.

3. Quick Start Guide: How to Use IQT in Blueprints

Let’s see how you can start using IQT in your Blueprints.

3.1. Setting Up UIQT_Queue

  1. Add the Component: In any Actor Blueprint (NPC, Game System, etc.), go to “Components” and add a UIQT_Queue component.
  2. Configure in Editor: In the “Details” panel of your UIQT_Queue component, you can adjust the EnqueueMode, bIgnoreDuplicatesOnEnqueue, and MaxQueueSize properties according to your needs.
Property Description Initial Recommendation
Enqueue Mode Defines the processing order of items. Priority Order (for complex AI) or FIFO (for sequences)
Ignore Duplicates On Enqueue Prevents the same item from being added multiple times. True (generally desirable to avoid unwanted repetitions)
Max Queue Size Item limit in the queue (0 for unlimited). 0 (unlimited, but monitor performance)
  1. Initialize the Queue: It is crucial to initialize the queue before using it. It’s ideal to do this in your Actor’s Event BeginPlay.
[Event BeginPlay]
--> [UIQT_Queue Reference] -- Initialize Queue

3.2. Basic Operations with UIQT_Queue

3.2.1. Creating an FIQT_QueueItem

Before queuing, you need to create an item. Use a “Make FIQT_QueueItem” node in your Blueprint.

  • Name: Give it a meaningful name (e.g., “PatrolPointA”).
  • Priority: Set an integer number.
  • AbilityTriggerTag: Define a Gameplay Tag that will trigger the action when this item is processed (e.g., Task.MoveToLocation).
  • AbilityEndTag: Tag to indicate success (e.g., Task.MoveToLocation.Finished).
  • AbilityFailTag: Tag to indicate failure (e.g., Task.MoveToLocation.Failed).
  • UserPayload: If you need to attach an Actor, Component, or another UObject, connect it here.
[Make FIQT_QueueItem]
Name = "MoveToTarget"
Priority = 100
Ability Trigger Tag = "Ability.Task.Move"
Ability End Tag = "Ability.Task.Move.Success"
Ability Fail Tag = "Ability.Task.Move.Failed"
User Payload = [Target Actor Reference]

3.2.2. Enqueuing an Item (Enqueue Item)

Connect the created item to the Enqueue Item node of your UIQT_Queue component.

[FIQT_QueueItem (created)]
--> [UIQT_Queue Reference] -- Enqueue Item (ItemToEnqueue: FIQT_QueueItem)
    --> [Branch (Return Value: bSuccess)]
        [True] --> [Print String: "Item enqueued successfully!"]
        [False] --> [Print String: "Failed to enqueue item."]

3.2.3. Dequeuing an Item (Dequeue Item)

To process the next item in the queue, call Dequeue Item.

[UIQT_Queue Reference] -- Dequeue Item (OutItem: FIQT_QueueItem)
    --> [Branch (Return Value: bSuccess)]
        [True] --> [Do Something with OutItem (e.g., Get User Payload, Get Ability Trigger Tag)]
        [False] --> [Print String: "Queue is empty."]

After dequeuing, you will typically use the OutItem information (such as AbilityTriggerTag or UserPayload) to trigger the actual action in your AI system or GAS.

3.2.4. Removing a Specific Item (Remove Specific Item)

If you need to cancel or remove a specific task from the queue, use this node. The item you pass must exactly match the item in the queue (Name, AbilityTriggerTag, bIsOpen).

[FIQT_QueueItem (to remove)]
--> [UIQT_Queue Reference] -- Remove Specific Item (ItemToRemove: FIQT_QueueItem)
    --> [Branch (Return Value: bSuccess)]
        [True] --> [Print String: "Item removed successfully!"]
        [False] --> [Print String: "Item not found or failed to remove."]

3.2.5. Checking Queue Status

  • Get Queue Count: Returns the number of items in the queue.
  • Is Queue Empty?: Returns true if the queue has no items.
  • Contains Item: Checks if a specific item is in the queue.
  • Get Number of Open Items / Get Number of Closed Items: Useful for tracking task progress based on your bIsOpen flag.
[UIQT_Queue Reference] -- Get Queue Count --> [Print String]
[UIQT_Queue Reference] -- Is Queue Empty? --> [Branch]

3.2.6. Searching for Items in the Queue

  • Find Item by Task ID: Searches for an item using its unique TaskID.
  • Find Item by Hash Key: Searches for an item by a combination of Name, AbilityTriggerTag, and bIsOpen.
[UIQT_Queue Reference] -- Find Item by Task ID (Task ID: [Your GUID], OutItem: FIQT_QueueItem)
    --> [Branch (Return Value: bSuccess)]
        [True] --> [Print String: "Item found!"]
        [False] --> [Print String: "Item not found."]

3.3. Using UIQT_WaitForAction (GAS Integration)

UIQT_WaitForAction is a UAbilityTask you will use within your GameplayAbilities. It allows your ability to “pause” its execution and wait for a specific GameplayTag event before proceeding.

Usage Example:

Imagine your AI needs to move to a location and only then attack an enemy. You can have a GameplayAbility for “Move and Attack.”

  1. Inside the GameplayAbility (Override ActivateAbility):
  2. Call IQT_WaitActionEvent.
  3. Define SuccessTag (e.g., Ability.Event.MoveCompleted) and FailTag (e.g., Ability.Event.MoveFailed).
  4. Set OnlyTriggerOnce to true so the task ends after the first event.
  5. Connect Delegates: Drag from the SucessesfullAction and FailedAction pins to create custom events.
[Event ActivateAbility]
--> [IQT_WaitActionEvent]
        Owning Ability: (Self)
        Success Tag: "Ability.Event.MoveCompleted"
        Fail Tag: "Ability.Event.MoveFailed"
        Optional External Target: (If the event's ASC is not your own)
        Only Trigger Once: True
        Only Match Exact: True
    --> [SucessesfullAction (Custom Event)]
        --> [Print String: "Movement complete! Now attacking."]
        --> [Call another Ability / Logic for Attack]
        --> [End Ability]
    --> [FailedAction (Custom Event)]
        --> [Print String: "Movement failed! Error handling."]
        --> [End Ability]
  1. Triggering the Event (from another location): When your character’s movement is completed (or fails), you will need to trigger the corresponding GameplayTag on the Actor’s AbilitySystemComponent.
[OnMovementFinished Event (e.g., from Character Movement Component)]
--> [Get Ability System Component from Actor] -- Send Gameplay Event (Event Tag: "Ability.Event.MoveCompleted", Event Data: [Optional Data])

This will make the UIQT_WaitForAction within your GameplayAbility “wake up” and execute the success or failure logic.

4. Best Practices and Advanced Tips

  • FIQT_QueueItem Design: Carefully consider what each FIQT_QueueItem represents in your game. UserPayload is your best friend to avoid creating multiple item structures.
  • Gameplay Tags: Use a well-organized FGameplayTag hierarchy. They are essential for the system’s flexibility, especially with UIQT_WaitForAction.
  • Consistent Priorities: If you use PriorityOrder mode, define a clear convention for your priority values.
  • Queue Monitoring: Use the GetQueueCount(), IsQueueEmpty(), GetNumOpenItems(), GetNumClosedItems() functions to debug and monitor the state of your AI or task system.
  • Thread Safety (Information for C++ Developers): UIQT_PriorityQueueInternal is thread-safe due to the use of FCriticalSection. This means you can enqueue and dequeue items from different threads without worrying about race conditions, although all Blueprint interactions must occur on the Game Thread.

5. Common Troubleshooting

  • Item Not Enqueued:
    • Check if InitializeQueue() was called.
    • Check if the queue has not reached its MaxQueueSize.
    • If bIgnoreDuplicatesOnEnqueue is true, check if the item already exists in the queue.
    • Check if the FIQT_QueueItem data is valid (ValidateQueueItemData).
  • Dequeue Item Returns Empty: The queue may be empty. Check IsQueueEmpty() before attempting to dequeue.
  • UIQT_WaitForAction Does Not Trigger:
    • Check if the GameplayTag you are sending exactly matches the SuccessTag or FailTag configured in UIQT_WaitForAction (or if OnlyMatchExact is false for child tags).
    • Ensure the GameplayTag event is being sent to the correct AbilitySystemComponent (either the OwningAbility‘s or the OptionalExternalTarget‘s).
    • Confirm that the GameplayAbility containing UIQT_WaitForAction is actually active.
Sumário