Mounts

The Mount is any Actor you want your player's character or selected character to sit on or get in to.  This guide will cover the Components and interfaces used by Mount Actors in a general overview of what these functions do.  

References

For a more comprehensive demonstration of how the interfaces and components are implemented for the mounts, download the Demo Projects and inspect the following Classes listed below.  Additionally these plugins are designed to be dropped into your project as they are and form a basis for your implementation if you just want to get started quickly.  To Download the Demos see Quick Start Guide.

Mounting System Tutorial Core (MSTC)

BP_MST_MountCharacterBase

This blueprint represents a generic blueprint implementation for all character based mounts.  It has no Mesh or Animations associated with it and does not have any Seats defined in the UMountablePawnComponent.

Mounting System Tutorial (MST)

BP_MST_RobotHorse 

This is a child class of the BP_MST_MountCharacter.  It has a Skeletal mesh setup for it which also has predefined Sockets on its skeleton for where the Driver and Passenger should be setup.  It also defines both the Driver and Passenger Seat in the UMountablePawnComponent.

See the tutorial on Mount Seats for more information on setting up Seats.

Advanced Mounting System (AMS)

AAmsMountCharacterBase

This C++ class forms the base class to the Character Based Mounts in the Advanced System.  It does not define any Mesh or Animations to use with it nor does it define any seats for its UMountablePawnComponent.  

BP_AMS_RobotHorse

This Blueprint class is a child class of the AAmsMountCharacterBase.  Primarily this class gives the mount a mesh and defines seats for the Driver and Passengers to attach to.  In Addition it overrides a few mount related functions responsible for finding Mounting and Dismounting Directions based on player camera rotation and initializes the mounts input scheme for the Driver.

Demo References

For a more comprehensive demonstration of how the interfaces and components are implemented together download the Demo Projects and inspect the following Classes

Mounting System Tutorial Core (MSTC)

BP_MST_MountCharacter 

This blueprint represents a generic blueprint implementation for all character based mounts.  It has no Mesh or Animations associated with it and does not have any Seats defined in the UMountablePawnComponent.

Mounting System Tutorial (MST)

BP_MST_RobotHorse 

This is a child class of the BP_MST_MountCharacter.  It has a Skeletal mesh setup for it which also has predefined Sockets on its skeleton for where the Driver and Passenger should be setup.  It also defines both the Driver and Passenger Seat in the UMountablePawnComponent.

See the tutorial on Mount Seats for more information on setting up Seats.

Advanced Mounting System

AAmsMountCharacterBase

This C++ class forms the base class to the Character Based Mounts in the Advanced System.  It does not define any Mesh or Animations to use with it nor does it define any seats for its UMountablePawnComponent.  

BP_AMS_RobotHorse

This Blueprint class is a child class of the AAmsMountCharacterBase.  Primarily this class gives the mount a mesh and defines seats for the Driver and Passengers to attach to.  In Addition it overrides a few mount related functions responsible for finding Mounting and Dismounting Directions based on player camera rotation and initializes the mounts input scheme for the Driver.

Component and Interface

The Mount needs 3 things to be added to it so that it works with the PNMS System

Add MountablePawnComponent

In the Components section of your blueprint add the UMountablePawnComponent to it.  Alternatively in C++ declare the UMountRiderComponent as a variable and create it in the constructor of the Rider Class.  This component has most of the functionality you will need to implement the following interfaces.

Add IADMUnifiedControllerPawn Interface

For blueprints, in the Interface list in Class Settings add the Unified Controller Pawn Interface.  This interface's purpose is to act as a unifying method of retrieving the Core Actor types of Controller, Rider, and Mount between these three actor type. 

Add the IMountablePawn Interface

In the Inteface list in Class Settings add the IMountablePawn Interface.  This interface's purpose is to give the external world access to key functionalities and information kept within the UMountablePawnComponent.

MountablePawnComponent Settings

The UMountablePawnComponent has a few settings to keep in mind.

Flag: IsMountable

This flag allows you to completely turn off the ability of any thing to mount this character.  From a gameplay standpoint the mount may have become enraged or Feral and can no longer be mounted.

It may also be useful if you have defined a parent Class or Blueprint that you want mountable and then decide that this subclass or Blueprint should not be mountable.  Generally you want to avoid having to change this for such a reason as it is considered bad practice.

FSeatManager: SeatManager

This struct contains the definition of all the seats the mount has available to it.  It also holds important information such as how characters mount and dismount from the seats and what directions are valid for mounting and dismounting from the seats.  Generally your Base classes will not include seat definitions unless you have put a lot of work into standardizing your mounts.

We will cover more about setting up your seats later.

Implement the IADMUnifiedControllerPawn Interface

Implementing the functions of the IADMUnifiedControllerPawn interface is fairly straight forward and is similar to the Controller and Rider setup.

PrepareToMount

This function is a preparatory function called by the Controller to make sure that any necessary prerequisites needed for Mounting to Proceed.  On the Mount this allows the controller to detect if the Mount is ready to perform mounting for any reason.  If this function returns false then the entire mounting process stops.  

For the most basic implementations you can simply return true but there maybe some reasons you would want to return false.  You may require the mount to be tamed first.  This can be a place to check if the mount has achieved the prerequisite.  This function also exists on the Rider and the Controller as well so each of these three classes can define their own rules about canceling a mounting operation.

Return

  • bool - If this operation returns false then the mounting process will give an error return and stop the mounting operation.

Implementation

For the demo purposes this function simply returns true.

PrepareToDismount

This function is a preparatory function called by the Controller to make sure that any necessary prerequisites needed for Dismounting to Proceed.  On the Mount this allows the controller to detect if the Mount is ready to perform dismounting.  If this function returns false then the entire dismounting process stops.  

For the most basic implementation you can simply return true, but there maybe reasons you would want to return false.  You may have certain mounts that are on a fixed path that move through the world with the player but are not directly controlled by the player.  You may need players to stay sitting and enjoy the trip rather than dismount randomly.

Return

  • bool - If this operation returns false then the mounting process will give an error return and stop the mounting operation.

Implementation

For the demo purposes this function simply returns true.

IsMounted

This function simply returns if the UMountablePawnComponent has mounted Riders on it

Return

  • bool - if true, then the mount is currently mounted or is being mounting by a Rider.  If false then mount has no riders.

Implementation

Return the function  UMountablePawnComponent::IsMounted().

GetCharacterPawn

This function allows you to easily get the Mount's Driver

Return

  • APawn - Gets the current Driver of the Mount if it has one.  If no driver is present then this returns null.

Implementation

Return the function UMountablePawnComponent::GetDriver().

GetCharacterMount

This function allows you to easily get the current mount of the player or AI entity. 

Return

  • AActor - Always gets the Actor that the UMountablePawnComponent belongs to.

Implementation

Return the function UMountablePawnComponent::GetOwner() in C++ or self in Blueprints

GetCharacterController

This function allows you to easily get the controller of the player or AI entity. 

Return

  • AController - Always returns the controller of the mount, reguardless of what controller is currently controlling it.

Implementation

Return the function APawn::GetController() for Pawn and Character classes or Null or None for Actor Classes as they are not controllable.

Implement the IMountablePawn Interface

Implementing the functions of the IMountablePawn interface is fairly straight forward.  The Majority of it is getter and Setter functions.

IsMountableActor

This function returns if the mount is enabled for mounting or not.

Return

  • bool - Returns true if the mount is capable of being mounted.

Implementation

Return the function UMountablePawnComponent::CanMount().

IsMountableByPawn

Indicates that the supplied Pawn is capable of mounting this actor.  This allows you to inspect the Pawn and determine that it has the requirements needed to Mount this Mount.  For example you may require the Mount to be owned by the Pawn, this is a method of determining prerequisites.  This function is not explicitly called anywhere and so must be placed strategically within your functions.  

Parameters

  • NewRider - The actor trying to get onto the Mount.

Return

  • bool - Returns true if this mount can attach to the mount or not.

Implementation

The implementation of this function is left entirely up to the Developer.

GetMaxRiders

Gets the maximum number of riders the mount can support

Return

  • int32 - number of available seats on the mount.

Implementation

Return the function UMountablePawnComponent::GetNumSeats().

IsDriverSeat

This function is used to determine if the supplied SeatData structure belongs to the Driver Seat.

Parameters

  • SeatData - the FSeatData struct to validate if the it is the Driver Seat for.

Return

  • bool - returns true if the supplied FSeatData is the Driver Seat

Implementation

return the function UMountablePawnComponent::IsDriverSeat(SeatData).

HasDriver

This function returns weather or not this mount has an active Driver or not.

Return

  • bool - returns true if the mount has a driver

Implementation

return the function UMountablePawnComponent::HasDriver().

GetDriver

This function gets the current Driver of the Mount

Return

  • APawn - returns the Driver of the Mount.

Implementation

return the function UMountablePawnComponent::GetDriver().

IsDriverReady

This function is used to determine if the Driver of the Mount is in a ready state, that it is fully attached and seated to the mount.

Return

  • bool -returns true if the driver is ready.

Implementation

Use the function IMountablePawnInterface::GetDriver() to check if the rider currently has a Driver associated with it.

If the Driver is Valid then return the interface function IMountRiderInterface::IsSeatedOnMount().  Otherwise return false.

HasPassengers

This function returns if the Mount has passengers mounted to it.  This includes Drivers and any other character attached.

Return

  • bool - returns true if there are any mounted actors.

Implementation

To implement call the function UMountablePawnComponent::GetNumRiders() to get the number of riders currently on the mount.

Check if the returned number of riders is greater than 0 and return true if it is, other wise return false.

GetCurrentRiderCount

This function gets the current number of Riders mounted on the mount.

Return

  • int32 - the number of riders on the mount.

Implementation

To implement call the function UMountablePawnComponent::GetNumRiders() to get the number of riders currently on the mount.

IsSeatOccupiedById

Checks if a the seat specified by the ID is currently occupied or is available.

Parameters

  • SeatId - the ID of the seat to be attached to.

Return

  • bool - Returns true if the seat is occupied and false if it is available.

Implementation

Return the function UMountablePawnComponent::IsSeatOccupiedById(SeatId).

IsSeatOccupiedAtIndex

Checks if a the seat specified by the Index is currently occupied or is available.

Parameters

  • SeatIndex - the index of the seat to be attached to.

Return

  • bool - Returns true if the seat is occupied and false if it is available.

Implementation

Return the function UMountablePawnComponent::IsSeatOccupiedAtIndex(SeatIndex).

MustHaveDriver

Returns true if the Mount must have a Driver or it is can be mounted by players without a driver specified.

Return

  • bool - Returns true if the mount's first passenger must be the driver

Implementation

Return the function UMountablePawnComponent::MustHaveDriver().

GetSeatDataById

Gets a copy of the seat data specified by the seat id

Parameters

  • SeatId - The seat Identifier you want to get the information for

Return

  • SeatData - out parameter that contains the Seat Data of the specified seat
  • bool - if this function returns true then it means that the the seat with the specified id was found and returned.

Implementation

Return the function UMountablePawnComponent::GetSeatDataById(SeatId, SeatData).

GetSeatDataAtIndex

Gets a copy of the seat data specified at the Seat Index.

Parameters

  • SeatIndex - The seat index you want to get the information for

Return

  • SeatData - out parameter that contains the Seat Data of the specified seat
  • bool - if this function returns true then it means that the the seat with the specified index was found and returned.
Implementation

 

Return the function UMountablePawnComponent::GetSeatDataAtIndex(SeatIndex, SeatData).

GetMountBody

Get the Mount Mesh Body.  You can return different meshes based on the seat ID, this is useful for things such as linked actors.  For things like an animal mount you will probably ignore the seat ID.  For more complicated mounts like a buggy being pulled by an animal or truck with a trailer, or a train with multiple cars the mesh body maybe different than the actual mount body.

Parameters

  • SeatId - the id of the seat you want to get the mesh body for.

Return

  • UMeshComponent - the UMeshComponent that corresponds the the seat id.

Implementation

For the demo we simply return the "Mesh" component of the Character mount. 

GetMountablePawnComponent

This function serves as a catch all to allow you to retrieve the UMountablePawnComponent directly and call functions and get information out of it without having to leverage an existing interface function.  Additionally you should create custom interfaces in C++ or blueprint to make it easier to get these bits of information.

Return

  • UMountablePawnComponent - the component for the mount.

Implementation

Return the UMountablePawnComponent itself.

GetRelativeMountDirection

Given a Rider that is mounting, use this function to determine the relative direction that the rider can mount from.  For demo purposes we will specify the return value as "Any Side".

Parameters

  • Rider - Rider you want to determine their relative location to the mount for.

Return

  • EMountDirection - Calculated Mount Direction you want the rider to mount from.

Implementation

For the demo we simply return the "Any Side" value.  The PNM System also has a few function library functions that you can use to determine how much to the right, left, front, back, up or down relative to the mount.  

  • UAdsMountingSystemLibrary::GetAngleFromForwardBetweenActors(MountActor, RiderActor)
  • UAdsMountingSystemLibrary::GetAngleFromRightBetweenActors(MountActor, RiderActor)
  • UAdsMountingSystemLibrary::GetAngleFromUpBetweenActors(MountActor, RiderActor)

CanMountAtPosition

This function returns true if a rider is able to mount from the specified  position.  This function is not used as part of the PNM System and would need to be manually implemented.

Parameters

  • RiderLocation - the FVector location of the rider currently.
  • DesiredMountingPosition - the EMountDirection to select a mounting point for.

Return

  • Bool - if true than a seat was found that matched the desired Position and Location.

Implementation

return the function UMountablePawnComponent::FindAvailableMountingPosition(Position, RiderLocation, OutSeatData, OutSeatIndex).

CanMountActor

This function is called as part of the PNM System to determine if the mount can be mounted.

Parameters

  • NewRider - the new rider that wants to mount.

Return

  • Bool -true if the supplied rider can mount the Pawn.

Implementation

To Implement this function in the Demo begin by calling the IMountablePawnInterface::GetMaxRiders() and IMountablePawnInterface::GetCurrentRiderCount() to determine if Max Riders is larger then the Current Number of Riders..  

Then use the IMountablePawnInterface::IsMountableActor()

If MaxRiders is less than CurrentRiders and the mount IsMountable then the demo considers this pawn mountable.

FindAvailableMountingPosition

This function is called internally by the PNM System after retrieving a Position from IMountablePawnInterface::GetRelativeMountDirection().

Parameters

  • Position - the EMountDirection to select a mounting point for.
  • RiderLocation - the FVector location of the rider currently.

Return

  • OutSeatData - The FSeatData that was found.
  • OutSeatIndex - The index of the Seat selected if one is found.  If no seat was found this will return -1.
  • Bool - if true than a seat was found that matched the desired Position and Location.

Implementation

return the function UMountablePawnComponent::FindAvailableMountingPosition(Position, RiderLocation, OutSeatData, OutSeatIndex).

SetSeatOccupiedById

Sets a Seat as Occupied by its Identifier. This is the most common method for setting the seat occupancy.  The Seat ID corresponds to the ID given or generated for it in the FSeatManager.

Parameters

  • SeatId - the id of the seat you want to set occupied
  • Rider - The Rider you want to set as occupying the Seat

Return 

  • bool - Returns if the seat was able to be set at the specified ID for the rider.

Implementation

Return the function UMountablePawnComponent::SetSEatOccupiedById(SeatId, Rider)

SetSeatOccupiedAtIndex

Sets a Seat as Occupied by its Identifier.   This is the least common method of setting  a seat as occupied.  The SeatIndex corresponds to the seats location in the FSeatManager::Seats TArray.

Parameters

  • SeatIndex - The index of the seat to set as occupied
  • Rider - The Rider you want to set as occupying the Seat

Return

  • bool - Returns if the seat was able to be set at the specified Index for the rider or false if it failed to do so.

Implementation

Return the function UMountablePawnComponent::SetSeatOccupiedAtIndex(SeatIndex, Rider)

ClearSeatById

Clears the seat of occupancy from the mount by the seat ID and opens it up for future mounting and occupancy.

Parameters

  • SeatId - the id of the seat you want to clear the occupancy from.

Return

  • bool - Returns if the seat was able to be set at the specified Index.

Implementation

Return the function UMountablePawnComponent::ClearSeatById(SeatId).

ClearSeatAtIndex

Clears the seat of occupancy from the mount by the seat index and opens it up for future mounting and occupancy.

Parameters

  • SeatIndex - the index of the seat you want to clear the occupancy from.

Return

  • bool - Returns if the seat was able to be cleared at the specified Index.

Implementation

Return the function UMountablePawnComponent::ClearSeatAtIndex(SeatIndex).

OnRiderFinishedMounting

This is called on the mount when ever a rider has finished their mounting process.  It is a hook to allow you to update custom logic you may want such as a UI element on the Mount. 

Parameters

  • MountedActor - The Rider you want to set as occupying the Seat
  • SeatId - The seat Identifier that the Actor was set to occupy.

Return

  • bool - This function has a bool return only so that it remains a proper function and is not translated into an Event within Blueprints.  You can return true or false for this with out consequence.

Implementation

Return the function UMountablePawnComponent::RiderFinishedMounting(SeatId, MountedActor).  Additionally this function is responsible for notifying the PlayerController and calling the IRiderControllerInterfacer::OnRiderAdded() function.

OnRiderFinishedDismounting

This is called on the mount whenever a rider has finished their dismounting process.  It is a hook to allow you to update custom logic you may want such as a UI element on the Mount. 

Parameters

  • DismountedActor- The Rider that dismounted
  • SeatId - The seat Identifier that the Actor was removed from.

Return

  • bool - This function has a bool return only so that it remains a proper function and is not translated into an Event within Blueprints.  You can return true or false for this with out consequence..

Implementation

Call the function UMountablePawnComponent::RiderFinishedDismounting(SeatId, DismountedActor).  Additionally this function is responsible for notifying the PlayerController and calling the IRiderControllerInterfacer::OnRiderRemoved() function.

Additionally this is a good spot to check if the Rider removed was the Driver of the Mount and have an AI Controller repossess the mount if Driver is no longer controlling the mount.

OnRiderFinishedChangingSeats

This is called on the mount whenever a rider has finished their change seat process.  It is a hook to allow you to update custom logic you may want such as a UI element on the Mount. 

Parameters

  • Rider - The Rider that changed seats
  • NewSeatId - the new seat that the rider is attached to
  • OldSeatId - the seat the rider orginally occupied

Return

  • bool - This function has a bool return only so that it remains a proper function and is not translated into an Event within Blueprints.  You can return true or false for this with out consequence..

Implementation

Call the function UMountablePawnComponent::RiderFinishedChangingSeats(Rider, NewSeatId, OldSeatId).  Additionally this function is responsible for notifying the PlayerController and calling the IRiderControllerInterfacer::OnOtherRiderChangedSeats() function.

Additionally this is a good spot to check if the Rider changed seat away from the Driver Seat of the Mount and have an AI Controller repossess the mount if Driver is no longer controlling the mount.  The PNM System already handles what happens if a Rider moves to an unoccupied Driver Seat but does not cover what happens if a rider moves away, that is left up to the Developers to determine.

Next Section: Demo Animations