CARLA
 
载入中...
搜索中...
未找到
WalkerController.cpp
浏览该文件的文档.
1// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
7#include "Carla.h"
8// 包含CARLA模拟框架中Walker控制器的头文件
9// Walker控制器负责控制行人的移动和动画
11// 包含CARLA模拟框架中Walker动画的头文件
12// Walker动画涉及到行人的行走、跑步、跳跃等动作的动画处理
14// 包含Unreal Engine中用于可摆放网格组件的头文件
15// PoseableMeshComponent允许开发者在运行时动态地调整网格(3D模型)的位置、旋转和缩放
16#include "Components/PoseableMeshComponent.h"
17// 包含Unreal Engine中用于基本几何体组件的头文件
18// PrimitiveComponent是许多基本形状(如立方体、球体、平面等)的基类
19#include "Components/PrimitiveComponent.h"
20// 包含Unreal Engine中用于映射(键值对)的头文件
21// Map是一个模板类,用于存储键值对,类似于标准C++中的std::map
22#include "Containers/Map.h"
23#include "GameFramework/Character.h"
24#include "GameFramework/CharacterMovementComponent.h"
25// 包含Unreal Engine中用于Pawn的头文件
26// Pawn是一个更通用的基类,用于表示游戏世界中的可控制实体
27// Character是Pawn的一个子类,专门用于表示具有移动能力的角色
28#include "GameFramework/Pawn.h"
29// AWalkerController类的构造函数
30// FObjectInitializer参数用于初始化对象属性
31AWalkerController::AWalkerController(const FObjectInitializer &ObjectInitializer)
32 : Super(ObjectInitializer)
33{ // 设置PrimaryActorTick.bCanEverTick为true,表示这个Actor(行人控制器)可以在每一帧都被更新
34 PrimaryActorTick.bCanEverTick = true;
35}
36// 当AWalkerController“占有”一个APawn时,会调用此函数
37// InPawn参数指向被占有的Pawn
39{// 调用父类的OnPossess函数
40 Super::OnPossess(InPawn);
41
42 auto *Character = Cast<ACharacter>(InPawn);
43 if (Character == nullptr)
44 {
45 UE_LOG(LogCarla, Error, TEXT("Walker is not a character!"));
46 return;
47 }
48
49 auto *MovementComponent = Character->GetCharacterMovement();
50 if (MovementComponent == nullptr)
51 {
52 UE_LOG(LogCarla, Error, TEXT("Walker missing character movement component!"));
53 return;
54 }
55// 设置角色的最大行走速度
56 MovementComponent->MaxWalkSpeed = GetMaximumWalkSpeed();
57 // 设置角色的跳跃垂直速度
58 MovementComponent->JumpZVelocity = 500.0f;// 一个硬编码的跳跃速度值
59 Character->JumpMaxCount = 2;
60}
61
63{
64 Control = InControl;
65}
66
68{
69 auto *Character = GetCharacter();
70 if (!Character) return;
71
72 TArray<USkeletalMeshComponent *> SkeletalMeshes;
73 Character->GetComponents<USkeletalMeshComponent>(SkeletalMeshes, false);
74 USkeletalMeshComponent *SkeletalMesh = SkeletalMeshes.IsValidIndex(0) ? SkeletalMeshes[0] : nullptr;
75 if (!SkeletalMesh) return;
76
77 // 获取行人的动画类
78 auto *AnimInst = SkeletalMesh->GetAnimInstance();
79 if (!AnimInst) return;
80 UWalkerAnim *WalkerAnim = Cast<UWalkerAnim>(AnimInst);
81 if (!WalkerAnim) return;
82
83 // 获取当前的姿态
84 FPoseSnapshot TempSnapshot;
85 SkeletalMesh->SnapshotPose(TempSnapshot);
86
87 // 拷贝姿态
88 // WalkerAnim->Snap = TempSnapshot;
89
90 for (int i=0; i<TempSnapshot.BoneNames.Num(); ++i)
91 {
93 Transforms.World = SkeletalMesh->GetSocketTransform(TempSnapshot.BoneNames[i], ERelativeTransformSpace::RTS_World);
94 Transforms.Component = SkeletalMesh->GetSocketTransform(TempSnapshot.BoneNames[i], ERelativeTransformSpace::RTS_Actor);
95 Transforms.Relative = SkeletalMesh->GetSocketTransform(TempSnapshot.BoneNames[i], ERelativeTransformSpace::RTS_ParentBoneSpace);
96 // Transforms.Relative = TempSnapshot.LocalTransforms[i];
97
98 WalkerBones.BoneTransforms.Add(TempSnapshot.BoneNames[i].ToString(), Transforms);
99 }
100}
101
103{
104 auto *Character = GetCharacter();
105 if (!Character) return;
106
107 TArray<USkeletalMeshComponent *> SkeletalMeshes;
108 Character->GetComponents<USkeletalMeshComponent>(SkeletalMeshes, false);
109 USkeletalMeshComponent *SkeletalMesh = SkeletalMeshes.IsValidIndex(0) ? SkeletalMeshes[0] : nullptr;
110 if (!SkeletalMesh) return;
111
112 // 获取行人动画的类
113 auto *AnimInst = SkeletalMesh->GetAnimInstance();
114 if (!AnimInst) return;
115 UWalkerAnim *WalkerAnim = Cast<UWalkerAnim>(AnimInst);
116 if (!WalkerAnim) return;
117
118 // 如果姿势为空,则获得第一个版本
119 if (WalkerAnim->Snap.BoneNames.Num() == 0)
120 {
121 // 获得当前的姿势
122 SkeletalMesh->SnapshotPose(WalkerAnim->Snap);
123 }
124
125 TMap<FName, FTransform> BonesMap;
126 for (const TPair<FString, FTransform> &pair : WalkerBones.BoneTransforms)
127 {
128 FName BoneName = FName(*pair.Key);
129 BonesMap.Add(BoneName, pair.Value);
130 }
131
132 // 分配常用骨架
133 for (int i=0; i<WalkerAnim->Snap.BoneNames.Num(); ++i)
134 {
135 FTransform *Trans = BonesMap.Find(WalkerAnim->Snap.BoneNames[i]);
136 if (Trans)
137 {
138 WalkerAnim->Snap.LocalTransforms[i] = *Trans;
139 }
140 }
141}
142
144{
145 auto *Character = GetCharacter();
146 if (!Character) return;
147
148 TArray<USkeletalMeshComponent *> SkeletalMeshes;
149 Character->GetComponents<USkeletalMeshComponent>(SkeletalMeshes, false);
150 USkeletalMeshComponent *SkeletalMesh = SkeletalMeshes.IsValidIndex(0) ? SkeletalMeshes[0] : nullptr;
151 if (!SkeletalMesh) return;
152
153 // 获得行人动画类
154 auto *AnimInst = SkeletalMesh->GetAnimInstance();
155 if (!AnimInst) return;
156 UWalkerAnim *WalkerAnim = Cast<UWalkerAnim>(AnimInst);
157 if (!WalkerAnim) return;
158
159 // 设置当前姿势
160 WalkerAnim->Blend = Blend;
161}
162
164{
165 auto *Character = GetCharacter();
166 if (!Character) return;
167
168 TArray<USkeletalMeshComponent *> SkeletalMeshes;
169 Character->GetComponents<USkeletalMeshComponent>(SkeletalMeshes, false);
170 USkeletalMeshComponent *SkeletalMesh = SkeletalMeshes.IsValidIndex(0) ? SkeletalMeshes[0] : nullptr;
171 if (!SkeletalMesh) return;
172
173 // 获得行人动画类
174 auto *AnimInst = SkeletalMesh->GetAnimInstance();
175 if (!AnimInst) return;
176 UWalkerAnim *WalkerAnim = Cast<UWalkerAnim>(AnimInst);
177 if (!WalkerAnim) return;
178
179 // 获得当前姿势
180 SkeletalMesh->SnapshotPose(WalkerAnim->Snap);
181}
182// AWalkerController类的Tick成员函数,用于处理每一帧的更新逻辑
183// DeltaSeconds参数表示从上一帧到当前帧的时间间隔
184void AWalkerController::Tick(float DeltaSeconds)
185{// 使用TRACE_CPUPROFILER_EVENT_SCOPE宏来标记这个函数的执行范围
186 // 这通常用于性能分析,以便在性能分析工具中查看此函数的执行时间和频率
187 TRACE_CPUPROFILER_EVENT_SCOPE(AWalkerController::Tick);
188 // 调用父类的Tick函数,以确保父类的更新逻辑得到执行
189 // Super通常是一个宏,用于引用当前类的父类
190 Super::Tick(DeltaSeconds);
191// 获取当前控制的角色实例
192 auto *Character = GetCharacter();
193 // 如果没有获取到有效的角色实例,则直接返回,不进行后续操作
194 if (!Character) return;
195// 根据控制输入(方向和速度)来添加角色的移动输入
196 // Control.Direction表示移动方向,Control.Speed表示请求的移动速度
197 // GetMaximumWalkSpeed()函数返回角色能行走的最大速度
198 // 通过将Control.Speed除以最大行走速度,可以得到一个0到1之间的比例,用于控制角色的实际移动速度
199 Character->AddMovementInput(Control.Direction,
201 // 如果控制输入中包含了跳跃指令
202 // 则调用角色的Jump函数来执行跳跃动作
203 if (Control.Jump)
204 {
205 Character->Jump();
206 }
207}
UE_LOG(LogCarla, Log, TEXT("UActorDispatcher::Destroying actor: '%s' %x"), *Id, Actor)
void Tick(float DeltaSeconds) override
float GetMaximumWalkSpeed() const
允许的最大步行速度(以厘米/秒为单位)。
void ApplyWalkerControl(const FWalkerControl &InControl)
void BlendPose(float Blend)
void SetBonesTransform(const FWalkerBoneControlIn &WalkerBones)
FWalkerControl Control
AWalkerController(const FObjectInitializer &ObjectInitializer)
void OnPossess(APawn *InPawn) override
void GetBonesTransform(FWalkerBoneControlOut &WalkerBones)
FPoseSnapshot Snap
Definition WalkerAnim.h:25
float Blend
Definition WalkerAnim.h:22