Assignment Goals

The primary goals of this assignment are:

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

For this assignment, you'll be creating C++ Pawn, which is UE4's base class for anything that can be controlled by either a user or AI in a scene. Your pawn will be a rolling ball 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 the avoidance, alignment and cohesion 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 Rolling template (with no starter content) called assn3, at the top level of your git repository
  2. This project already has a C++ actor for user behavior. Look at its code in assn3Ball.h and assn3Ball.cpp, and experiment a little with how the ball moves when you play the level.

C++ pawn

  1. Create a new C++ pawn.
  2. Give it a UStaticMeshComponent and copy the initialization of both the mesh and physics parameters from the player pawn code.
  3. Add a new USphereComponent to detect nearby neighbors. Set the radius to 750 (you can tweak this later if you want). Don't forget to attach to the Pawn's RootComponent.
    • If you do not see the collision shape and size, you can turn them on by selecting "Collision" in the main viewport "Show" menu

Tracking neighbors

  1. Create a TSet<AActor*> in your AI pawn to hold the list of neighboring actors that overlap your USphereComponent.
    • This is transient data, and should not be serialized with your pawn. Either don't mark it as a UPROPERTY, or if you do to make it visible for debugging, remember to include the Transient property.
  2. Initialize this set in your BeginPlay() function using the USphereComponent's GetOverlappingActors() function.
    • Note that each AI pawn will also appear in its own list of neighbors.
    • It will also include the player pawn, so you can herd your flock by driving the player pawn around the scene.
  3. Create OnComponentBeginOverlap and OnComponentEndOverlap delegate functions to add actors to the set as they come in range, and remove them when they leave. Register them with the USphereComponent using AddDynamic() in your AI Pawn's constructor.
    • You can find the signature for these in delegate declarations in PrimitiveComponent.h.
    • You can find a few examples creating and registering ComponentBeginOverlap delgegate functions in the engine code.

Neighbor forces

  1. In your AI Pawn Tick() function, loop through the actors in the TSet to drive the pawn direction.
  2. Add UPROPERTY's to your pawn class to control the strength of the 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.
  3. Use AddImpulse() to apply the forces
    • Look at the player controlled ball for an example.
    • Add the forces one at a time to debug the force direction and scale.
    • Remove (set to 0) the Z component from any force, you apply.
  4. For cohesion, apply a force toward the average position of all of the neighbors.
  5. For the avoidance force, scale the vector to each neighbor by 1/distance3 so the closest pawn will push hardest.
  6. For alignment, apply a force in the direction of the difference between the average velocity of the neighbors and your velocity.

It can be very helpful to transform and/or scale the coefficients to all be a similar scale, and avoid really large or small values. For example, since the advoidance force is based on distance3, cubing it can help to make the values you tweak more in line with the cohesion force.

Alternately, in the code, you'll need a cohesion scale factor, c, and an avoidance scale factor, a. The cohesion and aviodance between two boids are in balance at a distance D when c D = a / D3. You could choose your UPROPERTY controls to be the rest distance and force scale or responsiveness.

Grad Students

Add a steering force to steer around other balls or obstacles "in front" of the current direction a ball is moving. Use the actor bounds and velocities to predict if the current motion would result in a collision. If so, steer the boid to avoid that collision.

Submission

  1. For full credit, you must have multiple incremental commits during your development.
  2. Use Sequencer to record behavior of 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).