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
30// AWalkerController类的构造函数
31// FObjectInitializer参数用于初始化对象属性
32AWalkerController::AWalkerController(const FObjectInitializer &ObjectInitializer)
33 : Super(ObjectInitializer)
34{
35 // 设置PrimaryActorTick.bCanEverTick为true,表示这个Actor(行人控制器)可以在每一帧都被更新
36 PrimaryActorTick.bCanEverTick = true;
37}
38
39// 当AWalkerController“占有”一个APawn时,会调用此函数
40// InPawn参数指向被占有的Pawn
42{
43 // 调用父类的OnPossess函数
44 Super::OnPossess(InPawn);
45
46 auto *Character = Cast<ACharacter>(InPawn);
47 if (Character == nullptr)
48 {
49 UE_LOG(LogCarla, Error, TEXT("Walker is not a character!"));
50 return;
51 }
52
53 auto *MovementComponent = Character->GetCharacterMovement();
54 if (MovementComponent == nullptr)
55 {
56 UE_LOG(LogCarla, Error, TEXT("Walker missing character movement component!"));
57 return;
58 }
59 // 设置角色的最大行走速度
60 MovementComponent->MaxWalkSpeed = GetMaximumWalkSpeed();
61 // 设置角色的跳跃垂直速度
62 MovementComponent->JumpZVelocity = 500.0f;// 一个硬编码的跳跃速度值
63 Character->JumpMaxCount = 2;
64}
65
67{
68 Control = InControl;
69}
70
72{
73 auto *Character = GetCharacter();
74 if (!Character) return;
75
76 TArray<USkeletalMeshComponent *> SkeletalMeshes;
77 Character->GetComponents<USkeletalMeshComponent>(SkeletalMeshes, false);
78 USkeletalMeshComponent *SkeletalMesh = SkeletalMeshes.IsValidIndex(0) ? SkeletalMeshes[0] : nullptr;
79 if (!SkeletalMesh) return;
80
81 // 获取行人的动画类
82 auto *AnimInst = SkeletalMesh->GetAnimInstance();
83 if (!AnimInst) return;
84 UWalkerAnim *WalkerAnim = Cast<UWalkerAnim>(AnimInst);
85 if (!WalkerAnim) return;
86
87 // 获取当前的姿态
88 FPoseSnapshot TempSnapshot;
89 SkeletalMesh->SnapshotPose(TempSnapshot);
90
91 // 拷贝姿态
92 // WalkerAnim->Snap = TempSnapshot;
93
94 for (int i=0; i<TempSnapshot.BoneNames.Num(); ++i)
95 {
97 Transforms.World = SkeletalMesh->GetSocketTransform(TempSnapshot.BoneNames[i], ERelativeTransformSpace::RTS_World);
98 Transforms.Component = SkeletalMesh->GetSocketTransform(TempSnapshot.BoneNames[i], ERelativeTransformSpace::RTS_Actor);
99 Transforms.Relative = SkeletalMesh->GetSocketTransform(TempSnapshot.BoneNames[i], ERelativeTransformSpace::RTS_ParentBoneSpace);
100 // Transforms.Relative = TempSnapshot.LocalTransforms[i];
101
102 WalkerBones.BoneTransforms.Add(TempSnapshot.BoneNames[i].ToString(), Transforms);
103 }
104}
105
107{
108 auto *Character = GetCharacter();
109 if (!Character) return;
110
111 TArray<USkeletalMeshComponent *> SkeletalMeshes;
112 Character->GetComponents<USkeletalMeshComponent>(SkeletalMeshes, false);
113 USkeletalMeshComponent *SkeletalMesh = SkeletalMeshes.IsValidIndex(0) ? SkeletalMeshes[0] : nullptr;
114 if (!SkeletalMesh) return;
115
116 // 获取行人动画的类
117 auto *AnimInst = SkeletalMesh->GetAnimInstance();
118 if (!AnimInst) return;
119 UWalkerAnim *WalkerAnim = Cast<UWalkerAnim>(AnimInst);
120 if (!WalkerAnim) return;
121
122 // 如果姿势为空,则获得第一个版本
123 if (WalkerAnim->Snap.BoneNames.Num() == 0)
124 {
125 // 获得当前的姿势
126 SkeletalMesh->SnapshotPose(WalkerAnim->Snap);
127 }
128
129 TMap<FName, FTransform> BonesMap;
130 for (const TPair<FString, FTransform> &pair : WalkerBones.BoneTransforms)
131 {
132 FName BoneName = FName(*pair.Key);
133 BonesMap.Add(BoneName, pair.Value);
134 }
135
136 // 分配常用骨架
137 for (int i=0; i<WalkerAnim->Snap.BoneNames.Num(); ++i)
138 {
139 FTransform *Trans = BonesMap.Find(WalkerAnim->Snap.BoneNames[i]);
140 if (Trans)
141 {
142 WalkerAnim->Snap.LocalTransforms[i] = *Trans;
143 }
144 }
145}
146
148{
149 auto *Character = GetCharacter();
150 if (!Character) return;
151
152 TArray<USkeletalMeshComponent *> SkeletalMeshes;
153 Character->GetComponents<USkeletalMeshComponent>(SkeletalMeshes, false);
154 USkeletalMeshComponent *SkeletalMesh = SkeletalMeshes.IsValidIndex(0) ? SkeletalMeshes[0] : nullptr;
155 if (!SkeletalMesh) return;
156
157 // 获得行人动画类
158 auto *AnimInst = SkeletalMesh->GetAnimInstance();
159 if (!AnimInst) return;
160 UWalkerAnim *WalkerAnim = Cast<UWalkerAnim>(AnimInst);
161 if (!WalkerAnim) return;
162
163 // 设置当前姿势
164 WalkerAnim->Blend = Blend;
165}
166
168{
169 auto *Character = GetCharacter();
170 if (!Character) return;
171
172 TArray<USkeletalMeshComponent *> SkeletalMeshes;
173 Character->GetComponents<USkeletalMeshComponent>(SkeletalMeshes, false);
174 USkeletalMeshComponent *SkeletalMesh = SkeletalMeshes.IsValidIndex(0) ? SkeletalMeshes[0] : nullptr;
175 if (!SkeletalMesh) return;
176
177 // 获得行人动画类
178 auto *AnimInst = SkeletalMesh->GetAnimInstance();
179 if (!AnimInst) return;
180 UWalkerAnim *WalkerAnim = Cast<UWalkerAnim>(AnimInst);
181 if (!WalkerAnim) return;
182
183 // 获得当前姿势
184 SkeletalMesh->SnapshotPose(WalkerAnim->Snap);
185}
186// AWalkerController类的Tick成员函数,用于处理每一帧的更新逻辑
187// DeltaSeconds参数表示从上一帧到当前帧的时间间隔
188void AWalkerController::Tick(float DeltaSeconds)
189{// 使用TRACE_CPUPROFILER_EVENT_SCOPE宏来标记这个函数的执行范围
190 // 这通常用于性能分析,以便在性能分析工具中查看此函数的执行时间和频率
191 TRACE_CPUPROFILER_EVENT_SCOPE(AWalkerController::Tick);
192 // 调用父类的Tick函数,以确保父类的更新逻辑得到执行
193 // Super通常是一个宏,用于引用当前类的父类
194 Super::Tick(DeltaSeconds);
195// 获取当前控制的角色实例
196 auto *Character = GetCharacter();
197 // 如果没有获取到有效的角色实例,则直接返回,不进行后续操作
198 if (!Character) return;
199// 根据控制输入(方向和速度)来添加角色的移动输入
200 // Control.Direction表示移动方向,Control.Speed表示请求的移动速度
201 // GetMaximumWalkSpeed()函数返回角色能行走的最大速度
202 // 通过将Control.Speed除以最大行走速度,可以得到一个0到1之间的比例,用于控制角色的实际移动速度
203 Character->AddMovementInput(Control.Direction,
205 // 如果控制输入中包含了跳跃指令
206 // 则调用角色的Jump函数来执行跳跃动作
207 if (Control.Jump)
208 {
209 Character->Jump();
210 }
211}
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