Sphere Trace For Objects in C++

I added a new object channel named Point in Project Settings/Collision.

I want to make Spehere Trace Single For Objects in C++. Basicly, i wanna do this in C++.

I searched it for a while and i found this in DefaultEngine.ini :

This didnt work. Trace cant find the object: hit value is false:

	TArray<TEnumAsByte<EObjectTypeQuery>> ObjectTypesArray;
	ObjectTypesArray.Reserve(1);
	ObjectTypesArray.Emplace(ECollisionChannel::ECC_GameTraceChannel1);

	bool hit = UKismetSystemLibrary::SphereTraceSingleForObjects(GetWorld(), StartLocation, EndLocation, 500.f, ObjectTypesArray, false, IgnoredActors, EDrawDebugTrace::ForDuration, OutHit, true);

And this causes intellysense error:

ObjectTypesArray.Add(ECollisionChannel::ECC_GameTraceChannel1);

What should i do? How can i add my own object channel to my TArray? Thanks a lot in advance.

1 Like

You need 2 elements. 1 To call the mesh and set the variables to it, 2 after this you can trace it based on the variable system you set up for the mesh.

Step 3 is to place the parts where the trace hits I’m guessing you want to do that.

Maybe you don’t have the variable system defined and it cannot find anything because you have not set up vector variables. Ray Trace works with vector cords in a x,y,z caspian cords system. A vector is a set of cords on an x,y,z map, often made up by floats.

Most people want to do this with skeletal mesh, it could be done with other things, same rule applies, you need a variable system with Vector variables that contain floats. Since you are tracing an object in space cords you must use vector variables with X,Y.Z and trace it on what axis you want, Z axis for example trace from above to below with sphere radius, since the Z axis is a vertical pole, polar line, trace from above to below.

You need to setup the vector variable system and then something like this GetMesh()->Whatever-mesh-Component what ever mesh you are trying to get.

For single trace you need a start and a stop vector based on vectors you set up for the mesh as initial variables

I don’t think I’m a boot.
He needs vector variables is all I said.
These 2 vectors represent world space and local space as in relative space near the object.
He also needs another variable to tie to his mesh object, give the mesh a variable name so he can use it as a refrence to transform to local space.
He needs to get world space and covert it to local space, then use the trace system with the relative position so he can covert again to world space and trace

I’m sorry I don’t copy paste code, his code seems to be missing the vector variable that is relative to local space.

I just thought it would be helpful if I told him he is missing the coordinates described as vectors.

How do you want to make a trace if you don’t have a vector system that you have transformed.
Trace what ? you need a relative position of the object to make a trace calculated by vectors from world position.

The trace is done on the base of the position of the object in space, so you need to feed the “trace - omat” some vectors to tell it , “hey look there it is”

Otherwise the trace-omat will say, sorry can’t find anything.

It’s just the sintax without the variable. He is starting at blank ending at blank.

Somethin g of the sort.
FVector SomeNewVariableTo world = Transform Position Of object (Old Variable relative location)

After we get this nice variable we can input with it something like this:

SomeNewVariableToWorld = trace start
and then
SomeNewVariableToWorld = trace end.

But this is just one part, he needs to setup the initial variables 3 vars at minimum as I said and transform coordinates to get local space to feed it to the tracer.

I think when It comes to this OpenGL beginer lessons C++ are great, there it talks about what a vector is, how to include floats into it, how to transform a vector, and then he will find it much more easy to deal with such things.
OpenGL pipeline is a must to study a little bit.

I may be wrong and he has this tied to some blue print, and variables are there, I dunno.
I don’t see any variable in his code except the hit variable.

What kind of gibberish are you saying? is this a bot?

I assume your issue comes from the fact that you’re using an ECollisionChannel value in an array expecting an EObjectTypeQuery, using Emplace only forced the bytes to be copied from one enum to the other but that doesn’t necessarily map the values as the engine would expect.

You should use the following function to convert from one to the other:

UEngineTypes::ConvertToObjectType(ECollisionChannel::ECC_GameTraceChannel1)

Which should turn your code to this instead:

TArray<TEnumAsByte<EObjectTypeQuery>> ObjectTypesArray;
ObjectTypesArray.Add(UEngineTypes::ConvertToObjectType(ECollisionChannel::ECC_GameTraceChannel1));
bool bHasHit = UKismetSystemLibrary::SphereTraceSingleForObjects(GetWorld(), StartLocation, EndLocation, 500.f, ObjectTypesArray, false, IgnoredActors, EDrawDebugTrace::ForDuration, OutHit, true);
3 Likes

he’s already feeding a StartLocation and an EndLocation to the function, I assume it’s defined somewhere above, sorry for mistaking you for a bot but I really doubt they need a primer on vectors if they’re converting code from BP to C++ (or to be explained how Traces work)

are you seriously judging a 4 lines long code snippet as if it was their entire code? The StartLocation and EndLocation are pretty obviously variables that are calculated beforehand, it’s not “a syntax without the variable” as if StartLocation and EndLocation weren’t variables they’d be getting compile errors which is completely off topic.

I assume you did not understand the question, you can check my answer as I’m 80% confident this was their problem since we can assume that if things worked in BP and logic is kept exactly the same this should be the only issue that they have/had

I just completed a similar task where you have to move the skeletal mesh with casting a trace for foot placement.

The start and end variables are part of the built in system connected to some inside function of unreal, to cast a trace , but that trace start and end are based on the other variables that you have to make and supply to the built in mechanism of unreal engine.

I won’t say more, this guy if he wanted help he would talk here, and discuss and ask more questions like get into the discussion.

Well anyway something of the sort.
TheTransformWorldLocationVariable + FVector(0.f, 0.f, 50.f), /represents Trace start/

So even if the variable trace start represents something you have to add your input to the system. The system does not magicly guess where your cube is and cast the ray trace beneath the cube or in front of it to see if there is anything there for a hit.

You have to have a vector variable to pass to the other variables that are trace start and end.
There is no point in pasting code since he should respond and ask for help first.

Not enough interest mister.

Thx very very much. It works.

There is no need to import the kismet library, just invoke what it does. and use SweepMultiByObjectType. It’s pretty nice to dive through these methods and learn how these things work. Sometimes it is worth it or necessary to just import a thing from kismet, I don’t think that is the case here.

     TArray<FHitResult> HitResults;

FVector Start = GetActorLocation();  // Center of the sphere
FVector End = Start;                 // No movement, just a sphere test
float Radius = 500.f;                // Your sphere radius

FCollisionObjectQueryParams ObjectQueryParams;
ObjectQueryParams.AddObjectTypesToQuery(ECC_Pawn); // Example: looking for Pawns, add more as needed
ObjectQueryParams.AddObjectTypesToQuery(ECC_WorldDynamic);

FCollisionShape CollisionShape = FCollisionShape::MakeSphere(Radius);

bool bHit = GetWorld()->SweepMultiByObjectType(
    HitResults,
    Start,
    End,
    FQuat::Identity,
    ObjectQueryParams,
    CollisionShape
);

if (bHit)
{
    for (const FHitResult& Hit : HitResults)
    {
        AActor* HitActor = Hit.GetActor();
        if (HitActor)
        {
            UE_LOG(LogTemp, Warning, TEXT("Hit Actor: %s"), *HitActor->GetName());
        }
    }
}