In this tutorial will be used Tile, Camera:Pick() and Entity:GetDistance
FPSPlayer component of FPS Template will be used as a base to modify
Algorithm:
1. Create a Tile with text prompt
2. In Update function of component check if player look at usable object at close distance
3. if the check is passed then show prompt at center of screen
Result will looks like that:
Let's implement this Algorithm:
1. Add new component variable, for example after:
FPSPlayer.movement = Vec3(0)
New code line:
FPSPlayer.usePromtTile = nil
Now in FPSPlayer:Load() function after:
if not self.camera then
self.camera = CreateCamera(world)
self.camera:Listen()
Add:
local font = LoadFont("Fonts/arial.ttf")
self.usePromtTile = CreateTile(self.camera, font, "Press E", 20, TEXT_CENTER, 1.5)
This overload used (more short one for text currently not available when tutorial is written):
CreateTile(Camera camera, Font font, string text, number fontsize, number alignment, number linespacing)
Tile is something like mini GUI widget which can be used to show text or rectangles without creating Interface.
2 and 3. Inside of FPSPlayer:Update() in "if window then" scope before its end (after 392th line) add:
--to decide later if we want to show or hide prompt tile
local doHideTile = true
--cx and cy are screen center coordinates which were created above
local pickInfo = self.camera:Pick(framebuffer, cx, cy, 0, true)
if pickInfo.success and pickInfo.entity and pickInfo.entity:GetDistance(self.entity) < 2.0 then
--iterate all components of picked entity
for _, component in ipairs(pickInfo.entity.components) do
--find out if component of picked entity have Use function and it's enabled
if component.Use and type(component.Use) == "function" and component:GetEnabled() then
--move tile to center of screen
self.usePromtTile:SetPosition(cx, cy)
doHideTile = false
--stop iterating once we found usable object
break
end
end
end
self.usePromtTile:SetHidden(doHideTile)
Result file: FPSPlayer.lua