iPollo Posted March 7, 2020 Share Posted March 7, 2020 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
_Ace Posted March 7, 2020 Share Posted March 7, 2020 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
iPollo Posted March 7, 2020 Author Share Posted March 7, 2020 (edited) 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 March 7, 2020 by iPollo Link to comment
_Ace Posted March 7, 2020 Share Posted March 7, 2020 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 1 Link to comment
Scripting Moderators ds1-e Posted March 7, 2020 Scripting Moderators Share Posted March 7, 2020 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
iPollo Posted March 7, 2020 Author Share Posted March 7, 2020 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
_Ace Posted March 7, 2020 Share Posted March 7, 2020 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
iPollo Posted March 7, 2020 Author Share Posted March 7, 2020 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
Skuleris Posted March 7, 2020 Share Posted March 7, 2020 (edited) ----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 March 7, 2020 by Skuleris Link to comment
Zorgman Posted March 8, 2020 Share Posted March 8, 2020 Create only one colshape clientside, attach it to the player and check objects inside it every 100-200 ms, filter to see if you have items among them and update the render list when necessary. Link to comment
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now