Files

151 lines
6.0 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Animation/AnimInstance.h"
#include "PlayerBodyAnimInstance.generated.h"
class AFpsPlayer;
/**
* AnimInstance du corps vu a la TROISIEME personne -- celui que les autres
* joueurs voient, et dont on ne percoit soi-meme que l'ombre.
*
* Meme partage des roles que UFpsArmsAnimInstance : elle ne DECIDE de rien, elle
* lit l'etat du pawn une fois par frame et le republie en variables. C'est la
* machine a etats du Blueprint enfant qui choisit l'animation, parce qu'une
* transition se regle a l'oeil avec des durees de fondu et n'a rien a faire dans
* du C++ qu'il faut recompiler.
*
* La difference avec les bras est reseau, et elle est essentielle : les bras ne
* sont vus que par leur proprietaire, ce corps-ci est vu par TOUT LE MONDE.
* Chaque machine evalue donc les quatre corps de la partie. Et pourtant rien
* n'est replique ici -- tout est DERIVE d'un etat que le moteur ou le projet
* synchronisent deja :
*
* Velocity -> replique par le mouvement du Character
* bIsCrouched -> UPROPERTY repliquee d'ACharacter
* bIsSprinting -> repliquee par AFpsPlayer (c'est a ca qu'elle sert)
* AimPitch -> RemoteViewPitch, replique par APawn sans rien demander
*
* Repliquer une seule de ces variables serait envoyer deux fois la meme
* information -- exactement le reproche fait a UPlayerNameplateComponent.
*/
UCLASS()
class EMBERWILD_API UPlayerBodyAnimInstance : public UAnimInstance
{
GENERATED_BODY()
public:
virtual void NativeInitializeAnimation() override;
virtual void NativeUpdateAnimation(float DeltaSeconds) override;
protected:
// ------------------------------------------------------------------
// Etat publie vers le Blueprint d'animation
// ------------------------------------------------------------------
/** Vitesse horizontale en cm/s : l'axe du BlendSpace de deplacement. */
UPROPERTY(BlueprintReadOnly, Category = "Movement")
float GroundSpeed = 0.f;
/**
* Direction du deplacement par rapport a l'orientation du corps, en degres :
* 0 = on avance, 90 = on va vers la droite, 180 = on recule.
*
* Elle est non nulle en permanence dans ce jeu et ce n'est pas un detail :
* bUseControllerRotationYaw garde le corps aligne sur la camera, donc un pas
* de cote est un VRAI pas de cote, jamais un demi-tour. Le pack ne livre que
* des cycles vers l'avant, donc personne ne la lit encore ; elle est publiee
* parce que le jour ou les cycles lateraux arriveront, il n'y aura qu'un
* BlendSpace a brancher et pas une classe a rouvrir.
*/
UPROPERTY(BlueprintReadOnly, Category = "Movement")
float LocomotionDirection = 0.f;
/** Vrai quand le joueur se deplace REELLEMENT, freinage exclu. */
UPROPERTY(BlueprintReadOnly, Category = "Movement")
bool bIsMoving = false;
UPROPERTY(BlueprintReadOnly, Category = "Movement")
bool bIsSprinting = false;
UPROPERTY(BlueprintReadOnly, Category = "Movement")
bool bIsFalling = false;
/**
* Vitesse verticale en cm/s : positif = on monte, negatif = on tombe.
*
* C'est elle, et elle seule, qui distingue un SAUT d'une CHUTE. bIsFalling
* vaut vrai dans les deux cas : le moteur appelle "falling" tout ce qui n'est
* pas au sol, detente comprise. Sans ce signe, sortir d'une falaise jouerait
* l'animation de detente -- un personnage qui prend son elan pour tomber.
*
* Gratuite sur le reseau comme le reste : le CharacterMovement replique deja
* la velocite des pawns distants, on ne fait que lire sa composante Z.
*/
UPROPERTY(BlueprintReadOnly, Category = "Movement")
float VerticalSpeed = 0.f;
UPROPERTY(BlueprintReadOnly, Category = "Movement")
bool bIsCrouching = false;
/**
* Tangage du regard, en degres, borne a -90..90. Positif = le joueur regarde
* vers le haut.
*
* Gratuit sur le reseau : APawn compresse et replique deja RemoteViewPitch
* pour ses pawns distants, et GetBaseAimRotation() rend la bonne valeur des
* deux cotes sans qu'on ait une seule propriete a declarer. Personne ne la
* lit tant qu'il n'y a pas d'AimOffset -- mais le jour ou un ami doit voir
* qu'on regarde le ciel, c'est cette variable qu'on branchera.
*/
UPROPERTY(BlueprintReadOnly, Category = "Aim")
float AimPitch = 0.f;
/**
* Vitesse de lecture du cycle de deplacement.
*
* A NE BRANCHER QUE si l'on joue une animation unique. Avec le BlendSpace du
* pack, qui interpole deja marche et course sur l'axe de la vitesse, la
* brancher etirerait une seconde fois un cycle deja etire et donnerait une
* cadence qui accelere deux fois trop vite. Elle reste ici parce que le
* BlendSpace est calibre sur les vitesses du pack et pas sur les notres
* (200 / 400 / 650) : si la foulee patine, c'est le reglage a sortir.
*/
UPROPERTY(BlueprintReadOnly, Category = "Movement")
float LocomotionPlayRate = 1.f;
/**
* En dessous de cette vitesse (cm/s) on considere le joueur immobile.
*
* Un seuil strictement a zero ferait clignoter la transition course/repos
* pendant le freinage, ou la vitesse decroit en passant par des valeurs
* minuscules mais non nulles.
*/
UPROPERTY(EditDefaultsOnly, Category = "Movement", meta = (ClampMin = "0"))
float MovingSpeedThreshold = 10.f;
/** Vitesse (cm/s) a laquelle le cycle tourne a sa cadence d'origine. */
UPROPERTY(EditDefaultsOnly, Category = "Movement", meta = (ClampMin = "1"))
float ReferenceLocomotionSpeed = 400.f;
/** Bornes du Play Rate, memes garde-fous que sur les bras. */
UPROPERTY(EditDefaultsOnly, Category = "Movement", meta = (ClampMin = "0.1"))
float MinLocomotionPlayRate = 0.6f;
UPROPERTY(EditDefaultsOnly, Category = "Movement", meta = (ClampMin = "0.1"))
float MaxLocomotionPlayRate = 1.8f;
private:
/**
* Cache du pawn. TryGetPawnOwner() fait un Cast a chaque appel, et cette
* fonction tourne a chaque frame sur QUATRE corps en partie a quatre.
*
* TWeakObjectPtr et pas un pointeur nu : apres un respawn le pawn est
* detruit, et cet objet peut lui survivre d'une frame.
*/
TWeakObjectPtr<AFpsPlayer> OwningPlayer;
};