Unreal 入门-Montage Root Motion 功能代码说明。
来源:互联网 发布:天猫魔盒如何下载软件 编辑:程序博客网 时间:2024/05/22 03:20
Root Motion 移动功能。
void UCharacterMovementComponent::SimulatedTick(float DeltaSeconds){ SCOPE_CYCLE_COUNTER(STAT_CharacterMovementSimulated); checkSlow(CharacterOwner != nullptr); if (NetworkSmoothingMode == ENetworkSmoothingMode::Replay) { const FVector OldLocation = UpdatedComponent ? UpdatedComponent->GetComponentLocation() : FVector::ZeroVector; const FVector OldVelocity = Velocity; // Interpolate between appropriate samples { SCOPE_CYCLE_COUNTER( STAT_CharacterMovementSmoothClientPosition ); SmoothClientPosition( DeltaSeconds ); } // Update replicated movement mode ApplyNetworkMovementMode( GetCharacterOwner()->GetReplicatedMovementMode() ); UpdateComponentVelocity(); bJustTeleported = false; CharacterOwner->RootMotionRepMoves.Empty(); CurrentRootMotion.Clear(); CharacterOwner->SavedRootMotion.Clear(); // Note: we do not call the Super implementation, that runs prediction. // We do still need to call these though OnMovementUpdated(DeltaSeconds, OldLocation, OldVelocity); CallMovementUpdateDelegate(DeltaSeconds, OldLocation, OldVelocity); LastUpdateLocation = UpdatedComponent ? UpdatedComponent->GetComponentLocation() : FVector::ZeroVector; LastUpdateRotation = UpdatedComponent ? UpdatedComponent->GetComponentQuat() : FQuat::Identity; LastUpdateVelocity = Velocity; //TickCharacterPose( DeltaSeconds ); return; } // If we are playing a RootMotion AnimMontage. if (CharacterOwner->IsPlayingNetworkedRootMotionMontage()) { bWasSimulatingRootMotion = true; UE_LOG(LogRootMotion, Verbose, TEXT("UCharacterMovementComponent::SimulatedTick")); // Tick animations before physics. if( CharacterOwner->GetMesh() ) { TickCharacterPose(DeltaSeconds); // Make sure animation didn't trigger an event that destroyed us if (!HasValidData()) { return; } } if( RootMotionParams.bHasRootMotion ) { const FQuat OldRotationQuat = UpdatedComponent->GetComponentQuat(); const FVector OldLocation = UpdatedComponent->GetComponentLocation(); SimulateRootMotion(DeltaSeconds, RootMotionParams.GetRootMotionTransform()); #if !(UE_BUILD_SHIPPING) // debug if (false) { const FRotator OldRotation = OldRotationQuat.Rotator(); const FRotator NewRotation = UpdatedComponent->GetComponentRotation(); const FVector NewLocation = UpdatedComponent->GetComponentLocation(); DrawDebugCoordinateSystem(GetWorld(), CharacterOwner->GetMesh()->GetComponentLocation() + FVector(0,0,1), NewRotation, 50.f, false); DrawDebugLine(GetWorld(), OldLocation, NewLocation, FColor::Red, true, 10.f); UE_LOG(LogRootMotion, Log, TEXT("UCharacterMovementComponent::SimulatedTick DeltaMovement Translation: %s, Rotation: %s, MovementBase: %s"), *(NewLocation - OldLocation).ToCompactString(), *(NewRotation - OldRotation).GetNormalized().ToCompactString(), *GetNameSafe(CharacterOwner->GetMovementBase()) ); } #endif // !(UE_BUILD_SHIPPING) } // then, once our position is up to date with our animation, // handle position correction if we have any pending updates received from the server. if( CharacterOwner && (CharacterOwner->RootMotionRepMoves.Num() > 0) ) { CharacterOwner->SimulatedRootMotionPositionFixup(DeltaSeconds);//这里调整位置跟随动作运动 } } //...}
这里做了移动:
void ACharacter::SimulatedRootMotionPositionFixup(float DeltaSeconds){ const FAnimMontageInstance* ClientMontageInstance = GetRootMotionAnimMontageInstance();//这里获取了自带Mesh if( ClientMontageInstance && CharacterMovement && Mesh ) { // Find most recent buffered move that we can use. const int32 MoveIndex = FindRootMotionRepMove(*ClientMontageInstance); if( MoveIndex != INDEX_NONE ) { const FVector OldLocation = GetActorLocation(); const FQuat OldRotation = GetActorQuat(); // Move Actor back to position of that buffered move. (server replicated position). const FSimulatedRootMotionReplicatedMove& RootMotionRepMove = RootMotionRepMoves[MoveIndex]; if( RestoreReplicatedMove(RootMotionRepMove) ) { const float ServerPosition = RootMotionRepMove.RootMotion.Position; const float ClientPosition = ClientMontageInstance->GetPosition(); const float DeltaPosition = (ClientPosition - ServerPosition); if( FMath::Abs(DeltaPosition) > KINDA_SMALL_NUMBER ) { // Find Root Motion delta move to get back to where we were on the client. const FTransform LocalRootMotionTransform = ClientMontageInstance->Montage->ExtractRootMotionFromTrackRange(ServerPosition, ClientPosition); // Simulate Root Motion for delta move. if( CharacterMovement ) { const float MontagePlayRate = ClientMontageInstance->GetPlayRate(); // Guess time it takes for this delta track position, so we can get falling physics accurate. if (!FMath::IsNearlyZero(MontagePlayRate)) { const float DeltaTime = DeltaPosition / MontagePlayRate; // Even with negative playrate deltatime should be positive. check(DeltaTime > 0.f); CharacterMovement->SimulateRootMotion(DeltaTime, LocalRootMotionTransform); // After movement correction, smooth out error in position if any. CharacterMovement->bNetworkSmoothingComplete = false; CharacterMovement->SmoothCorrection(OldLocation, OldRotation, GetActorLocation(), GetActorQuat()); } } } } // Delete this move and any prior one, we don't need them anymore. UE_LOG(LogRootMotion, Log, TEXT("\tClearing old moves (%d)"), MoveIndex+1); RootMotionRepMoves.RemoveAt(0, MoveIndex+1); } }}
这里获取了Character自带的Mesh,限制的Root Motion只能用在Character 自带的Mesh。
/** Get FAnimMontageInstance playing RootMotion */FAnimMontageInstance * ACharacter::GetRootMotionAnimMontageInstance() const{ return (Mesh && Mesh->GetAnimInstance()) ? Mesh->GetAnimInstance()->GetRootMotionMontageInstance() : NULL;}
0 0
- Unreal 入门-Montage Root Motion 功能代码说明。
- Unreal 入门-Unreal 基础知识。
- Unreal 入门-
- Unreal 入门-
- Unreal 入门-Unreal问题库
- 关于 root motion
- Unreal 入门-性能分析
- Unreal 入门-AO贴图
- Unreal 入门-顶点变形
- Unreal 入门-EQS
- Unreal 代码流程分析
- Root Motion深度解析[Unity]
- Root Motion的脚本处理
- Root Motion深度解析[Unity]
- Root Motion深度解析[Unity]
- Leap Motion 入门简介
- Unreal 入门-UE4 Console Command
- Happiness montage
- C语言中联合的使用基础
- Mac中MySQL忘记密码怎么办
- ios之Xcode工程中添加文件常用快捷键
- ubuntu Unable to locate package libXp
- Unreal 入门-顶点变形
- Unreal 入门-Montage Root Motion 功能代码说明。
- 杭电2004成绩转换
- linux中ls源码简单分析
- Win64 驱动内核编程-20.UnHook SSDT
- Unreal 入门-EQS
- Spring之IoC
- 数据平台
- 在CakePHP项目中集成EasyWeChat
- python 网络爬虫入门(四)— 破解pexels高清原图