x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

UCanvas::Deproject() not returning desired results

I am trying to spawn a test cube at the mouse position. Based on the thread here,

https://rocket.unrealengine.com/questions/2162/mouse-position-picking-c.html

I decided that the best course of action (at least, until there's a better way of doing this, as James.Golding mentioned that there was a better implementation in the works) was to call UCanvas::Deproject() inside my HUD's draw call (which is the only time the canvas is valid), and save off the results of this call (the world space origin and direction) to be used later in positioning the cube I want to spawn. I am essentially doing it exactly the way Mike.Purvis does in that thread (GEngine->GameViewport->GetMousePosition() to get the mouse pos and then Canvas->Deproject() with that mouse pos).

I've found that the cube seems to consistently spawn at the camera position, even though I correctly pass in the cached world space origin into the call to UWorld::SpawnActor().

I then added some diagnostic code in my HUD's DrawHUD() immediately after the Deproject() call (see screenshot attached) to tell me what the world space origin actually is. This text follows the mouse cursor around correctly (so I know it's getting the right mouse position), and the X and Y seem to change somewhat as I move the cursor around, but the Z is not changing as the cursor moves over the cubes that are already in the level.

alt text

Any idea why this would be? It's almost as if the projection is stopping right at the start of the camera view frustum, and not even getting into the scene at all.

Alternatively, if there's a good way to do a Deproject() outside of a DrawHUD() call, I'd prefer to use that instead -- but my understanding has been that that's not currently possible.

Product Version: Not Selected
Tags:
deproject.jpg (96.6 kB)
more ▼

asked Mar 11 '14 at 02:19 AM in C++ Programming

avatar image

ue4-archive ♦♦ STAFF
50k 3667 1996 9121

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

2 answers: sort voted first

I am using this function from the PlayerController, skipping all that stuff like from the mouse click demo.

 //= trace to check if mouse pointer if over a terrain
 FHitResult Hit;
 GetHitResultUnderCursor(ECC_Visibility,Hit);

 //Did it hit something?
 if (Hit.bBlockingHit) 
 {
   // Hit.ImpactPoint is your world hit location

 }




more ▼

answered Mar 11 '14 at 02:19 AM

avatar image

ue4-archive ♦♦ STAFF
50k 3667 1996 9121

avatar image ue4-archive ♦♦ STAFF Mar 11 '14 at 02:19 AM

Thanks! That's actually what I really needed -- I did not need to be using Deproject() at all.

Derp :P

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

Hi there!

Are you passing in a value of world origin?

That is an out parameter, you are supposed to pass in a FVector to be filled with the world origin data by deproject, which you can then use for doing traces to obtain the z value

The only in parameters for deproject are the 2D coordinates, all others are out parameters.

When you are deprojecting it will be near the camera, because you are going from the 2D plane of the canvas to 3d space, so it starts close to current camera view.

You cannot expect deproject to account for a Z value when it is being given 2D coordinates, what z value would you like it to decide upon? You must determine the Z value yourself using a trace.

After you deproject are you doing a trace from the deprojected point down into the world? See my code below

if you want to trace exact hit location you can use

 //Did Not Hit Anything?
     if(!TraceHit.bBlockingHit) return;
  
     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     //        Get Hit Loc
     FVector HitLoc = TraceHit.ImpactPoint();


If you use all of my code below you will rotate the SMA's in your level by clicking on them with this function :)


I use deproject in my game's custom HUD class to click on objects in the world all the time!

I posted my entire code for making an ingame mouse cursor a while ago

here's the whole tutorial, including a video showing it working http://forums.epicgames.com/threads/972861-Tutorial-Compile-C-for-UE4-Code-Samples-For-You-gt-gt-New-Get-Set-AnimBluePrint-Vars?p=31656285&viewfull=1#post31656285

here's the function most related to your question

 //if player controller mouse button clicked
 //then do trace
 void AYourHUD::CursorGetClickedActor()
 {
     
     APlayerController* ThePC = GetOwningPlayerController();
     
     //could not get PC ?
     if(!ThePC) return;
     
     //Was LeftMouseButton Just Clicked?
     if(!ThePC->WasInputKeyJustPressed(EKeys::LeftMouseButton)) return;
     
     //~~~~~~~~~~
     
     //no canvas for some reason?
     if(!Canvas) return;
     
     //~~~~~~~~~~~~~~~~~~
     
     /** 
      * Transforms 2D screen coordinates into a 3D world-space origin and direction.
      * @param ScreenPos - screen coordinates in pixels
      * @param WorldOrigin (out) - world-space origin vector
      * @param WorldDirection (out) - world-space direction vector
      */
     //void Deproject(FVector2D ScreenPos, /*out*/ FVector& WorldOrigin, /*out*/ FVector& WorldDirection);
     
     
     FVector Origin;
     FVector WorldDir;
     Canvas->Deproject(MouseLocation,Origin,WorldDir);
     
     
     //Trace
     
     FCollisionQueryParams TraceParams(FName(TEXT("HUDClick")), this);
     //TraceParams.bTraceComplex = true;
     //TraceParams.bTraceAsyncScene = true;
     TraceParams.bReturnPhysicalMaterial = false;
 
     //Re-initialize hit info
     FHitResult TraceHit = FHitResult(ForceInit);
     
     GetWorld()->LineTraceSingle(
         TraceHit,        //result
         Origin,    //start
         Origin + 70000 * WorldDir , //end
         ECC_PawnMovement, //collision channel
         TraceParams
     );
         
     
     //Did Not Hit Anything?
     if(!TraceHit.bBlockingHit) return;
     
     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     //            Get Hit Actor
     AActor* HitActor = TraceHit.GetActor();
     
     //Could not get actor?
     if (!HitActor) return;
     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     
     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     //        Check Hit a Static Mesh Actor
     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     if(HitActor->IsA(AStaticMeshActor::StaticClass()))
     {
         //attempt cast to SMA
         AStaticMeshActor* HitWall = Cast(HitActor);
         
         //could not cast to SMA some reason?
         if (!HitWall) return;
         
         //Static mesh actor has component?
         if(!HitWall->StaticMeshComponent) return;
         
         //Just a fun little test, repeatedly rotates clicked static mesh
         FRotator TheRot = HitWall->GetActorRotation();
         TheRot.Yaw += 3;    //rotators are in degrees now, yaaay!
         TheRot.Pitch += 3;
         HitWall->SetActorRotation(TheRot);
     }
     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 }





more ▼

answered Mar 11 '14 at 02:19 AM

avatar image

ue4-archive ♦♦ STAFF
50k 3667 1996 9121

avatar image ue4-archive ♦♦ STAFF Mar 11 '14 at 02:19 AM

Thanks so much, Nathan! I will try that first thing tomorrow. I'm sure that will do the trick, so I am going to mark that as answered for now. Much obliged!

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question