Assignment Goals

The primary goals of this assignment are:

  1. Use a template code project.
  2. Extend an Unreal Engine Pawn with C++ code to add behavior.
  3. Use delegate functions to set up collision response.

For this assignment, you'll be creating C++ AI Controller, which is Unreal's base class for controlling a Pawn. Each instance of your controller will drive a pawn following a simple boid behavioral model. You'll use an expanded collision volume to detect other nearby boids, and based on their positions and velocities attempt to follow some variation of the boid behavioral rules. There will also be one user-controlled pawn that you can use to influence flock behavior.

Details

Once again, this assignment leaves a little more of function discovery and engine navigation to you as compared to the previous assignments.

Create a project

  1. This time, create a C++ project using the Top Down template called assn3, at the top level of your git repository.
  2. This project already has a C++ character pawn and player controller, with a Blueprint data-only pawn and controller derived from them solely for parameter tweaking. Look at the controller code in assn3PlayerController.h and assn3PlayerController.cpp for some examples of how controllers typically work.

Pawn

  1. Create a data-only Blueprint Pawn, derived from the DefaultPawn class (not the Pawn base class).
    • You can search for that class in the "All Classes" section of the Blueprint Parent Class selection dialog.
    • If you choose the correct one, it should show up as a small sphere when you drag it into the scene
  2. Enable the "Simulate Physics" option in your data-only pawn under Physics/CollisionComponent.
    • At this point, if you place one or more of these pawns in the scene a little ways off the floor and hit play, they should drop to the floor. Also, the player should be able to kick them around.

Controller

  1. Create a new C++ class derived from AIController, and a new data-only Blueprint class derived from your new C++ class
  2. Set your data-only blueprint controller as the "AI Controller Class" in your data-only pawn
    • When you run with an instance of your pawn in the scene, it should create a temporary instance of your controller, which you can find by name in the "Outliner" window.

Neighbors

  1. Neighborhood tracking
    • Add a new USphereComponent to your controller detect nearby neighbors.
    • Add a radius parameter set to EditAnywhere (so you can adjust it in your data-only controller). I found a radius of about 200 to work well.
    • Add an AttachToPawn function to your controller. In this function:
      1. Use NewObject to create a new USphereComponent. Use the pawn as the parent ("outer" in UE5 terminology).
      2. Use the USphereComponent InitSphereRadius to set the sphere size.
      3. Use AttachToComponent to attach the USphereComponent to the Pawn's RootComponent.
      4. Call the USphereComponent RegisterComponent function to initialize it.
  2. Neighbor set
    • Create a TSet<APawn*> in your controller to hold the list of neighboring pawns that overlap your USphereComponent.
    • This is transient data, and should not be serialized with your pawn.
      • You can just not mark it as a UPROPERTY at all.
      • If you want to make it visible for debugging, mark it UPROPERTY(VisibleAnywhere,Transient).
  3. Neighbor tracking
    • Create OnComponentBeginOverlap and OnComponentEndOverlap delegate functions in your controller to add pawns to the set as they come in range, and remove them when they leave.
    • You can find the signature for these in delegate declarations in PrimitiveComponent.h.
    • Register them with the USphereComponent using AddDynamic() in your AI Controller's AttachToPawn function.
    • You can find a few examples creating and registering ComponentBeginOverlap delegate functions in the engine code.
    • Note that each pawn will also register as overlapping itself (since the neighbor-detecting sphere and physical sphere overlap). Check if the "Other" Actor in the overlap function is equal to GetPawn() to avoid adding yourself to your own neighbors list.

Neighbor forces

  1. In your AI Controller Tick() function, loop through the pawns in the TSet to drive the Pawn direction.
  2. Add UPROPERTY's to your controller class to control the strength of the Boid forces.
    • You will need to tune these individually. Too small, and you won't get any motion at all. Too large, and the balls will fly off of the map. Start with one at a time, starting with a small value, but increase or decrease by factors of 10 or so to help narrow down the effective scale.
  3. Use Pawn->AddMovementInput() to apply the forces
    • For the second (scale) argument to this function, use DeltaTime to scale the force with frame rate. This produces more consistent behavior as frame rate changes.

Grad Students

In addition to the ball pawn, use a Character with the SMK_Quinn model and ABP_Quinn_C blueprint animation class.

Submission

  1. For full credit, you must have multiple incremental commits during your development.
  2. Record a video of the player interacting with at least a dozen AI balls. Put the video somewhere like google drive, box, or youtube (not checked directly into your repository).
  3. Add an assn3.txt. Tell us what works and what doesn't, and anything else you think we should know for grading. Include a link to video demonstrating your project.
  4. Push to your repository, and tag your final commit with an assn3 tag (git tag assn3 followed by git push origin assn3).