Files
Unreal_EmberWild/Source/Survival_projet/Public/CharacterPreviewActor.h
T
2026-08-11 15:23:10 +02:00

147 lines
5.2 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "CharacterAppearanceTypes.h"
#include "CharacterPreviewActor.generated.h"
class UCameraComponent;
class UCharacterAppearanceComponent;
class USkeletalMeshComponent;
/**
* Les deux cadrages de l'ecran de customisation.
*
* Deux et pas un par categorie : ce qu'on veut, c'est voir le visage quand on
* choisit une barbe et la silhouette entiere quand on choisit un corps. Un
* cadrage par categorie donnerait onze reglages a poser a la main pour onze
* fois le meme resultat.
*/
UENUM(BlueprintType)
enum class ECharacterPreviewFraming : uint8
{
FullBody,
Face,
Count UMETA(Hidden)
};
/**
* Le mannequin de l'ecran de customisation : un personnage pose dans la map de
* menu, qu'on fait tourner a la souris et que la camera cadre selon ce que le
* joueur est en train de regler.
*
* Il porte le MEME UCharacterAppearanceComponent que le pawn de jeu, et c'est
* tout l'interet : le personnage qu'on regarde ici est monte par exactement le
* code qui montera celui que les autres joueurs verront. Deux chemins de
* montage finiraient par diverger, et le joueur s'en apercevrait au pire
* moment -- une fois en partie.
*/
UCLASS()
class SURVIVAL_PROJET_API ACharacterPreviewActor : public AActor
{
GENERATED_BODY()
public:
ACharacterPreviewActor();
virtual void Tick(float DeltaSeconds) override;
/** Monte l'apparence sur le mannequin. */
UFUNCTION(BlueprintCallable, Category = "Preview")
void ApplyAppearance(const FCharacterAppearance& InAppearance);
/** La camera glisse vers le cadrage demande. Sans effet s'il y est deja. */
UFUNCTION(BlueprintCallable, Category = "Preview")
void SetFraming(ECharacterPreviewFraming NewFraming);
/** Fait pivoter le personnage. Appelee pendant un clic-glisser. */
UFUNCTION(BlueprintCallable, Category = "Preview")
void AddPreviewYaw(float DeltaDegrees);
/** Remet le personnage face a la camera. */
UFUNCTION(BlueprintCallable, Category = "Preview")
void ResetPreviewYaw();
UFUNCTION(BlueprintPure, Category = "Preview")
UCameraComponent* GetPreviewCamera() const { return PreviewCamera; }
UFUNCTION(BlueprintPure, Category = "Preview")
UCharacterAppearanceComponent* GetAppearanceComponent() const { return AppearanceComponent; }
/** Le reglage vit ici et pas sur le widget : c'est une sensibilite de camera. */
UFUNCTION(BlueprintPure, Category = "Preview")
float GetYawPerPixel() const { return YawPerPixel; }
protected:
virtual void BeginPlay() override;
/** Le porteur d'animation et de pose ; les pieces s'y accrochent. */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Preview")
TObjectPtr<USkeletalMeshComponent> BodyMesh;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Preview")
TObjectPtr<UCharacterAppearanceComponent> AppearanceComponent;
/**
* Pivot de rotation, entre la racine et le mesh.
*
* Le personnage tourne en faisant pivoter CE composant et jamais l'acteur :
* la camera est fille de l'acteur, la faire tourner avec lui donnerait un
* decor qui defile pendant qu'on regarde un personnage immobile.
*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Preview")
TObjectPtr<USceneComponent> TurntablePivot;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Preview")
TObjectPtr<UCameraComponent> PreviewCamera;
/**
* Les deux positions de camera, a placer A LA SOURIS dans le viewport du
* Blueprint plutot qu'a taper en coordonnees.
*
* Ce sont des reperes vides : la camera n'y est pas accrochee, elle glisse
* vers eux. Sans quoi changer de categorie la ferait sauter d'un cadrage a
* l'autre, ce qui se lit comme une coupure de montage.
*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Preview|Framing")
TObjectPtr<USceneComponent> FullBodyViewSpot;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Preview|Framing")
TObjectPtr<USceneComponent> FaceViewSpot;
/**
* Vitesse de glissement de la camera entre deux cadrages.
*
* Une vitesse d'interpolation et pas une duree : le mouvement freine en
* arrivant au lieu de s'arreter net, et deux changements de categorie
* coup sur coup s'enchainent sans a-coup -- la camera repart d'ou elle est.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Preview|Framing", meta = (ClampMin = "0.5"))
float FramingInterpSpeed = 6.f;
/** Degres de rotation par pixel de deplacement horizontal de la souris. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Preview|Turntable")
float YawPerPixel = 0.35f;
private:
/** Le repere vise par la camera, selon le cadrage courant. */
USceneComponent* GetSpotForFraming(ECharacterPreviewFraming InFraming) const;
/**
* Coupe le Tick quand la camera est arrivee.
*
* Meme principe que le couvercle d'AStorageContainer : cet acteur ne tick
* que pendant qu'il bouge. Un mannequin immobile dans un menu n'a aucune
* raison de couter une frame.
*/
void UpdateFramingInterpolation(float DeltaSeconds);
ECharacterPreviewFraming CurrentFraming = ECharacterPreviewFraming::FullBody;
/** Rotation accumulee par le clic-glisser, en degres. */
float TurntableYaw = 0.f;
};