Jump to content

[HELP] Floating Arrow Marker


Recommended Posts

In a simple way :

local x,y,z = 2222.22222, 222.22222, 137 -- The marker positions, idk where :D
local floating = true;
local marker = Marker(x,y,z, "arrow", 5, 0, 0, 0, 0)

function render()
	if ( floating == true ) then z = z + 0.5 else z = z - 0.5 end; -- Here is the rate speed of floating which is 0.5, you could also make the marker going up faster than going down, vice versa.
		if  ( z >= 149 ) then -- I made the marker stop going up at z = 149, then going down.
			floating = false;
		elseif ( z <= 138 ) then -- Same here, stop from going down at z = 138, then going up.
			floating = true;
	end
		marker:setPosition ( x,y,z ) -- setting the new positions to our marker which is z only.
end
addEventHandler('onClientRender',root, render)

Also don't forget to include OPP tag inside your Meta.xml file :

<oop>true</oop>

Best wishes!.

Edited by فاّرس
a typo.
  • Thanks 1
Link to comment
  • Discord Moderators

I made the below function as you might find it useful to animate multiple floating arrows, as alternative to the static approach above.

Use createAnimatedArrow(...) instead of createMarker(...) for your arrow.

It uses the stream in/out events so we don't waste CPU on markers that are far away. You could further optimise it to bind/unbind the render event at the first and last stream in / out, saving 1 pairs call.

local markers = {}

local animationMethod = "InOutQuad" -- What easing function to use, see https://wiki.multitheftauto.com/wiki/Easing
local animationTime = 1000 -- The time for the animation to go from bottom to top
local animationAmplitude = 0.3 -- How far the marker will move

local function onAnimationFrame(dt)
	for marker,anim in pairs(markers) do
		-- Check if marker is still valid or destroyed
		if isElement(marker) then
			-- Find animation progress from time since last frame
			local delta = dt / animationTime
			anim.t = anim.t + delta * anim.direction
			
			-- Reverse direction if we are above 1 or below 0
			if anim.t < 0 then
				anim.direction = anim.direction * -1
				anim.t = 0
			elseif anim.t > 1 then
				anim.direction = anim.direction * -1
				anim.t = 1
			end
			
			-- Find the easing value (usually a 0-1 value) from our animation progress (0-1)
			local anim_time = getEasingValue(anim.t, animationMethod)
			-- Find the z value we want to offset with
			local z_anim = animationAmplitude * anim_time
			setElementPosition(marker, anim.x, anim.y, anim.z + z_anim)
		else
			-- Dereference it
			markers[marker] = nil
		end
	end
end
addEventHandler("onClientPreRender", root, onAnimationFrame)

local function onArrowMarkerStreamIn()
	if markers[source] then return end

	-- Store the position
	-- 't' to keep track of the animation progress
	-- 'direction' to keep track of whether we are moving up or down
	local x, y, z = getElementPosition(source)
	markers[source] = {t = 0, direction = 1, x = x, y = y, z = z}
end

local function onArrowMarkerStreamOut()
	if not markers[source] then return end
	
	-- If the marker element is still valid, set it to its original position
	if isElement(source) then
		setElementPosition(source, markers[source].x, markers[source].y, markers[source].z)
	end
	
	-- Dereference marker
	markers[source] = nil
end

function createAnimatedArrow(x, y, z, markerType, ...)
	if markerType ~= "arrow" then return false end
	
	local marker = createMarker(x, y, z, markerType, ...)
	if not marker then return false end
	
	-- Use the stream in / stream out events to only animate markers that are nearby
	addEventHandler("onClientElementStreamIn", marker, onArrowMarkerStreamIn)
	addEventHandler("onClientElementStreamOut", marker, onArrowMarkerStreamOut)
	
	return marker
end

If your markers are serverside, or you want to change its position after creating it, you'll have to change a few things, let me know if you need help. 

  • Thanks 2
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...