CARLA
WalkerController.cpp
Go to the documentation of this file.
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"
10 
11 #include "Components/PoseableMeshComponent.h"
12 #include "Components/PrimitiveComponent.h"
13 #include "Containers/Map.h"
14 #include "GameFramework/Character.h"
15 #include "GameFramework/CharacterMovementComponent.h"
16 #include "GameFramework/Pawn.h"
17 
18 AWalkerController::AWalkerController(const FObjectInitializer &ObjectInitializer)
19  : Super(ObjectInitializer)
20 {
21  PrimaryActorTick.bCanEverTick = true;
22 }
23 
25 {
26  Super::OnPossess(InPawn);
27 
28  auto *Character = Cast<ACharacter>(InPawn);
29  if (Character == nullptr)
30  {
31  UE_LOG(LogCarla, Error, TEXT("Walker is not a character!"));
32  return;
33  }
34 
35  auto *MovementComponent = Character->GetCharacterMovement();
36  if (MovementComponent == nullptr)
37  {
38  UE_LOG(LogCarla, Error, TEXT("Walker missing character movement component!"));
39  return;
40  }
41 
42  MovementComponent->MaxWalkSpeed = GetMaximumWalkSpeed();
43  MovementComponent->JumpZVelocity = 500.0f;
44  Character->JumpMaxCount = 2;
45 }
46 
48 {
49  Control = InControl;
50 }
51 
53 {
54  auto *Character = GetCharacter();
55  if (!Character) return;
56 
57  TArray<USkeletalMeshComponent *> SkeletalMeshes;
58  Character->GetComponents<USkeletalMeshComponent>(SkeletalMeshes, false);
59  USkeletalMeshComponent *SkeletalMesh = SkeletalMeshes.IsValidIndex(0) ? SkeletalMeshes[0] : nullptr;
60  if (!SkeletalMesh) return;
61 
62  // get the walker animation class
63  auto *AnimInst = SkeletalMesh->GetAnimInstance();
64  if (!AnimInst) return;
65  UWalkerAnim *WalkerAnim = Cast<UWalkerAnim>(AnimInst);
66  if (!WalkerAnim) return;
67 
68  // get current pose
69  FPoseSnapshot TempSnapshot;
70  SkeletalMesh->SnapshotPose(TempSnapshot);
71 
72  // copy pose
73  // WalkerAnim->Snap = TempSnapshot;
74 
75  for (int i=0; i<TempSnapshot.BoneNames.Num(); ++i)
76  {
77  FWalkerBoneControlOutData Transforms;
78  Transforms.World = SkeletalMesh->GetSocketTransform(TempSnapshot.BoneNames[i], ERelativeTransformSpace::RTS_World);
79  Transforms.Component = SkeletalMesh->GetSocketTransform(TempSnapshot.BoneNames[i], ERelativeTransformSpace::RTS_Actor);
80  Transforms.Relative = SkeletalMesh->GetSocketTransform(TempSnapshot.BoneNames[i], ERelativeTransformSpace::RTS_ParentBoneSpace);
81  // Transforms.Relative = TempSnapshot.LocalTransforms[i];
82 
83  WalkerBones.BoneTransforms.Add(TempSnapshot.BoneNames[i].ToString(), Transforms);
84  }
85 }
86 
88 {
89  auto *Character = GetCharacter();
90  if (!Character) return;
91 
92  TArray<USkeletalMeshComponent *> SkeletalMeshes;
93  Character->GetComponents<USkeletalMeshComponent>(SkeletalMeshes, false);
94  USkeletalMeshComponent *SkeletalMesh = SkeletalMeshes.IsValidIndex(0) ? SkeletalMeshes[0] : nullptr;
95  if (!SkeletalMesh) return;
96 
97  // get the walker animation class
98  auto *AnimInst = SkeletalMesh->GetAnimInstance();
99  if (!AnimInst) return;
100  UWalkerAnim *WalkerAnim = Cast<UWalkerAnim>(AnimInst);
101  if (!WalkerAnim) return;
102 
103  // if pose is empty, then get a first version
104  if (WalkerAnim->Snap.BoneNames.Num() == 0)
105  {
106  // get current pose
107  SkeletalMesh->SnapshotPose(WalkerAnim->Snap);
108  }
109 
110  TMap<FName, FTransform> BonesMap;
111  for (const TPair<FString, FTransform> &pair : WalkerBones.BoneTransforms)
112  {
113  FName BoneName = FName(*pair.Key);
114  BonesMap.Add(BoneName, pair.Value);
115  }
116 
117  // assign common bones
118  for (int i=0; i<WalkerAnim->Snap.BoneNames.Num(); ++i)
119  {
120  FTransform *Trans = BonesMap.Find(WalkerAnim->Snap.BoneNames[i]);
121  if (Trans)
122  {
123  WalkerAnim->Snap.LocalTransforms[i] = *Trans;
124  }
125  }
126 }
127 
129 {
130  auto *Character = GetCharacter();
131  if (!Character) return;
132 
133  TArray<USkeletalMeshComponent *> SkeletalMeshes;
134  Character->GetComponents<USkeletalMeshComponent>(SkeletalMeshes, false);
135  USkeletalMeshComponent *SkeletalMesh = SkeletalMeshes.IsValidIndex(0) ? SkeletalMeshes[0] : nullptr;
136  if (!SkeletalMesh) return;
137 
138  // get the walker animation class
139  auto *AnimInst = SkeletalMesh->GetAnimInstance();
140  if (!AnimInst) return;
141  UWalkerAnim *WalkerAnim = Cast<UWalkerAnim>(AnimInst);
142  if (!WalkerAnim) return;
143 
144  // set current pose
145  WalkerAnim->Blend = Blend;
146 }
147 
149 {
150  auto *Character = GetCharacter();
151  if (!Character) return;
152 
153  TArray<USkeletalMeshComponent *> SkeletalMeshes;
154  Character->GetComponents<USkeletalMeshComponent>(SkeletalMeshes, false);
155  USkeletalMeshComponent *SkeletalMesh = SkeletalMeshes.IsValidIndex(0) ? SkeletalMeshes[0] : nullptr;
156  if (!SkeletalMesh) return;
157 
158  // get the walker animation class
159  auto *AnimInst = SkeletalMesh->GetAnimInstance();
160  if (!AnimInst) return;
161  UWalkerAnim *WalkerAnim = Cast<UWalkerAnim>(AnimInst);
162  if (!WalkerAnim) return;
163 
164  // get current pose
165  SkeletalMesh->SnapshotPose(WalkerAnim->Snap);
166 }
167 
168 void AWalkerController::Tick(float DeltaSeconds)
169 {
170  TRACE_CPUPROFILER_EVENT_SCOPE(AWalkerController::Tick);
171  Super::Tick(DeltaSeconds);
172 
173  auto *Character = GetCharacter();
174  if (!Character) return;
175 
176  Character->AddMovementInput(Control.Direction,
178  if (Control.Jump)
179  {
180  Character->Jump();
181  }
182 }
FPoseSnapshot Snap
Definition: WalkerAnim.h:25
void BlendPose(float Blend)
void ApplyWalkerControl(const FWalkerControl &InControl)
float Blend
Definition: WalkerAnim.h:22
FWalkerControl Control
void OnPossess(APawn *InPawn) override
float GetMaximumWalkSpeed() const
Maximum walk speed allowed in centimetres per second.
AWalkerController(const FObjectInitializer &ObjectInitializer)
void GetBonesTransform(FWalkerBoneControlOut &WalkerBones)
void Tick(float DeltaSeconds) override
void SetBonesTransform(const FWalkerBoneControlIn &WalkerBones)