// 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 SURVIVAL_PROJET_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 OwningPlayer; };