Head View Design
1 Head View Coordinate Calculation
Generally, we have mainly two ways to implement head view logic.
-
Use a WidgetComponent to render the head view widget to a render target and display it in the 3D scene.
-
Convert the 3D location to a 2D screen position and create a 2D widget to display it from the screen.
As the first way has the higher cost, we use the second way in our project. The idea of head view computation is given below.
We can use the build-in function ProjectWorldtoScreen to convert world location to 2D screen position. Then, the most important thing here is to detect the screen position inside or outside the viewport.
-
Inside viewport: Use the screen position to set the head view widget position in the screen.
-
Outside viewport: Hide the head view widget or set its position at the viewport edge.
In order to detect this two cases, we define the following parameters.
-
(SX, SY): The size of viewport.
-
(X1, Y1), (X2, Y2): Edge offset of viewport. Use this offet to limit the widget inside the original viewport.
-
(TX, TY): The size of viewport rect with edge offset.
-
C: The center coordinate of viewport rect with the edge offset.
-
A: The origin coordinate of viewport rect with the edge offset.
-
B: The end coordinate of viewport rect with the edge offset.
-
P: The 2D coordinate converted from ProjectWorldtoScreen.
-
D: The edge coordinate for P.
If P is inside the viewport, we directly use P for the widget position. If P is outside the viewport, we need to use D for the widget position.
We have the following relation of above parameters.
-
A = (X1, Y1)
-
B = (SX-X2, SY-Y2)
-
C = (A+B)/2
-
(TX, TY) = (SX-X1-X2, SY-Y1-Y2)
-
(E, F) = P - C
-
M = TY/TX
-
N = F/E
Then, we have:
-
If P >= A and P <= B, then P is inside the viewport rect.
-
If P < A or P > B, then P is outside the viewport rect.
-
If ABS(N) >= M, then P is outside the up or down edge of viewport rect.
-
D.X = ((E/F) * TY/2) + C.X
-
D.Y = (F/ABS(F) * TY/2) + C.Y
-
-
If ABS(N) < M, the P is outside the left or right edge of viewport rect.
-
D.X = (E/ABS(E) * TX/2) + C.X
-
D.Y = ((F/E) * TX/2) + C.Y
-
-
Use the above logic, we can determine the head view widget is inside or outside the screen. You can dide the head view widget or set its position at the viewport edge according to your game types.
As the head view widget should be followed the actor, the position is needed to be calcaulated every frame. Notice that you should do this logic from HUD(BP_HUD_USG) tick to avoid the slight jitter of head view widget.
2 Program Design
The minimap module in our project mainly contains following parts:
-
The component to make its owner actor to have this head view widget. The location calculation is done in this component. The tick logic is called by the HUD Class.
- /Game/USGT/Framework/UI/ActorHeadView/BP_ActorHeadViewProxy_USG
-
This is the basic head view widget and you can derive this blueprint to create item widgets to display from screen.
- /Game/USGT/Framework/UI/ActorHeadView/WB_ActorHeadView_USG
2.1 BP_ActorHeadViewProxy_USG
The component to make its owner actor to have this head view widget. The location calculation is done in this component. The tick logic is called by the HUD Class. If you do the calculation logic from the component tick, you will find the head widget jitter in the screen.
The calculation to convert 3D location to 2d screen position is given below. This function is a little bit complicated and we can’t display all logic from the picture.
Add the component to your actor to display the screen head view widget.
-
WidgetClass: The widget to display on the screen.
-
IsMovableActor: If true, the head widget will following the actor and it will have more computation cost.
-
ActorLocOffset: Offset for calculating the head widget location.
-
HeadSocketName: If this parameter is not none, we will try to get the socket location to display the head widget.
-
DisplayName: Display name to pass to the widget to show in the screen.
-
MaxDisplayDistance: If the distance between the local controlled pawn and target actor is larger than this parameter, the head widget will be hidden.
-
bHiddenIfOutScreen: If true, the head widget will be hidden when it is outside the viewport.
-
ScreenEdgeStart: The edge offet of viewport from top left corner.
-
ScreenEdgeEnd: The edge offset of viewport from right bottom corner.
2.2 WB_ActorHeadView_USG
This is the basic head view widget and you can derive this blueprint to create item widgets to display from screen.
Create a child widget blueprint of WB_ActorHeadView_USG and implement following interfaces.
-
OnInOrOutScreen: Called when the widget is in or out the screen. If bHiddenIfOutScreen is false, then the widget will be at the edge of viewport and you can change the widget style as you like. See the example from following blueprints.
-
/Game/USGT/Game/CoreModules/Items/Cup/BP_PickupCup
-
/Game/USGT/Game/CoreModules/UI/HeadView/WB_BottleHeadView
-
- OnInitOwnerActor: Called when the widget item was created by BP_ActorHeadViewProxy_USG.
For example, we implemented the OnInitOwnerActor interface for the player head widget and modified the display when the player profile or health value changed.