Adding Text Chat to UE4 in C++

Note, this is a C++ based example. However, it’s easily converted to BP.

If you want to just check out the code or skip the guide then you can download the project here.

There are a few things wrong with this setup such as no deletion of messages so you’ll keep a copy of them until you exit the game so you’re probably going to want to set up a timer to destroy them after x time.

 

  1. Open your PlayerController class and add a struct called FChatMessage.
C++
USTRUCT(BlueprintType)
struct FChatMessage
{
    GENERATED_BODY()

    UPROPERTY(BlueprintReadWrite)
    FDateTime Time;

    UPROPERTY(BlueprintReadWrite)
    FString Message;

    UPROPERTY(BlueprintReadWrite)
    FColor Color;

    UPROPERTY(BlueprintReadWrite)
    class APlayerState* Sender;

    FChatMessage() : Time(FDateTime::Now()), Message("No Message"), Color(FColor::White) {}
    FChatMessage(const FString& message) : Time(FDateTime::Now()), Message(message), Color(FColor::White) {}
    FChatMessage(const FDateTime& time, const FString& message, const FColor& color, class APlayerState* sender) : Time(time), Message(message), Color(color), Sender(sender) {}
};
  1. Add a delegate in the PlayerController for receiving chat messages. DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnChatMessageReceived, const FChatMessage&, ChatMessage);
  2. Add 2 methods and the delegate to your PlayerController class.
C++
UFUNCTION(BlueprintCallable, Server, Reliable, WithValidation)
void Server_SendChatMessage(const FChatMessage& ChatMessage);

UFUNCTION(Client, Reliable)
void Client_ReceiveChatMessage(const FChatMessage& ChatMessage);

UPROPERTY(BlueprintAssignable, meta = (DisplayName = "OnChatMessageReceived"))
FOnChatMessageReceived m_OnChatMessageReceived;
  1. Create the implementation of these methods.
C++
bool ATCPlayerController::Server_SendChatMessage_Validate(const FChatMessage& ChatMessage) { return true; }
void ATCPlayerController::Server_SendChatMessage_Implementation(const FChatMessage& ChatMessage)
{
    // Our message is empty or the sender is null so don't send a message
    if (ChatMessage.Message.IsEmpty() || ChatMessage.Sender == nullptr)
    {
        return;
    }

    // Iterate over all clients in the map and send the message to them
    for (FConstPlayerControllerIterator Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator)
    {
        if (ATCPlayerController* const PC = Cast<ATCPlayerController>(*Iterator))
        {
            PC->Client_ReceiveChatMessage(ChatMessage);
        }
    }
}

void ATCPlayerController::Client_ReceiveChatMessage_Implementation(const FChatMessage& ChatMessage)
{
    m_OnChatMessageReceived.Broadcast(ChatMessage);
}