// 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(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(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); }