Setting up team colors

Fairly simple question.

I don’t see the need to make a complex team class. For every client that joins, I look at the current players and team they are on (they all have a TeamNum in the playerstate), and I assign they new player their number to keep things balance. Now, my question is… how should I handle team colors?

I’m thinking of two ways to do it, but if anyone has a better idea please feel free to share. My first way would be to just have a static array of colors in the game mode, where the index represent the teams color. Since clients don’t have access to the gamemode pointer, this should make colors accessible. My other idea was to just have a color associated with the playerstate as well (TeamColor). When the server assigns the team, it will also assign a color as well.

Is one better than the other? Are there better ideas? Should a create a whole struct that can be replicated (if that’s possible? Can you replicate a struct?), that has a teamNum, teamColor, teamName, etc. associated with it.

Thanks a bunch for your time all!

  • Austin

Hm, i guess you could make material that has both colors in it. Blend it with a scalarparameter and use the TeamNum for that.

0 - Blue

1 - Red

That should work, but i can’t tell you what would be the best way to replicate this. The Server got all PlayerStates, so replicaten TeamNum would be an option. Letting the client use this replicated number to set the scalar paramter.

Yes you can replicate structures.
The easiest way would be to:

  1. Create a material with both colors and a float parameter, like eXi said.
  2. Your TeamNumber variable should be Replicable with notify.
  3. On notification recieved, set the material parameter to the TeamNumber.

The reason why you need to use notification, is because of the way objects are spawned. Since you can’t pass arguments by constructor, the objects will be created with the default TeamNumber and replicated before you have a chance to set its team.

The notification would look something like this (Ignore/Update the the “[…]”):

.h

...
UPROPERTY(ReplicatedUsing = OnRep_UpdateTeamID)
Float TeamNumber;
...

.cpp

...
void [YourClassHERE]::OnRep_UpdateTeamID(){
	UMaterialInstanceDynamic* MatInst = GetMesh()->CreateAndSetMaterialInstanceDynamic([YourMaterialIndex]);
	MatInst->SetScalarParameterValue(FName(TEXT("[YourParamName]")), TeamNumber);
}
...

Enjoy!

As far as I know that is exactly why. UE4 classes have a fixed constructor that take a FObjectInitializer. In theory It could be possible to make you own constructor that takes additional arguments, but then you would need to create your own SpawnActor function(probably by extending UWorld) in order to pass them to the constructor.

To be honest, I Never tried to do it! :stuck_out_tongue:

Question from me: You can’t pass arguments by constructor? That’s a limitation, because of the way objects are spawned by the engine or? o.o

I’m more the BP guy by now (just wrote my c++ exam though), so i still need to learn alot about UE4 c++.

Ok thank you. Adding the standard values after spawning the actor isn’t that bad, but i would love to have a constructor for that (since this is one of the main c++ object things >.<). Maybe i will read myself into it (regarding the ue4 source) to change the constructor like i want to (together with the spawn function)

Its almost instantaneous anyway (unless there is Network issues). One thing you could/should do, is to set the default to a number that isn’t used by either teams, this way avoiding a player starting as “enemy” in case of a delay.

In any case once you made it work, don’t forget to mark an answer.

Yeah. I was going to do that as its how the shooter game example does it, but that’s not very extensible. It basically limits you to two teams and also makes it difficult to get the team color associated with a player if you ever need it.

Like I said in eXi’s response, I don’t really like the way that works because it’s too limiting. If I want to make a game with 6 teams for some reason, things become complicated. That’s why I was suggesting ideas of the server trekking the clients their colors as well. Or static function somewhere to get a color based on team number.

Thanks for your response!

If you want to associate team with numbers, why not create arrays with team meta data (color, name etc.) which let you translate number to something else, UT3 does that (look on default propeties on bottom):

www.codekisk.com/unreal/ut3/scriptref/Source_utgame/utteaminfo.html

You can make a formula to create a color based on the TeamID (like multiplying the RGB values by it). Regardless the implementation is the same, the client sets the color.

You only need to calculate/apply the color once per spawn, so it doesn’t matter if you store it or not. If you really want, you can have each client save its own color it in the Playerstate, since it is replicated to all clients, then use that to change a Vector3 parameter in the material.

If you want a lot of info on a team, like team names, team icons, etc… then it makes sense.

Why not just changing the whole material? If you have a number from 0 to 5 (so 6 different teams), you can just replicate the TeamNum and let the character change it’s complete material (so you have 6 materials). They all just differ in the color. I guess you could also directly replicate the material variable that is used to define the mat.

This way you can have a lot of team colors.

And why is it difficult to associate the team color with a player? You have the TeamNumber that tells you who is on which team. You could also use an enum to have “Red” “Blue” etc as TeamName and use the same as the Int value for team num.

That’s kind of where I was leading to when I was talking about a struct. Thanks for the link, I’ll dive into it now.

So I guess this is the route I’l go, except probably make a struct vs. a class since the data I’ll be storing probably wont change one the server sends it to client.

Thanks !

I think I found a way to avoid around the construtor to “pass” the variables, but I have not tested it.

While you can’t pass argument via contructor, you can postpone the spawning of the actor by using “SpawnActorDeferred(…)”. This should allow you to set the variables and then finish with “UGameplayStatics::FinishSpawningActor(…)”.

Assuming that the server will only replicate after spawning is complete, it should work. This would also not require you to implement the notify, and simply set the colors in the BeginPlay()… that is unless you plan on making the players change teams on the fly (without respawning).