Jump to content

[Question] onClientRender


iPollo

Recommended Posts

Hello everyone, I would like to ask the veterans a question.

Let's suppose that I am making an item system, where when the player comes close to an item, the "F" key (in the form of an image) and the name of the item appear above it in a 3D way, this key is responsible for collecting items of the map.

As dxDraw functions appear one time per frame, they must be included in the onClientRender/onClientPreRender to show all the time.

Thinking about it, I thought of creating a loop through all the items that are on the map to be collected, and if the player is within the range of 1 meter for example of this item, he must display the image and name of the item, as mentioned above.

The question arises now, creating a lopping within the onClientRender/onClientPreRender to do this verification would not generate a poor performance at GM?, as if it were a poorly optimized way, it would perform a looping and verification MANY TIMES, it would cause any lag or delay? Or I shouldn't even worry about it?

I'm asking because I know languages and playing styles where it can't be done NEVER, it would cause tremendous underperformance at GM.

EX:

addEventHandler("onClientPreRender", root, function()
    for i = 1, table.size(spawnedItem_ID), 1 do
        local x, y, z = getElementPosition(localPlayer)
        if(getDistanceBetweenPoints3D(x, y, z, spawnedItem_X[i], spawnedItem_Y[i], spawnedItem_Z[i]) <= 5) then
            triggerEvent("onPlayerEnterItemArea", root, spawnedItem_ELEMENTO[i])
            -- Draw the image and the text
        end
    end
end) 

 

Link to comment

depends if those objects/items are serversided o clientsided, if the system is 100% client it will affect fps only = depends on the clients pc, if you need to trigger server events or request information from the server then you need to do it efficiently, maybe create a colshape within the object, then a loop isn't necessary, the event (onColShapeHit / OnClientColShapeHit) will do the work for you, anyway there are many ways to do with without lagging the player or the server :)

Link to comment
34 minutes ago, _Ace said:

depends if those objects/items are serversided o clientsided, if the system is 100% client it will affect fps only = depends on the clients pc, if you need to trigger server events or request information from the server then you need to do it efficiently, maybe create a colshape within the object, then a loop isn't necessary, the event (onColShapeHit / OnClientColShapeHit) will do the work for you, anyway there are many ways to do with without lagging the player or the server :)

Yes, what I needed was as if it were an area, which then I would just check when the player's event entered a certain area was triggered, the problem with using onColShapeHit, is that it creates a physical collision area, and I I do not want it, cause the player would hit a "invisible shape" i do not know if colShape works like that way

 

Edited by iPollo
Link to comment

colshapes works like a invisible marker, example code if you wanna test:
 

local cj=createColSphere(2495.09448, -1679.98962, 13.33878, 5)

function coltest(element)
    if source==cj and element==localPlayer then
        outputChatBox("cj house")
    end
end
addEventHandler("onClientColShapeHit", cj, coltest)

it creates a colshape in front of cjs house (clientside).

anyway you could do it without markers or shapes, like you said, but I think the loop that reads the table should be in a slower timed function like a 300-500ms setTimer, onClientRender will check tables/positions much more times per second = slower, you can use the onClientRender to show the text, and a slower timer to check the item table/player position

  • Thanks 1
Link to comment
  • Scripting Moderators
17 hours ago, iPollo said:

Hello everyone, I would like to ask the veterans a question.

Let's suppose that I am making an item system, where when the player comes close to an item, the "F" key (in the form of an image) and the name of the item appear above it in a 3D way, this key is responsible for collecting items of the map.

As dxDraw functions appear one time per frame, they must be included in the onClientRender/onClientPreRender to show all the time.

Thinking about it, I thought of creating a loop through all the items that are on the map to be collected, and if the player is within the range of 1 meter for example of this item, he must display the image and name of the item, as mentioned above.

The question arises now, creating a lopping within the onClientRender/onClientPreRender to do this verification would not generate a poor performance at GM?, as if it were a poorly optimized way, it would perform a looping and verification MANY TIMES, it would cause any lag or delay? Or I shouldn't even worry about it?

I'm asking because I know languages and playing styles where it can't be done NEVER, it would cause tremendous underperformance at GM.

EX:


addEventHandler("onClientPreRender", root, function()
    for i = 1, table.size(spawnedItem_ID), 1 do
        local x, y, z = getElementPosition(localPlayer)
        if(getDistanceBetweenPoints3D(x, y, z, spawnedItem_X[i], spawnedItem_Y[i], spawnedItem_Z[i]) <= 5) then
            triggerEvent("onPlayerEnterItemArea", root, spawnedItem_ELEMENTO[i])
            -- Draw the image and the text
        end
    end
end) 

 

If you gonna use variables inside render scope, it is better to reuse them (declare it in main scope), so they are not recreating every frame.

local x, y, z = 0, 0, 0

addEventHandler("onClientPreRender", root, function()
    for i = 1, table.size(spawnedItem_ID), 1 do
        x, y, z = getElementPosition(localPlayer)
        if(getDistanceBetweenPoints3D(x, y, z, spawnedItem_X[i], spawnedItem_Y[i], spawnedItem_Z[i]) <= 5) then
            triggerEvent("onPlayerEnterItemArea", root, spawnedItem_ELEMENTO[i])
            -- Draw the image and the text
        end
    end
end) 

However colshape solution it's better. (if you not gonna reach thousands of them for client/server)

Link to comment
17 hours ago, _Ace said:

colshapes works like a invisible marker, example code if you wanna test:
 


local cj=createColSphere(2495.09448, -1679.98962, 13.33878, 5)

function coltest(element)
    if source==cj and element==localPlayer then
        outputChatBox("cj house")
    end
end
addEventHandler("onClientColShapeHit", cj, coltest)

it creates a colshape in front of cjs house (clientside).

anyway you could do it without markers or shapes, like you said, but I think the loop that reads the table should be in a slower timed function like a 300-500ms setTimer, onClientRender will check tables/positions much more times per second = slower, you can use the onClientRender to show the text, and a slower timer to check the item table/player position

I understand, this way is much better, but let's assume that in my system, items are created automatically, so colShape will also be created automatically along with the items.
In the example above, you specified which area the event will fire.
As in my items will be created automatically on ServerSide, I can't go putting area by area, is there any way when the event is called on clientSide I receive some variable that contains the colShape id that was hitted?

Link to comment

you can create the colshape in the serverside and trigger the event using onColShapeHit, or you can add the colshapes clientside right after you create the items serverside (if those itens are objetcs) you can get server objects information in clientside using getElementsByType("object")

example:

function tobj()
    for i,o in ipairs(getElementsByType("object")) do
        local x,y,z=getElementPosition(o)
        outputChatBox("model: "..getElementModel(o).." position: "..x.." "..y.." "..z)
    end
end
addCommandHandler("testeobj", tobj)

this will get the model and position of all objetcs (if there are any), if your itens are not objects then you can still create the colshapes serverside or clientside using the coords in your item table, use triggerClientEvent to send the coords if you want to create the colshape in the client, btw you can still use the area near system without the colsphapes, just a matter of optimizing like majqq said

 

Link to comment
12 minutes ago, _Ace said:

you can create the colshape in the serverside and trigger the event using onColShapeHit, or you can add the colshapes clientside right after you create the items serverside (if those itens are objetcs) you can get server objects information in clientside using getElementsByType("object")

example:


function tobj()
    for i,o in ipairs(getElementsByType("object")) do
        local x,y,z=getElementPosition(o)
        outputChatBox("model: "..getElementModel(o).." position: "..x.." "..y.." "..z)
    end
end
addCommandHandler("testeobj", tobj)

this will get the model and position of all objetcs (if there are any), if your itens are not objects then you can still create the colshapes serverside or clientside using the coords in your item table, use triggerClientEvent to send the coords if you want to create the colshape in the client, btw you can still use the area near system without the colsphapes, just a matter of optimizing like majqq said

 

I'm not sure  if I understood, the point I want to get to, its find out which colShape is being hit by the player, see some examples:

here is the function that will be called automatically, see that it creates the item, and a sphere around it: (serverSide)

function createItemInMap(item, name, x, y, z)
    createObject(item, x, y, z)
    createColSphere(x, y, z, 1.5)
end

What I would like to know is how I do it, so when this event is called (onClientColShapeHit), on the clientSide, I automatically receive some "ID" from colShape, so I could know which item it is near, thus avoiding not necessary loopings

addEventHandler("onClientColShapeHit", root, function(shapeID)
	--Then i check the item which belongs to this shapeID
end)

 

Link to comment
----client side
addEventHandler("onClientColShapeHit", resourceRoot, function()
    local id = getElementData(source,"item_ID")
	--
end)
--server side
function createItemInMap(item, name, x, y, z)
    createObject(item, x, y, z)
    local colSphere = createColSphere(x, y, z, 1.5)
    local item_ID = 1
    setElementData(colSphere, "item_ID", item_ID, true)
end

When creating colshape, set its elementData.

Use resourceRoot to trigger event only with colShapes created within the same resource.

Edited by Skuleris
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...