86 lines
3.2 KiB
C++
86 lines
3.2 KiB
C++
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
|
|
#include "FpsArmsAnimInstance.h"
|
|
|
|
#include "FpsPlayer.h"
|
|
#include "GameFramework/CharacterMovementComponent.h"
|
|
#include "HeldItemComponent.h"
|
|
|
|
void UFpsArmsAnimInstance::NativeInitializeAnimation()
|
|
{
|
|
Super::NativeInitializeAnimation();
|
|
|
|
OwningPlayer = Cast<AFpsPlayer>(TryGetPawnOwner());
|
|
}
|
|
|
|
void UFpsArmsAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
|
|
{
|
|
Super::NativeUpdateAnimation(DeltaSeconds);
|
|
|
|
// L'AnimInstance est initialisee avec le composant, c'est-a-dire potentiellement
|
|
// avant que le pawn soit completement en place. On retente donc tant qu'on n'a
|
|
// personne, plutot que d'abandonner definitivement sur un echec au demarrage.
|
|
if (!OwningPlayer.IsValid())
|
|
{
|
|
OwningPlayer = Cast<AFpsPlayer>(TryGetPawnOwner());
|
|
if (!OwningPlayer.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
const AFpsPlayer* Player = OwningPlayer.Get();
|
|
const UCharacterMovementComponent* Movement = Player->GetCharacterMovement();
|
|
if (!Movement)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Size2D et pas Size : en pleine chute la composante verticale ferait courir
|
|
// les bras alors que le joueur ne pose pas un pied.
|
|
GroundSpeed = Movement->Velocity.Size2D();
|
|
|
|
// Le test d'acceleration est ce qui distingue « le joueur avance » de « le
|
|
// joueur a lache la touche et glisse encore ». Sans lui, l'animation de course
|
|
// continue pendant toute la decceleration, les pieds patinant dans le vide --
|
|
// invisible sur des bras, mais le meme AnimInstance servira au corps un jour.
|
|
bIsMoving = GroundSpeed > MovingSpeedThreshold
|
|
&& !Movement->GetCurrentAcceleration().IsNearlyZero();
|
|
|
|
// Lu depuis le composant plutot que mis en cache dans un membre : apres un
|
|
// respawn le pawn est un NOUVEL acteur, avec un nouveau composant, et un
|
|
// pointeur garde ici pointerait sur celui du cadavre.
|
|
if (const UHeldItemComponent* HeldItems = Player->GetHeldItemComponent())
|
|
{
|
|
bHasItemInHand = HeldItems->HasItemInHand();
|
|
}
|
|
|
|
bIsSprinting = Player->IsSprinting();
|
|
bIsFalling = Movement->IsFalling();
|
|
LandingImpact = Player->GetLandingImpact();
|
|
bIsCrouching = Movement->IsCrouching();
|
|
VerticalSpeed = Movement->Velocity.Z;
|
|
|
|
// Les deux etats de deplacement au sol sont composes ICI et nulle part
|
|
// ailleurs. bIsSprinting ne dit que « la touche est enfoncee » : sans le ET
|
|
// avec bIsMoving, appuyer sur Maj a l'arret suffit a lancer l'animation de
|
|
// course, bras qui pompent devant un personnage qui ne bouge pas.
|
|
//
|
|
// Le sol et l'accroupi sont exclus des deux pour que ces booleens restent
|
|
// mutuellement exclusifs avec les etats Air et Crouch de la machine : deux
|
|
// conditions vraies en meme temps, c'est une transition prise au hasard.
|
|
const bool bGrounded = !bIsFalling && !bIsCrouching;
|
|
bIsRunning = bGrounded && bIsMoving && bIsSprinting;
|
|
bIsWalking = bGrounded && bIsMoving && !bIsSprinting;
|
|
|
|
// La cadence suit la vitesse REELLE et pas l'etat de sprint : c'est ce qui
|
|
// fait que les bras accelerent pendant la montee en vitesse, au lieu de
|
|
// sauter d'une cadence a l'autre a l'instant ou la touche est pressee.
|
|
// Elle couvre donc aussi l'accroupi, gratuitement.
|
|
LocomotionPlayRate = FMath::Clamp(
|
|
GroundSpeed / ReferenceLocomotionSpeed,
|
|
MinLocomotionPlayRate,
|
|
MaxLocomotionPlayRate);
|
|
}
|