CARLA
Loading...
Searching...
No Matches
FrictionTrigger.cpp
Go to the documentation of this file.
1// Copyright (c) 2026 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB). This work is licensed under the terms of the MIT license.
3// For a copy, see <https://opensource.org/licenses/MIT>.
4
5#include "FrictionTrigger.h"
6#include "Carla.h"
8
9AFrictionTrigger::AFrictionTrigger(const FObjectInitializer &ObjectInitializer)
10 : Super(ObjectInitializer)
11{
12 RootComponent = ObjectInitializer.CreateDefaultSubobject<USceneComponent>(this, TEXT("SceneRootComponent"));
13 RootComponent->SetMobility(EComponentMobility::Static);
14
15 TriggerVolume = CreateDefaultSubobject<UBoxComponent>(TEXT("TriggerVolume"));
16 TriggerVolume->SetupAttachment(RootComponent);
17 TriggerVolume->SetHiddenInGame(true);
18 TriggerVolume->SetMobility(EComponentMobility::Static);
19 TriggerVolume->SetCollisionProfileName(FName("OverlapAll"));
20 TriggerVolume->SetGenerateOverlapEvents(true);
21}
22
24{
25 // Register delegate on begin overlap.
26 if (!TriggerVolume->OnComponentBeginOverlap.IsAlreadyBound(this, &AFrictionTrigger::OnTriggerBeginOverlap))
27 {
28 TriggerVolume->OnComponentBeginOverlap.AddDynamic(this, &AFrictionTrigger::OnTriggerBeginOverlap);
29 }
30
31 // Register delegate on end overlap.
32 if (!TriggerVolume->OnComponentEndOverlap.IsAlreadyBound(this, &AFrictionTrigger::OnTriggerEndOverlap))
33 {
34 TriggerVolume->OnComponentEndOverlap.AddDynamic(this, &AFrictionTrigger::OnTriggerEndOverlap);
35 }
36}
37
38void AFrictionTrigger::UpdateWheelsFriction(AActor *OtherActor, TArray<float>& NewFriction)
39{
40 ACarlaWheeledVehicle *Vehicle = Cast<ACarlaWheeledVehicle>(OtherActor);
41 if (Vehicle != nullptr)
42 Vehicle->SetWheelsFrictionScale(NewFriction);
43}
44
46 UPrimitiveComponent * /*OverlappedComp*/,
47 AActor *OtherActor,
48 UPrimitiveComponent * /*OtherComp*/,
49 int32 /*OtherBodyIndex*/,
50 bool /*bFromSweep*/,
51 const FHitResult & /*SweepResult*/)
52{
53 ACarlaWheeledVehicle *Vehicle = Cast<ACarlaWheeledVehicle>(OtherActor);
54 if(Vehicle == nullptr)
55 return;
56
57 // Save original friction of the wheels. A vehicle fires one overlap per
58 // component: save it once, but retry if its wheels did not exist yet.
59 const TArray<float> *Saved = OldFrictionValues.Find(Vehicle);
60 if (Saved == nullptr || Saved->Num() == 0)
61 OldFrictionValues.Add(Vehicle, Vehicle->GetWheelsFrictionScale());
62
63 TArray<float> TriggerFriction = {Friction, Friction, Friction, Friction};
64 UpdateWheelsFriction(Vehicle, TriggerFriction);
65}
66
68 UPrimitiveComponent * /*OverlappedComp*/,
69 AActor *OtherActor,
70 UPrimitiveComponent * /*OtherComp*/,
71 int32 /*OtherBodyIndex*/)
72{
73 // Set back the saved friction once the vehicle's last component has left
74 ACarlaWheeledVehicle *Vehicle = Cast<ACarlaWheeledVehicle>(OtherActor);
75 if(Vehicle == nullptr || TriggerVolume->IsOverlappingActor(Vehicle))
76 return;
77
78 TArray<float> SavedFriction;
79 if (OldFrictionValues.RemoveAndCopyValue(Vehicle, SavedFriction))
80 UpdateWheelsFriction(Vehicle, SavedFriction);
81}
82
83// Called when the game starts or when spawned
85{
86 Super::BeginPlay();
87 Init();
88}
89
90void AFrictionTrigger::EndPlay(const EEndPlayReason::Type EndPlayReason)
91{
92 // Deregister delegates
93 if (TriggerVolume->OnComponentBeginOverlap.IsAlreadyBound(this, &AFrictionTrigger::OnTriggerBeginOverlap))
94 {
95 TriggerVolume->OnComponentBeginOverlap.RemoveDynamic(this, &AFrictionTrigger::OnTriggerBeginOverlap);
96 }
97
98 if (TriggerVolume->OnComponentEndOverlap.IsAlreadyBound(this, &AFrictionTrigger::OnTriggerEndOverlap))
99 {
100 TriggerVolume->OnComponentEndOverlap.RemoveDynamic(this, &AFrictionTrigger::OnTriggerEndOverlap);
101 }
102
103 Super::EndPlay(EndPlayReason);
104}
105
106// Called every frame
107void AFrictionTrigger::Tick(float DeltaTime)
108{
109 Super::Tick(DeltaTime);
110}
Base class for CARLA wheeled vehicles.
virtual void Tick(float DeltaTime) override
virtual void EndPlay(EEndPlayReason::Type EndPlayReason) override
void OnTriggerBeginOverlap(UPrimitiveComponent *OverlappedComp, AActor *OtherActor, UPrimitiveComponent *OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult &SweepResult)
AFrictionTrigger(const FObjectInitializer &ObjectInitializer)
TObjectPtr< UBoxComponent > TriggerVolume
TMap< TWeakObjectPtr< ACarlaWheeledVehicle >, TArray< float > > OldFrictionValues
virtual void BeginPlay() override
void UpdateWheelsFriction(AActor *OtherActor, TArray< float > &NewFriction)
void OnTriggerEndOverlap(UPrimitiveComponent *OverlappedComp, AActor *OtherActor, UPrimitiveComponent *OtherComp, int32 OtherBodyIndex)