How can i do a LineTrace which can only hit the Landscape in C++?

Hey, i want to do a LineTrace which can only hit the Landscape, and nothing else.

I know that you can select “Landscape” as a TraceChannel in Blueprints:

So, how can i do this in C++?

My code looks like this:

  1. FCollisionQueryParams RV_TraceParams = FCollisionQueryParams(FName(TEXT("RV_Trace")), true, this);

  2. RV_TraceParams.bTraceComplex = true;

  3. RV_TraceParams.bTraceAsyncScene = true;

  4. RV_TraceParams.bReturnPhysicalMaterial = false;

  5. FVector Start = WorldLocation;

  6. FVector End = Start + (WorldDirection * 10000000);

  7. FHitResult RV_Hit;

  8. bool success = GetWorld()->LineTraceSingleByChannel(RV_Hit,Start,End,ECC_Visibility,RV_TraceParams);

What can i add instead of “ECC_Visibility”? I Have added a custom Trace Channel in the Editor, but i dont know how to access it in visual studio. And there is no “ECC_Landscape”…

Thanks in advance. =)

Thank you!
Now i have found my custom trace channel. I only looked into the DefaultGame.ini and not into the DefaultEngine.ini…

Actually, i first tried ECC_WorldStatic. My other Objects were all WorldDynamic or something else but it was not working… - But the custom channel works fine :slight_smile:

EngineTypes.h has this enum definition:

UENUM(BlueprintType)
enum ECollisionChannel
{
	/**
	* @NOTE!!!! This DisplayName [DISPLAYNAME] SHOULD MATCH suffix of ECC_DISPLAYNAME
	* Otherwise it will mess up collision profile loading
	* If you change this, please also change FCollisionResponseContainers
	* 
	* If you add any more TraceQuery="1", you also should change UCollsionProfile::LoadProfileConfig
	* Metadata doesn't work outside of editor, so you'll need to add manually 
	*/
	ECC_WorldStatic UMETA(DisplayName="WorldStatic"),
	ECC_WorldDynamic UMETA(DisplayName="WorldDynamic"),
	ECC_Pawn UMETA(DisplayName="Pawn"),
	ECC_Visibility UMETA(DisplayName="Visibility" , TraceQuery="1"),
	ECC_Camera UMETA(DisplayName="Camera" , TraceQuery="1"),
	ECC_PhysicsBody UMETA(DisplayName="PhysicsBody"),
	ECC_Vehicle UMETA(DisplayName="Vehicle"),
	ECC_Destructible UMETA(DisplayName="Destructible"),
	// @NOTE : when you add more here for predefined engine channel
	// please change the max in the CollisionProfile
	// search ECC_Destructible

	// Unspecified Engine Trace Channels
	ECC_EngineTraceChannel1 UMETA(Hidden),
	ECC_EngineTraceChannel2 UMETA(Hidden),
	ECC_EngineTraceChannel3 UMETA(Hidden),
	ECC_EngineTraceChannel4 UMETA(Hidden), 
	ECC_EngineTraceChannel5 UMETA(Hidden),
	ECC_EngineTraceChannel6 UMETA(Hidden),

	// in order to use this custom channels
	// we recommend to define in your local file
	// - i.e. #define COLLISION_WEAPON		ECC_GameTraceChannel1
	// and make sure you customize these it in INI file by
	// 
	// in DefaultEngine.ini
	//
	// [/Script/Engine.CollisionProfile]
	// GameTraceChannel1="Weapon"
	// 
	// also in the INI file, you can override collision profiles that are defined by simply redefining
	// note that Weapon isn't defined in the BaseEngine.ini file, but "Trigger" is defined in Engine
	// +Profiles=(Name="Trigger",CollisionEnabled=QueryOnly,ObjectTypeName=WorldDynamic, DefaultResponse=ECR_Overlap, CustomResponses=((Channel=Visibility, Response=ECR_Ignore), (Channel=Weapon, Response=ECR_Ignore)))
	ECC_GameTraceChannel1 UMETA(Hidden),
	ECC_GameTraceChannel2 UMETA(Hidden),
	ECC_GameTraceChannel3 UMETA(Hidden),
	ECC_GameTraceChannel4 UMETA(Hidden),
	ECC_GameTraceChannel5 UMETA(Hidden),
	ECC_GameTraceChannel6 UMETA(Hidden),
	ECC_GameTraceChannel7 UMETA(Hidden),
	ECC_GameTraceChannel8 UMETA(Hidden),
	ECC_GameTraceChannel9 UMETA(Hidden),
	ECC_GameTraceChannel10 UMETA(Hidden),
	ECC_GameTraceChannel11 UMETA(Hidden),
	ECC_GameTraceChannel12 UMETA(Hidden),
	ECC_GameTraceChannel13 UMETA(Hidden),
	ECC_GameTraceChannel14 UMETA(Hidden),
	ECC_GameTraceChannel15 UMETA(Hidden),
	ECC_GameTraceChannel16 UMETA(Hidden),
	ECC_GameTraceChannel17 UMETA(Hidden),
	ECC_GameTraceChannel18 UMETA(Hidden),
	
	/** Add new serializeable channels above here (i.e. entries that exist in FCollisionResponseContainer) */
	/** Add only nonserialized/transient flags below */

	// NOTE!!!! THESE ARE BEING DEPRECATED BUT STILL THERE FOR BLUEPRINT. PLEASE DO NOT USE THEM IN CODE
	/** 
	 * This can be used to get all overlap event. If you trace with this channel, 
	 * It will return everything except its own. Do not use this often as this is expensive operation
	 */
	 /**
	  * can't add displaynames because then it will show up in the collision channel option
	  */
	ECC_OverlapAll_Deprecated UMETA(Hidden),
	ECC_MAX,
};

If you search for “Landscape” in your INI’s you should be able to see what custom ECC it’s using under the hood. Also, you may want to consider using ECC_WorldStatic (which should only contain static geometry and the landscape), just so you can free up that channel for some other use down the line (but that may or may not be needed - your call).

I also have same issue. Is it an engine bug? If yes it feels like a big possibility to optimization.

        FHitResult Result;
	FCollisionQueryParams Params;
	TArray<AActor*> IgnoredActors;
	IgnoredActors.Add(this);
	IgnoredActors.Add(GetOwner());
	Params.AddIgnoredActors(IgnoredActors);

	GetWorld()->LineTraceSingleByChannel(
		Result,
		GetActorTransform().GetLocation(),
		GetActorTransform().GetLocation() + GetActorForwardVector() * MaxGroundTraceDistance,
		ECollisionChannel::ECC_WorldStatic,
		Params
	);

Stops on pawn. And If I am not adding weapon and weapon owner it stops on the owner.
This is what I have on the pawn

Okay, I just realized that it was collision on the StaticMeshComponent.
I thought UE uses only root component collision, but for linetraces it probably uses more.

I’ve changed collision preset on the Static Mesh component to the NoCollision and it helped.

You want to use LineTraceSingleByObjectType(), not by channel. “By channel” means it’s going to use the trace channels to determine what is hit (aka all the “responses” check-boxes under the main collision settings). “By object” means you’re going to consider the object type (the “Object Type” collision setting immediately above the check-boxes). Use LineTraceSingleByObjectType() and you won’t hit the pawn/weapon/etc as long as they aren’t set to the same object type.