Files

94 lines
3.7 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#include "PlayerBodyAnimInstance.h"
#include "FpsPlayer.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "KismetAnimationLibrary.h"
void UPlayerBodyAnimInstance::NativeInitializeAnimation()
{
Super::NativeInitializeAnimation();
OwningPlayer = Cast<AFpsPlayer>(TryGetPawnOwner());
}
void UPlayerBodyAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
{
Super::NativeUpdateAnimation(DeltaSeconds);
// Chez un CLIENT, le mesh arrive par replication et peut commencer a
// s'animer avant que le pawn soit completement initialise : le Cast du
// NativeInitialize rend alors nullptr, une fois pour toutes, et le corps de
// l'ami reste fige en pose de reference pour le reste de la partie. On
// reessaie donc tant qu'on n'a rien -- le cout est un Cast par frame
// uniquement pendant les quelques frames ou le pawn manque encore.
if (!OwningPlayer.IsValid())
{
OwningPlayer = Cast<AFpsPlayer>(TryGetPawnOwner());
if (!OwningPlayer.IsValid())
{
return;
}
}
const AFpsPlayer* BodyOwner = OwningPlayer.Get();
const UCharacterMovementComponent* Movement = BodyOwner->GetCharacterMovement();
if (!Movement)
{
return;
}
// Composante horizontale seule : en pleine chute la vitesse verticale
// depasse largement la vitesse de course, et un BlendSpace indexe dessus
// jouerait un sprint en l'air.
const FVector Velocity = BodyOwner->GetVelocity();
const FVector HorizontalVelocity(Velocity.X, Velocity.Y, 0.f);
GroundSpeed = HorizontalVelocity.Size();
// L'acceleration, et pas seulement la vitesse : elle tombe a zero des que la
// touche est relachee, alors que la vitesse decroit encore pendant tout le
// freinage. Sans elle le cycle de marche continuerait de tourner sur un
// personnage qui glisse jusqu'a l'arret.
bIsMoving = GroundSpeed > MovingSpeedThreshold
&& !Movement->GetCurrentAcceleration().IsNearlyZero();
bIsFalling = Movement->IsFalling();
// Prise telle quelle, sans seuil : c'est le Blueprint qui decide ou placer la
// bascule saut / chute. Une valeur brute reste une valeur brute -- lui donner
// un seuil ici, ce serait decider a la place de la machine a etats, et il
// faudrait recompiler pour le regler.
VerticalSpeed = Velocity.Z;
// Les deux etats du pawn, repliques chacun de leur cote : bIsCrouched par le
// moteur, bIsSprinting par AFpsPlayer. On les lit ici plutot que de deviner
// l'accroupissement a la hauteur de capsule, qui est en pleine interpolation
// pendant toute la transition.
bIsCrouching = BodyOwner->bIsCrouched;
bIsSprinting = BodyOwner->IsSprinting();
// Direction relative au CORPS et non a la vitesse du monde : c'est ce que
// demande un BlendSpace directionnel. GetActorRotation() suffit comme
// reference parce que bUseControllerRotationYaw garde le corps aligne sur le
// regard -- sur un jeu a la 3e personne libre, il faudrait la rotation de
// controle a la place.
//
// UKismetAnimationLibrary et pas UAnimInstance::CalculateDirection, depreciee
// en 5.8 : le calcul est le meme, mais l'ancienne cassera la compilation a la
// prochaine version du moteur.
LocomotionDirection = UKismetAnimationLibrary::CalculateDirection(HorizontalVelocity, BodyOwner->GetActorRotation());
// GetBaseAimRotation et pas GetControlRotation : le second n'existe que sur
// la machine qui possede le pawn, le premier retombe sur RemoteViewPitch
// pour les pawns des autres joueurs. NormalizeAxis ramene les 350 degres
// d'un regard vers le bas a -10, seule forme exploitable par un AimOffset.
AimPitch = FRotator::NormalizeAxis(BodyOwner->GetBaseAimRotation().Pitch);
LocomotionPlayRate = FMath::Clamp(
GroundSpeed / ReferenceLocomotionSpeed,
MinLocomotionPlayRate,
MaxLocomotionPlayRate);
}