# How to change Decal's rotation at runtime relative to the floor or wall? C++

**URL:** <https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014>\
**Category:** C++\
**Tags:** Raycast, unreal-engine, CPP\
**Created:** [March 30, 2022, 8:02pm UTC](https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014 "2022-03-30T20:02:19Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Quaked54](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@Quaked54](https://forums.unrealengine.com/u/Quaked54)\
**Post date:** [March 30, 2022, 8:02pm UTC](https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014/1 "2022-03-30T20:02:19Z")

</div>

I have done this before successfully and for some reason the decal will not spawn anymore. I have the correct collision channels ticked I also created my own specific collision channel for the linetrace that is going to create the exit hole. One day I don’t know what happened now either my code is now irrelevant or the engine has a bug. I don’t understand why this is happening.  
Here is the code:

```auto
FCollisionResponseParams ResponseParams;
FCollisionQueryParams RifleQueryParams = FCollisionQueryParams::DefaultQueryParam;
FActorSpawnParameters SpawnParams;
RifleQueryParams.bReturnPhysicalMaterial = true;
SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
RifleQueryParams.AddIgnoredComponent(WeaponBaseMesh);
TArray<FHitResult>Hit;
const FVector RifleStartTrace = WeaponBaseMesh->GetSocketLocation(FName("BarrelSocket"));
FRotator CurrentRotation = WeaponBaseMesh->GetSocketRotation(FName("BarrelSocket"));
 FVector EndTrace = RifleStartTrace + CurrentRotation.Vector() * 10000.0f;
DrawDebugLine(GetWorld(), RifleStartTrace, EndTrace, FColor::Red, false, 1.0f, 0, 1.0);
//Here is the multiline trace by channel causing the first hit.
if (GetWorld()->LineTraceMultiByChannel(Hit, RifleStartTrace, EndTrace, ECollisionChannel::ECC_GameTraceChannel1, RifleQueryParams, ResponseParams))
{
for (FHitResult& Results : EnemyHit)
{
//Here is the first result.
if (AEnemy* Enemy = Cast<AEnemy>(Results.GetActor()))
{
FHitResult LineTraceEndHit2;
FCollisionResponseParams ResponseLineParams;
FCollisionQueryParams LineQueryParams = FCollisionQueryParams(SCENE_QUERY_STAT(WeaponTrace), false, this);
FActorSpawnParameters LineSpawnParams;
LineSpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
LineQueryParams.AddIgnoredComponent(WeaponBaseMesh);
const FVector ExitLineStartTrace = StartTrace;
FRotator ExitLineCurrentRotation = EndTrace.Rotation();
FVector ExitLineEndTrace = EndTrace + ExitLineCurrentRotation .Vector();
DrawDebugLine(GetWorld(), ExitLineStartTrace , ExitLineEndTrace , FColor(255, 0, 0), false, -1, 0, 5.333);
//Here is the second line trace. I don't understand why the second is not firing off correctly I know I am attaching it to the exit point of the first line trace which hits the character. Now I know the second line trace much activate in order to create a exit hole. 
if (GetWorld()->LineTraceSingleByChannel(LineTraceEndHit2, ExitLineStartTrace , ExitLineEndTrace, ECollisionChannel::ECC_GameTraceChannel4, LineQueryParams , ResponseLineParams))
{
   //Here is where the second line trace fires once the enemy has been hit. 
if (AActor* Actor = Cast<AActor>(LineTraceEndHit2.GetActor()))
{
GEngine->AddOnScreenDebugMessage(-1, 20.0f, FColor::Orange, FString::Printf(TEXT("Blood Has spawned")));
FVector DecalSize(20.0f, 20.0f, 20.0f);
FRotator RandomDecalRotation = LineTraceEndHit2.TraceEnd.Rotation();
RandomDecalRotation = FRotator(90,0,0);
FVector DecalLocation = LineTraceEndHit2.Location;
UGameplayStatics::SpawnDecalAtLocation(Actor, BloodDecal, DecalSize, DecalLocation, RandomDecalRotation, 10.0f);
		}

}

```

---

<div class="post-metadata">

**Author:** ![Quaked54](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@Quaked54](https://forums.unrealengine.com/u/Quaked54)\
**Post date:** [March 30, 2022, 9:38pm UTC](https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014/2 "2022-03-30T21:38:50Z")

</div>

I figured it out. Supposedly I cannot use custom trace channels for single line traces. I can use custom trace channels for multi line trace by channels.

---

<div class="post-metadata">

**Author:** ![Quaked54](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@Quaked54](https://forums.unrealengine.com/u/Quaked54)\
**Post date:** [March 30, 2022, 10:25pm UTC](https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014/3 "2022-03-30T22:25:32Z")

</div>

But the only other question for me is that the decal spawns in different rotations relative to the wall and or the floor how can I dynamically change the decal’s rotation at runtime?

---

<div class="post-metadata">

**Author:** ![jwatte](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/jwatte/32/744941_2.png) [@jwatte](https://forums.unrealengine.com/u/jwatte)\
**Post date:** [March 30, 2022, 11:53pm UTC](https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014/4 "2022-03-30T23:53:24Z")

</div>

Instead of using LineTrace.Rotation(), you can construct your own rotation based on whatever you want the coordinate frame to be.

Typically, you’ll use the normal of the surface hit as “up,” (Z vector) and then you construct the “right” (Y vector) using some combination of cross product and normalization, and then finally construct forward (X vector) using Y cross Z.

For example, you can say that if the absolute of the Z value of the surface normal is greater than 0.8, then use Absolute X as the vector to cross-construct with, else use Absolute Z (up.) You need something like this, because absolute Up is the same as the surface normal of a horizontal floor, and thus a cross product would be zero.

Once you have your reference frame, you can turn it into a rotator to pass into the spawn-decal function.

Example code:

```auto
FVector impactNormal = ...;
FVector basis = FVector(0, 0, 1);
if (fabsf(impactNormal.Z) > 0.8) {
    basis = FVector(1, 0, 0);
}
FVector right = CrossProduct(impactNormal, basis).GetUnsafeNormal();
FVector forward = CrossProduct(right, impactNormal);
FBasisVectorMatrix bvm(forward, right, impactNormal, FVector(0, 0, 0));
FRotator theRotation = bvm.Rotator();

```

---

<div class="post-metadata">

**Author:** ![Quaked54](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@Quaked54](https://forums.unrealengine.com/u/Quaked54)\
**Post date:** [April 1, 2022, 2:26pm UTC](https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014/5 "2022-04-01T14:26:56Z")

</div>

> [@jwatte](#):
>
> `CrossProduct`

How would I form a function using this term and what is a cross product?

---

<div class="post-metadata">

**Author:** ![Quaked54](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@Quaked54](https://forums.unrealengine.com/u/Quaked54)\
**Post date:** [April 1, 2022, 2:27pm UTC](https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014/6 "2022-04-01T14:27:49Z")

</div>

> [@jwatte](#):
>
> `impactNormal `

What would I use to initialize the variable impact normal?

---

<div class="post-metadata">

**Author:** ![Quaked54](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@Quaked54](https://forums.unrealengine.com/u/Quaked54)\
**Post date:** [April 1, 2022, 2:42pm UTC](https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014/7 "2022-04-01T14:42:50Z")

</div>

So far this is what I have tried it seems to work. But is unpredictable.

```auto
	FVector DecalSize(20.0f, 20.0f, 20.0f);
	FVector ActorRot = GetActorRotation().Vector();
	FRotator RandomDecalRotation = ActorRot.Rotation();
	FVector DecalLocation = TraceEndHit.Location;

```

---

<div class="post-metadata">

**Author:** ![jwatte](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/jwatte/32/744941_2.png) [@jwatte](https://forums.unrealengine.com/u/jwatte)\
**Post date:** [April 1, 2022, 8:39pm UTC](https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014/8 "2022-04-01T20:39:42Z")

</div>

A cross product is a very important concept in 3D math. If you’re going to be doing 3D game development, I highly recommend reading up on matrix/vector algebra, dot products, and cross products. Wikipedia is accurate and correct, but perhaps not the best introductory tutorial 🙂 [Cross product - Wikipedia](https://en.wikipedia.org/wiki/Cross_product)

To get the surface/impact normal where you’re placing the decal, you have to look at what mecahnism you use to figure out where the place the decal.  
For example, if you ray-cast, or place decals in response to collision detection, then you will have a collision result, and that result will have an impact (surface) normal within it.  
For example, [FHitResult contains an ImpactNormal](https://docs.unrealengine.com/4.27/en-US/API/Runtime/Engine/Engine/FHitResult/) field.

The code you pasted has a `TraceEndHit`, so that should contain the impact/surface normal.

Using the rotation of whatever the actor is, is not generally going to be robust, because it has little to no correlation with the actual surface orientation that was hit.

---

<div class="post-metadata">

**Author:** ![Quaked54](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@Quaked54](https://forums.unrealengine.com/u/Quaked54)\
**Post date:** [April 2, 2022, 3:17am UTC](https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014/9 "2022-04-02T03:17:47Z")

</div>

But how would I go about creating a function to calculate the cross product?

---

<div class="post-metadata">

**Author:** ![Quaked54](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@Quaked54](https://forums.unrealengine.com/u/Quaked54)\
**Post date:** [April 2, 2022, 3:19am UTC](https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014/10 "2022-04-02T03:19:07Z")

</div>

> [@jwatte](#):
>
> `.GetUnsafeNormal();`

Does this function exist?

---

<div class="post-metadata">

**Author:** ![Quaked54](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@Quaked54](https://forums.unrealengine.com/u/Quaked54)\
**Post date:** [April 2, 2022, 3:26am UTC](https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014/11 "2022-04-02T03:26:24Z")

</div>

I created a FVector function now I need to pass in 2 parameters then calculate both values. GetUnSafeNormal() is a real function sorry woops.

---

<div class="post-metadata">

**Author:** ![Quaked54](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@Quaked54](https://forums.unrealengine.com/u/Quaked54)\
**Post date:** [April 2, 2022, 4:27am UTC](https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014/12 "2022-04-02T04:27:54Z")

</div>

Would this be a likely way of creating the function?  
`FVector ABase::CrossProduct(FVector Product1, FVector Product2) { ReturnProduct.CrossProduct(Product2, Product1).Normalize(); return ReturnProduct; }`

---

<div class="post-metadata">

**Author:** ![jwatte](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/jwatte/32/744941_2.png) [@jwatte](https://forums.unrealengine.com/u/jwatte)\
**Post date:** [April 2, 2022, 5:21am UTC](https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014/13 "2022-04-02T05:21:57Z")

</div>

These are all in the documentation. The top google hit for “unreal engine C++ fvector” is this: [FVector | Unreal Engine Documentation](https://docs.unrealengine.com/4.27/en-US/API/Runtime/Core/Math/FVector/)

Or you can just select a FVector, and press F12, and jump to the header, where all the functions are declared.

Note that CrossProduct is a static member function.

---

<div class="post-metadata">

**Author:** ![Quaked54](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@Quaked54](https://forums.unrealengine.com/u/Quaked54)\
**Post date:** [April 2, 2022, 5:46am UTC](https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014/14 "2022-04-02T05:46:23Z")

</div>

But is the way I am using this function correct?  
This is a non static function that calculates the cross product of both vectors and returns a value.

> [@Quaked54](#):
>
> FVector ABase::CrossProduct(FVector Product1, FVector Product2) { ReturnProduct.CrossProduct(Product2, Product1).Normalize(); return ReturnProduct; }

---

<div class="post-metadata">

**Author:** ![Quaked54](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@Quaked54](https://forums.unrealengine.com/u/Quaked54)\
**Post date:** [April 2, 2022, 12:26pm UTC](https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014/15 "2022-04-02T12:26:56Z")

</div>

I don’t wanna be that guy but is it possible to find a simpler maybe perhaps less precise answer to this issue? I don’t’ fully understand your example but I really do appreciate your help.

---

<div class="post-metadata">

**Author:** ![jwatte](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/jwatte/32/744941_2.png) [@jwatte](https://forums.unrealengine.com/u/jwatte)\
**Post date:** [April 2, 2022, 4:57pm UTC](https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014/16 "2022-04-02T16:57:16Z")

</div>

To call a static member function when you’re not in the inner scope of the defining class, name the class explicitly:

```auto
FVector right = FVector::CrossProduct(impactNormal, basis).GetUnsafeNormal();

```

(Note the `FVector::` part)

Is there an easier way to “find a consistent orientation that aligns with a particular vector?” No, not really. This is the math that needs to happen.

There might be code in the Unreal libraries that does something very similar to this code, and the function is already there to be used. I haven’t memorized all the Unreal helper functions, but it looks like [FRotationMatrix::MakeFromZX()](https://docs.unrealengine.com/4.27/en-US/API/Runtime/Core/Math/FRotationMatrix/MakeFromZX/) might be helpful.  
The “Z” vector should be the surface normal, and the “X” vector should be whatever vector you choose as the reference for clocking (e g, “north” in the above example.)

```auto
FVector impactNormal = TraceEndHit.Normal;
FVector basis = FVector(0, 0, 1);
if (fabsf(impactNormal.Z) > 0.8) {
    basis = FVector(1, 0, 0);
}
FMatrix rotation = FRotationMatrix::MakeFromZX(impactNormal, basis);

```

---

<div class="post-metadata">

**Author:** ![Quaked54](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@Quaked54](https://forums.unrealengine.com/u/Quaked54)\
**Post date:** [April 4, 2022, 9:32pm UTC](https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014/17 "2022-04-04T21:32:02Z")

</div>

Thank you man very much I really do appreciate the simplification. You are kind.

---

<div class="post-metadata">

**Author:** ![Quaked54](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@Quaked54](https://forums.unrealengine.com/u/Quaked54)\
**Post date:** [April 4, 2022, 9:35pm UTC](https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014/18 "2022-04-04T21:35:49Z")

</div>

> [@jwatte](#):
>
> `FVector::CrossProduct(impactNormal, basis).GetUnsafeNormal();`

Just the fact that there is a function specifically for that is awesome!

---

<div class="post-metadata">

**Author:** ![Quaked54](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@Quaked54](https://forums.unrealengine.com/u/Quaked54)\
**Post date:** [April 4, 2022, 9:38pm UTC](https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014/19 "2022-04-04T21:38:24Z")

</div>

I thought I would have to declare a function then write the crossproduct calculation from scratch within the declared function. Just the fact that there is a static member function specifically for cross products is pretty cool.

---

<div class="post-metadata">

**Author:** ![Jambax](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/jambax/32/904177_2.png) [@Jambax](https://forums.unrealengine.com/u/Jambax)\
**Post date:** [April 6, 2022, 9:28am UTC](https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014/20 "2022-04-06T09:28:44Z")

</div>

Note that the correct orientation is FRotationMatrix::MakeFromXZ(-ImpactNormal, MyOtherVector).

Decals project along their local +X axis, so you want it to project _ **into** _ the surface normal, not parallel with it. In decals with normal maps, this matters a lot.

[Next page](https://forums.unrealengine.com/t/how-to-change-decals-rotation-at-runtime-relative-to-the-floor-or-wall-c/511014.md?page=2)
