Hello,
it’s hard to find some documentation for this use case, and it’s not yet very clear when to choose to use the various shared pointers, this is why I ask here if you think I did the things right:
I have a class UBBTeam inheriting from UObject, which has a reference to an other team, and holds a static array of weak pointers to some players (ABBCharacter).
Each ABBCharacter is spawned regularly in the game mode. Moreover, each ABBCharacter holds a reference to another ABBCharacter, and a reference to his owning team.
The owner of the teams is my ABBGameMode, which holds them in a static array of shared pointer.
Here are the interesting excerpts of the classes, where I have put in comments my various questions :
ABBMatchGameMode class declaration
UCLASS(minimalapi)
class ABBMatchGameMode : public AGameMode
{
GENERATED_UCLASS_BODY()
public:
virtual void PostInitializeComponents() OVERRIDE;
private:
// Is this the best way to store UObjects? Should I use UProperty() ?
TStaticArray<TSharedPtr<UBBTeam>, 2> Teamtable;
};
ABBMatchGameMode class implementation
void ABBMatchGameMode::PostInitializeComponents()
{
Super::PostInitializeComponents();
for ( int index = 0; index < 2; index++ )
{
// Not sure about that, but it seems to be the only way. But maybe TSharedPtr is not well suited for that?
TSharedPtr<UBBTeam>
team( NewObject<UBBTeam>( ) );
Teamtable[ index ] = team;
}
Teamtable[ 0 ]->SetOtherTeam( *Teamtable[ 1 ] );
Teamtable[ 1 ]->SetOtherTeam( *Teamtable[ 0 ] );
}
UBBTeam class declaration:
UCLASS()
class UBBTeam : public UObject
{
GENERATED_UCLASS_BODY()
public:
void SetPlayer( ABBCharacter & player, const int team_position_index );
void SetOtherTeam( const UBBTeam & other_team );
private:
// This one should be OK, I saw plenty of examples like this in the engine
TStaticArray<TWeakObjectPtr<ABBCharacter>, 2> PlayersTable;
// Is it okay to use TWeakObjectPtr for UObject?
TWeakObjectPtr<UBBTeam> OtherTeam;
};
UBBTeam class implementation:
void UBBTeam::SetPlayer( ABBCharacter & player, const int team_position_index )
{
PlayersTable[ team_position_index ] = &player;
player.SetTeam( *this );
}
// I prefer to pass C++ references generally. Should I use TSharedRef instead?
void UBBTeam::SetOtherTeam( const UBBTeam & other_team )
{
check( &other_team != this );
OtherTeam = &other_team;
}
ABBCharacter class declaration:
UCLASS(config=Game)
class ABBCharacter : public ACharacter
{
GENERATED_UCLASS_BODY()
public:
void SetTeam( const class UBBTeam & team );
void SetTeamMate( const ABBCharacter & team_mate );
private:
// Again, TWeakObjectPtr for both Actors and UObject. No problem?
TWeakObjectPtr<class ABBCharacter> TeamMate;
TWeakObjectPtr<class UBBTeam> Team;
};
ABBCharacter class implementation:
// C++ reference for a UObject, is it ok?
void ABBCharacter::SetTeam( const UBBTeam & team )
{
check( !Team.IsValid() );
Team = &team;
}
// C++ reference for a Actor, is it ok?
void ABBCharacter::SetTeamMate( const ABBCharacter & team_mate )
{
check( !TeamMate.IsValid( ) );
TeamMate = &team_mate;
}
What do you think?
In the shooter game, I could see:
UPROPERTY(Transient, Replicated)
TArray<class AShooterWeapon*> Inventory;
UPROPERTY(Transient)
TArray<UMaterialInstanceDynamic*> MeshMIDs;
Does this mean that it is converted automatically to smart pointers under the hood?
Thanks