Hi,
I’m trying to implement some sort of Viewrange-/Spotting-Mechanics for a simple RTS game. The goal is to directly control, exactly which Player can see a Character or not.
(btw a PlayerController owns multiple Characters, but shouldn’t be relevant to the topic)
A Character of Player1 gets replicated to a Player2, if
- Player1 is on the same Team as Player2 -> replicate
- the Character is spotted/ is within the Viewrange of any enemy Character (Viewrange is an Int stored in Character, differs from Character to Character, e.g normal GI, Sniper…)
If a Character got spotted for a while, and then isn’t in Viewrange of any enemy Character anymore, it again should only be replicated to teammembers/allies.
>>>Therefore, I wanted to override the IsRelevantFor function inherited by the AActor class. As far as I understood, the RealViewer is the PlayerController/Player, to which “this” (Actor/Character) will be replicated to or not. The ViewTarget is the OTHER Actor/Character - we want to e.g. messure the distance between him and “this”, see if we are on same team etc… Still not sure what the SrcLocation mean (looked like its only a Vector, where “this”'s mouse is looking at??)
This is what I got til now:
bool ACProjectCharacter::IsNetRelevantFor(const AActor * RealViewer, const AActor * ViewTarget, const FVector & SrcLocation) const
{
if (!(Super::IsNetRelevantFor(RealViewer, ViewTarget, SrcLocation))) {
return false;
}
const ACProjectCharacter* target = Cast<ACProjectCharacter>(ViewTarget);
if (target != nullptr) {
if (this->TeamID == target->TeamID) {
return true;
}
else {
float dist;
FVector fV;
fV = this->GetActorLocation() - target->GetActorLocation();
dist = fV.Size();
if (this->GetSpotter() == nullptr) {
if (dist <= target->Viewrange) {
this->Spotter = target; // ERROR: can't assign value from const type to a non const type
return true;
} else {
return false;
}
} else if (Spotter == target) {
if (dist <= target->Viewrange) {
return true;
} else {
this->Spotter = nullptr;
return false;
}
}
}
}
}
The Code worked fine before - when I only checked the TeamID and the distance between this and the ViewTarget, but now as I brought the Spotter variable in, I run into some troubles. Pretty sure, c++ guys were smiling already while reading the code
But why do I even need a Spotter?
My thoughts were: If I (this Character) get spotted by EnemyCharacter1, I’ll get replicated; but in the next moment IsRelevantNetFor() is executed for another Actor EnemyCharater2, and I am NOT in the Viewrange of him, so the function returns false, and I am not replicated anymore, ALTHOUGH I AM still spotted by EnemyCharacter1. Therefore I wanted to save who spotted me, so not every other EnemyCharacter can set my Replication to false.
>>>But back to the Problem, i am stuck in: It is of course: CONST
As far as the IsNetRelevant function is tagged as const, I can’t modify any variables (members?) in this Character object, neither I can call a function, that is not const/changes any variables. Is this correct like this?
Before I tagged Spotter as mutable, “this->Spotter = target” I got error like “can’t assign value to a non mutable member”. But now I get something like “can’t assign value from const type to a non const type”.
>>> So what would be a proper way to implement this/ how to handle stuff like this with IsNetRelevantfor?
I am sure I still need to override the IsNetRelevant function, or is there another way to replicate an actor to specific Players only? Or do I need to do the calculations somewhere else (e.g. in GameMode: get through all Characters in Team0, foreach Character in Team1 calculate distance, and then set a simple bIsSpotted and (in case) the SpotterVariable;
IsNetRelevantFor() only needs to check these Values then, and replicates accordingly?)
I am not too happy with this solution, GameMode seems to do and hold so much stuff/calculations in it. Would like to “outsource” as much as I can, but GameMode is best choice to hold things like Teams, PlayerControllerList/CharacterList, Calculations etc, isn’t it?
Thank you in advance for all your input/workflows,
Regards
PS: Sorry, this text got so long… Tried to make things clear and readable, also if others got troubles with this and come upon this thread.