当前位置:网站首页>UE source code analysis: uccharactermovementcomponent - rootmotion
UE source code analysis: uccharactermovementcomponent - rootmotion
2022-07-03 19:15:00 【JK Chen】
brief introduction
RootMotion In two parts : From animation RootMotion And customization RootMotionSource
UCharacterMovementComponent::ApplyRootMotionSource
original edition CMC Mutually exclusive use both
RootMotion By changing Velocity Act on CMC, The main code is UCharacterMovementComponent::PerformMovement Inside
Data flow
Data on ,AnimInstance Inside FAnimMontageInstance Relevant data are :
/** AnimMontage instances that are running currently * - only one is primarily active per group, and the other ones are blending out */
TArray<struct FAnimMontageInstance*> MontageInstances;
/** Map between Active Montages and their FAnimMontageInstance */
TMap<class UAnimMontage*, struct FAnimMontageInstance*> ActiveMontagesMap;
/** Active Root Motion Montage Instance, if any. */
struct FAnimMontageInstance* RootMotionMontageInstance;
adopt RootMotionMontageInstance Get current RootMotion Corresponding Montage
float UAnimInstance::Montage_Play(UAnimMontage* MontageToPlay, float InPlayRate/*= 1.f*/, EMontagePlayReturnType ReturnValueType, float InTimeToStartMontageAt, bool bStopAllMontages /*= true*/)
if (MontageToPlay->HasRootMotion())
RootMotionMontageInstance = NewInstance;
FAnimMontageInstance * ACharacter::GetRootMotionAnimMontageInstance() const
return (Mesh && Mesh->GetAnimInstance()) ? Mesh->GetAnimInstance()->GetRootMotionMontageInstance() : nullptr;
AnimInstance Deal with FRootMotionMovementParams
Update process : bones - Animation blueprint - Montage - RootMotion
void USkeletalMeshComponent::TickAnimation(float DeltaTime, bool bNeedsValidRootMotion)
void UAnimInstance::UpdateAnimation(float DeltaSeconds, bool bNeedsValidRootMotion, EUpdateAnimationFlag UpdateFlag)
void UAnimInstance::UpdateMontage(float DeltaSeconds)
void UAnimInstance::Montage_Advance(float DeltaSeconds)
void FAnimMontageInstance::Advance(float DeltaTime, struct FRootMotionMovementParams* OutRootMotionParams, bool bBlendRootMotion)
// take Mesh Of RootMotion The accumulation of (FTransform Multiply) To RootMotionParams
OutRootMotionParams->Accumulate(RootMotion);
Save to :
// Root motion read from proxy (where it is calculated) and stored here to avoid potential stalls by calling GetProxyOnGameThread
FRootMotionMovementParams UAnimInstance::ExtractedRootMotion;
CMC Use FRootMotionMovementParams
FRootMotionMovementParams USkeletalMeshComponent::ConsumeRootMotion()
FRootMotionMovementParams USkeletalMeshComponent::ConsumeRootMotion_Internal(float InAlpha)
FRootMotionMovementParams UAnimInstance::ConsumeExtractedRootMotion(float Alpha)
ExtractedRootMotion
Move inside the component FRootMotionMovementParams
/** Root Motion movement params. Holds result of anim montage root motion during PerformMovement(), and is overridden * during autonomous move playback to force historical root motion for MoveAutonomous() calls */
UPROPERTY(Transient)
FRootMotionMovementParams RootMotionParams;
This deposit is procedural AnimRootMotion, Whether there is AnimRootMotion Also use this to judge , from ExtractedRootMotion Cumulative
bool UCharacterMovementComponent::HasAnimRootMotion() const
return RootMotionParams.bHasRootMotion;
Applied to the CMC The process of
void UCharacterMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction)
void UCharacterMovementComponent::PerformMovement(float DeltaSeconds)
void UCharacterMovementComponent::TickCharacterPose(float DeltaTime)
// to update ExtractedRootMotion
void USkeletalMeshComponent::TickPose(float DeltaTime, bool bNeedsValidRootMotion)
void USkeletalMeshComponent::TickAnimation(float DeltaTime, bool bNeedsValidRootMotion)
// obtain ExtractedRootMotion
FRootMotionMovementParams RootMotion = CharacterMesh->ConsumeRootMotion();
if (RootMotion.bHasRootMotion)
{
RootMotion.ScaleRootMotionTranslation(CharacterOwner->GetAnimRootMotionTranslationScale());
// Accumulate inside the mobile component
RootMotionParams.Accumulate(RootMotion);
}
// Handle RootMotionSource
CurrentRootMotion.PrepareRootMotion(DeltaSeconds, *CharacterOwner, *this, true);
// Use Override RootMotionSource perhaps RootMotionParams Update speed
if( CurrentRootMotion.HasOverrideVelocity() || HasAnimRootMotion() )
// Use RootMotionParams
if( HasAnimRootMotion() )
// direct override by AnimRootMotion Of Velocity
AnimRootMotionVelocity = CalcAnimRootMotionVelocity(RootMotionParams.GetRootMotionTransform().GetTranslation(), DeltaSeconds, Velocity);
Velocity = ConstrainAnimRootMotionVelocity(AnimRootMotionVelocity, Velocity);
// Use Override RootMotionSource
else
CurrentRootMotion.AccumulateOverrideRootMotionVelocity(DeltaSeconds, *CharacterOwner, *this, NewVelocity);
Velocity = NewVelocity;
// Update location ( See the analysis below )
void UCharacterMovementComponent::StartNewPhysics(float deltaTime, int32 Iterations)
void UCharacterMovementComponent::PhysWalking(float deltaTime, int32 Iterations)
// Update rotation
if( HasAnimRootMotion() )
MoveUpdatedComponent(FVector::ZeroVector, NewActorRotationQuat, true);
else if (CurrentRootMotion.HasActiveRootMotionSources())
MoveUpdatedComponent(FVector::ZeroVector, NewActorRotationQuat, true);
If you go RootMotionSource Words , stay PerformMovement It did Override,PhysWalking Do inside Override and Additive, The one outside here is redundant
void UCharacterMovementComponent::PhysWalking(float deltaTime, int32 Iterations)
while ( (remainingTime >= MIN_TICK_TIME) && (Iterations < MaxSimulationIterations) && CharacterOwner && (CharacterOwner->Controller || bRunPhysicsWithNoController || HasAnimRootMotion() || CurrentRootMotion.HasOverrideVelocity() || (CharacterOwner->GetLocalRole() == ROLE_SimulatedProxy)) )
RestorePreAdditiveRootMotionVelocity();
void UCharacterMovementComponent::ApplyRootMotionToVelocity(float deltaTime)
// application AnimRootMotion
if( HasAnimRootMotion() && deltaTime > 0.f )
Velocity = ConstrainAnimRootMotionVelocity(AnimRootMotionVelocity, Velocity);
return;
// application Override RootMotionSource
if( CurrentRootMotion.HasOverrideVelocity() )
CurrentRootMotion.AccumulateOverrideRootMotionVelocity(deltaTime, *CharacterOwner, *this, Velocity);
// application Additive RootMotionSource
if( CurrentRootMotion.HasAdditiveVelocity() )
CurrentRootMotion.AccumulateAdditiveRootMotionVelocity(deltaTime, *CharacterOwner, *this, Velocity);
// Movement and other subsequent processing
MoveAlongFloor(MoveVelocity, timeTick, &StepDownResult);
Network synchronization
From Montage and RootMotionSource Two parts
The first part is due to AnimInstance On the client side , So naturally, it is synchronous
The second part ,ApplyRootMotionSource Will be added to CurrentRootMotion(FRootMotionSourceGroup) Of PendingAddRootMotionSources Inside
CMC Of PerformMovement In the use of RootMotion We'll call FRootMotionSourceGroup::PrepareRootMotion,RootMotionSources.Append(PendingAddRootMotionSources);
// Sync CurrentRootMotion
void ACharacter::PreReplication( IRepChangedPropertyTracker & ChangedPropertyTracker )
RepRootMotion.AuthoritativeRootMotion = CharacterMovement->CurrentRootMotion;
UPROPERTY(ReplicatedUsing=OnRep_RootMotion)
struct FRepRootMotionMontage ACharacter::RepRootMotion;
// The analog end uses the synchronized RepRootMotion
void ACharacter::OnRep_RootMotion()
if (GetLocalRole() == ROLE_SimulatedProxy)
RootMotionRepMoves.AddZeroed(1);
// Analog end at SimulatedTick Will use RootMotionRepMoves Realization RootMotion
FSimulatedRootMotionReplicatedMove& NewMove = RootMotionRepMoves.Last();
NewMove.RootMotion = RepRootMotion;
correct
int32 UNetDriver::ServerReplicateActors(float DeltaSeconds)
PlayerController->SendClientAdjustment()
if (RemotePawn && (RemotePawn->GetRemoteRole() == ROLE_AutonomousProxy) && !IsNetMode(NM_Client))
{
INetworkPredictionInterface* NetworkPredictionInterface = Cast<INetworkPredictionInterface>(RemotePawn->GetMovementComponent());
if (NetworkPredictionInterface)
{
// Main control end
NetworkPredictionInterface->SendClientAdjustment();
}
}
void UCharacterMovementComponent::SendClientAdjustment()
if (CurrentRootMotion.HasActiveRootMotionSources())
ClientAdjustRootMotionSourcePosition(...)
else if (bIsPlayingNetworkedRootMotionMontage)
ClientAdjustRootMotionPosition(...)
边栏推荐
- Basic principle of LSM tree
- flask 生成swagger文档
- How does if ($variable) work? [repeat] - how exactly does if ($variable) work? [duplicate]
- The necessity of lean production and management in sheet metal industry
- Common PostgreSQL commands
- The earliest record
- Web Security (VIII) what is CSRF attack? Why can token prevent csdf attacks?
- High concurrency Architecture - distributed search engine (ES)
- Using the visualization results, click to appear the corresponding sentence
- 为什么要做特征的归一化/标准化?
猜你喜欢

【学术相关】顶级论文创新点怎么找?中国高校首次获CVPR最佳学生论文奖有感...

Merge K ascending linked lists
![[new year job hopping season] test the technical summary of interviewers' favorite questions (with video tutorials and interview questions)](/img/4e/a51365bb88b1fc29d1c77fcdde5350.jpg)
[new year job hopping season] test the technical summary of interviewers' favorite questions (with video tutorials and interview questions)

Compose LazyColumn 顶部添加控件

Record: pymysql is used in pycharm to connect to the database

Php based campus lost and found platform (automatic matching push)
![[disease identification] machine vision lung cancer detection system based on Matlab GUI [including Matlab source code 1922]](/img/fc/00835b95537cf889588502a3d13bc9.png)
[disease identification] machine vision lung cancer detection system based on Matlab GUI [including Matlab source code 1922]

Ego planner code parsing Bspline_ Optimizer section (3)

Analysis of dart JSON encoder and decoder

我們做了一個智能零售結算平臺
随机推荐
“google is not defined” when using Google Maps V3 in Firefox remotely
application
Smart wax therapy machine based on STM32 and smart cloud
Record the errors reported when running fluent in the simulator
Yolov3 network model building
【Proteus仿真】用24C04与1602LCD设计的简易加密电子密码锁
Next spread
Record: install MySQL on ubuntu18.04
leetcode:556. Next larger element III [simulation + change as little as possible]
利用可视化结果,点击出现对应的句子
达梦数据库的物理备份和还原简解
Simple solution of physical backup and restore of Damon database
Briefly describe the quantitative analysis system of services
What is the content of game modeling
Add control at the top of compose lazycolumn
Record: pymysql is used in pycharm to connect to the database
SQL custom collation
Max of PHP FPM_ Some misunderstandings of children
Which do MySQL and Oracle learn?
Introduction to SSH Remote execution command