89 lines
3.2 KiB
C++
89 lines
3.2 KiB
C++
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Components/WidgetComponent.h"
|
|
#include "PlayerNameplateComponent.generated.h"
|
|
|
|
class APlayerState;
|
|
|
|
/**
|
|
* L'etiquette de pseudo posee au-dessus d'un joueur.
|
|
*
|
|
* Herite de UWidgetComponent et le configure en espace ECRAN : c'est ce qui la
|
|
* fait toujours faire face a la camera, gratuitement et exactement, sans le
|
|
* moindre calcul d'orientation par frame. En espace Monde il faudrait la
|
|
* reorienter soi-meme a chaque image, et elle serait occultee par le decor --
|
|
* un pseudo qui disparait derriere un caillou n'aide personne.
|
|
*
|
|
* Contrepartie assumee de l'espace ecran : la taille ne diminue pas avec la
|
|
* distance. C'est le comportement des jeux coop du genre, et c'est justement
|
|
* pourquoi une distance de disparition est indispensable -- sans elle, quatre
|
|
* pseudos resteraient lisibles a l'autre bout de la carte.
|
|
*
|
|
* Le composant ne replique RIEN : le pseudo vit deja sur le PlayerState, qui
|
|
* est replique par le moteur. Ajouter une propriete ici enverrait deux fois la
|
|
* meme chaine sur le reseau.
|
|
*/
|
|
UCLASS(ClassGroup = (Survival), meta = (BlueprintSpawnableComponent))
|
|
class SURVIVAL_PROJET_API UPlayerNameplateComponent : public UWidgetComponent
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
UPlayerNameplateComponent();
|
|
|
|
virtual void BeginPlay() override;
|
|
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
|
|
|
protected:
|
|
/**
|
|
* Au-dela de cette distance, l'etiquette disparait. 2500 cm = 25 m, soit un
|
|
* peu plus que la portee a laquelle on distingue un coequipier dans un
|
|
* decor dense.
|
|
*/
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Nameplate", meta = (ClampMin = "100", Units = "cm"))
|
|
float MaxDrawDistance = 2500.f;
|
|
|
|
/**
|
|
* Periode de reevaluation, en secondes.
|
|
*
|
|
* Un timer et pas un Tick : la distance a la camera n'a aucune raison
|
|
* d'etre recalculee 120 fois par seconde pour une etiquette qui apparait ou
|
|
* disparait une fois toutes les dix secondes. Quatre joueurs a 120 ips
|
|
* feraient 480 calculs de distance par seconde pour rien.
|
|
*/
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Nameplate", meta = (ClampMin = "0.05", Units = "s"))
|
|
float RefreshInterval = 0.25f;
|
|
|
|
/**
|
|
* Cacher l'etiquette de son PROPRE personnage.
|
|
*
|
|
* Vrai par defaut : en vue premiere personne on ne voit jamais son propre
|
|
* corps, mais une etiquette en espace ecran, elle, se projetterait en plein
|
|
* milieu du viseur.
|
|
*/
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Nameplate")
|
|
bool bHideOnOwningPlayer = true;
|
|
|
|
private:
|
|
/** Distance a la camera locale, puis mise a jour du texte si besoin. */
|
|
void Refresh();
|
|
|
|
/** Le PlayerState du pawn porteur, ou nullptr tant qu'il n'est pas arrive. */
|
|
APlayerState* GetOwnerPlayerState() const;
|
|
|
|
FTimerHandle RefreshTimer;
|
|
|
|
/**
|
|
* Dernier pseudo reellement ecrit dans le widget.
|
|
*
|
|
* Le PlayerState arrive APRES le pawn chez un client : la premiere passe
|
|
* trouve donc un nom vide, et il faut continuer a regarder. Comparer plutot
|
|
* que reecrire evite de reconstruire la mise en page du Text Block quatre
|
|
* fois par seconde pour une chaine identique.
|
|
*/
|
|
FString LastShownName;
|
|
};
|