Help with my raycast function

hey all Im new to the c++ side of UDK coming over from c# in unity 3d and raw c++. i was wondering why this code is causing the engine to CTD when its run.

FHitResult& ATraces::Trace(FHitResult& f, UWorld& actor,FVector start, FVector end)
{
	FCollisionQueryParams CombatCollisionQuery(FName(TEXT("CombatTrace")), true, NULL);
	CombatCollisionQuery.bTraceComplex = true;
	CombatCollisionQuery.bTraceAsyncScene = false;
	CombatCollisionQuery.bReturnPhysicalMaterial = false;
	actor.LineTraceSingleByChannel (f, start, end, ECC_WorldStatic, CombatCollisionQuery);
	
	return f;
}

the function is called in a mouse click input function, here is the call

void AMyCharacter::Cast()
{
    FHitResult hitRes(ForceInit);
    
    	FHitResult& f = hitRes;
    	UWorld& MyWorld = *this->GetWorld();
    
    	
    	t->GetDefaultObject<ATraces>()->Trace(f, MyWorld, GetActorLocation(), GetActorLocation() + FVector(0.0f, 0.0f, -100.0f));

i know its crude and probably messy but i would appreciate any help at all uncovering why this causes a CTD

Can you post the crash error message or even the call stack? Also I would avoid using Cast as a function name, because C++ uses Cast for casting between types.

C# is working with objects, there is no direct memory control. In C++ you can work with memory as you want, but this feature gives you many problems, such as 0xc0000005 (read/write access violation). In C# we can give no (blotch) about getting references or instances, e.g.: in Unity3d we can find an object using

GameObject choppa = GameObject.Find("MahChoppa") as GameObject;

There we will get only a reference of Mah Choppa, not an instance. If i left types the same, but make it as it must look like in C++ it will be like this:

GameObject * choppa = Cast<GameObject>(GameObject::Find("MahChoppa"));

There variable choppa is ADDRESS, where founded object contains and we sure, that after that address we have type GameObject. That’s what star means. Double colon after GameObject means that we trying to access something static (function, method or variable). As i know, in Unity GameObject.Find still returns an Object, so let’s imagine, that C++ version returning “void*” - just an address, no type. So we use Cast to make sure, that what we found is legal to use as this type (we can directly convert it into GameObject*, but who knows, maybe it isn’t that type we want). If Cast fails, it returns nullptr or just zero, there we can understand, that it isn’t what we wanted.
Now why I wrote this: using all info you given, there can be a few things that might be the problem:
->That trick with UWorld is insanely cool, i should say, but it will cause the crash. You mustn’t use instance of UWorld, world is huge container, it isn’t good idea. If you need reference to world you need to write this:
UWorld * world = GetWorld();
And you don’t need “this” also, you aready in “this” namespace.
->Trace function don’t need FHitResult and “actor” in arguments. You can locally create FHitResult and then return it. Like this:

     FHitResult f;
     ...
     GetWorld()->LineTraceSingleByChannel (f, start, end, ECC_WorldStatic, CombatCollisionQuery);
     return f;

->Are you sure you need ATrace class in so hard way? I really don’t know how fast GetDefaultObject is, but probably better save pointer once, instead of getting it many times. And what is “t” actually… This combination looks strange, but i hope it will work.

hey thank you for the speedy reply. it was really clear and had alot of information that could help.

->also i was unaware that the GetWorld() line could even cause anything I’ll check that out

->the only reason i passed FHitResult by reference was because in my basic understanding of optimization i thought it was faster just to keep only one object and instead just edit the original object.

->the only reason i made this into another class was just so i could access it while using other actors like future AI. T is a object of class ATrace defined like TSubclassOf+ATrace+ t; (+ is angled brackets )

again I’m new so if there is a better way to do this pleeease let me know i wont be offended :stuck_out_tongue:

is this what you wanted or something else?

`
Unknown exception - code 00000001 (first/second chance not available)

"Fatal error: [File:D:\BuildFarm\buildmachine_++depot+UE4-Releases+4.8\Engine\Source\Runtime\CoreUObject\Private\UObject\UObjectGlobals.cpp] [Line: 2028]
None_47 is not being constructed with either NewObject, NewNamedObject or ConstructObject.
"`

Maybe it could be like that:

FHitResult ATraces::Trace(FVector start, FVector end)
 {
     FHitResult hitResult;
     FCollisionQueryParams CombatCollisionQuery(FName(TEXT("CombatTrace")), true, NULL); 
// You can also use "nullptr" instead of "NULL", they both equals zero by the way
     CombatCollisionQuery.bTraceComplex = true;
     CombatCollisionQuery.bTraceAsyncScene = false; // this
     CombatCollisionQuery.bReturnPhysicalMaterial = false; //and this by default are false, but it is ok forcing them to false, because if you will read this code again, you will be sure, that this trace isn't async etc.
     actor.LineTraceSingleByChannel (hitResult, start, end, ECC_WorldStatic, CombatCollisionQuery);
     
     return hitResult;
 }

void AMyCharacter::Cast()
 {
         //This code may be much cheaper
         FHitResult hitResult = t->GetDefaultObject<ATraces>()->Trace(GetActorLocation(), GetActorLocation() + FVector(0.0f, 0.0f, -100.0f));
         //And something down there...

And if you want have single Actor in scene, which will only do tracing, so you can make one magic trick - static variable.
In .h of an ATrace somewhere in public field write something like this:
static ATraces * globalPointer;
In .cpp you need to declare it, set it’s default value:
ATraces * ATraces::globalPointer = nullptr;
Also in .cpp, but in initializator method:
globalPointer = this;
Very fast and pretty safe, only if your actor will start with the scene, otherwise sometimes this variable equals nullptr, until first ATraces created in scene. If your ATraces already in level, then you don’t need to worry about this :slight_smile:
And now from every place you can use ATraces::globalPointer->DoSomething(), if you have #include “Traces.h” of course.

gahh its still crashing i think ill just resort to using one class. oh well thank you for all your help!

edit: okay this turns out that it works if im in debug mode. wtf O.o

Ow, GetDefaultObject isn’t that maybe you wanted.
Cast(t)->Trace(…)
Almost every class in UE can be casted, so don’t be scared of using this.
Launcher usually runs developement build of editor, so maybe it is still crashing, because you didn’t recompiled it as developement?