UE4: screen offset indication

    技术2022-07-10  147

    如需转载本文,请声明作者及出处。

    // 屏幕外的3d位置,在屏幕上的指向 void screen_offset_indicate(WorldLocalX, WorldLocalY, WorldLocalZ) { APlayerController* Player = ...; //指向图标的角度 float RotationAngleDegrees = 0.f; //指向图标在屏幕上的位置 FVector2D *ScreenPosition = new FVector2D(); const FVector2D ViewportSize = FVector2D(GEngine->GameViewport->Viewport->GetSizeXY()) / UWidgetLayoutLibrary::GetViewportScale(Player); const FVector2D ViewportCenter = FVector2D(ViewportSize.X / 2, ViewportSize.Y / 2); ACharacter *PlayerCharacter = static_cast<ACharacter*>(Player->GetPawn()); if (!PlayerCharacter) { return; } FVector Worldlocal = FVector(WorldLocalX, WorldLocalY, WorldLocalZ); FVector Forward = PlayerCharacter->GetActorForwardVector(); FVector Offset = (Worldlocal - PlayerCharacter->GetActorLocation()).GetSafeNormal(); float EdgePercent = 0.8f; // 可调可配,贴边的百分比 float DotProduct = FVector::DotProduct(Forward, Offset); bool IsBehindCamera = (DotProduct < 0.0); if (IsBehindCamera) { //当要指向的点跟到相机后时 //取巧的做法,将相机后的位置取反,得到屏幕位置后,再用屏幕宽度来减 FVector DiffVector = Worldlocal - PlayerCharacter->GetActorLocation(); FVector Inverted = DiffVector * -1.f; FVector NewLocal = PlayerCharacter->GetActorLocation() + Inverted; Player->ProjectWorldLocationToScreen(NewLocal, *ScreenPosition); ScreenPosition->Y = ViewportSize.Y - ScreenPosition->Y; ScreenPosition->X = ViewportSize.X - ScreenPosition->X; } Player->ProjectWorldLocationToScreen(Worldlocal, *ScreenPosition); if (ScreenPosition->X >= 0.f && ScreenPosition->X <= ViewportSize.X && ScreenPosition->Y >= 0.f && ScreenPosition->Y <= ViewportSize.Y) { //ScreenPosition在屏幕内了 return; } *ScreenPosition -= ViewportCenter; float AngleRadians = FMath::Atan2(ScreenPosition->Y, ScreenPosition->X); AngleRadians -= FMath::DegreesToRadians(90.0f); RotationAngleDegrees = FMath::RadiansToDegrees(AngleRadians) + 180.0f; float Cos = cosf(AngleRadians); float Sin = -sinf(AngleRadians); ScreenPosition = new FVector2D(ViewportCenter.X + (Sin * 150.0f), ViewportCenter.Y + (Cos * 150.0f)); float m = Cos / Sin; FVector2D ScreenBounds = ViewportCenter * EdgePercent; if (Cos > 0.0) { ScreenPosition = new FVector2D(ScreenBounds.Y / m, ScreenBounds.Y); } else { ScreenPosition = new FVector2D(-ScreenBounds.Y / m, -ScreenBounds.Y); } if (ScreenPosition->X > ScreenBounds.X) { ScreenPosition = new FVector2D(ScreenBounds.X, ScreenBounds.X*m); } else if (ScreenPosition->X < -ScreenBounds.X) { ScreenPosition = new FVector2D(-ScreenBounds.X, -ScreenBounds.X*m); } *ScreenPosition += ViewportCenter; }

     

    Processed: 0.014, SQL: 9