Jump to content

show text or image when near object?


dennis
 Share

Recommended Posts

Hello all,

 

 

I created an object and now I want to make it to show a message when near it.

 

to make it work I tried:

 

if EntityDistance(fw.main.camera, self.model) <2 then
 SetBlend(1)
 DrawText("test", 100,100)
 SetBlend(0)
end

 

But it simply doesn't work.

Can someone please tell me how to fix this? (I really need to have this inside the model code)

 

Some help would be apreciated.

Have a good day / night,

-Dennis

Link to comment
Share on other sites

Make sure that the draw Text gets called after rendering the scene

 

pseudo:

 

//main loop
{
Update all objects
Framework Render
Draw All objects
}

 

*edit: since you are using a script you do not need to worry about the render command.

 

I would do it like this:

  1. Give your model a script with a boolean 'inreach'. by default on false
     
  2. In the update function check if it is within reach and set the 'inreach' value for the boolean
     
  3. Then in the draw function you check if inreach is true and draw the text.

Link to comment
Share on other sites

Okay, but the code is object orientated. so I have a model called "electrical box_10"

the code I already made:

 

 

function class:CreateObject(model)
local object=self.super:CreateObject(model)
if EntityDistance(fw.main.camera, self.model) <2 then
 SetBlend(1)
 DrawText("test", 100,100)
 SetBlend(0)
end

 

so why doesn't it work? the models are already drawn right?

the scenee is drawn, i can walk around, and I want too chheck if I'm near the powerbox

Link to comment
Share on other sites

model scripts aren't called at the 2D drawing part you want (3D rendering and 2D rendering are done a different times). If you want to do this inside a model script you need to hook into the Flip function I believe it is, and then do it. The Flip function that you hook to however I believe will be global and not linked to the model script you hooked it in, in any way. I find it pretty lame and I believe the hooking ability was added at a later time as sort of a hack (in my mind). I'm in your boat, sort of, in that a 2D Draw() function should be available for all model scripts and automatically called by the engine.

 

The way I simulated this, is by just making a function called Flip (or whatever you want) inside the model script. Then my main lua game script I created a function call RunFlip() that would cycle through every model script, check if the Flip function exists and if it does call it. Then I call RunFlip() at the correct time in the main loop. Shown below:

 

 

main lua game script

-- objecttable holds all the loaded objects in your scene so we simply loop through them seeing if they have a function called Flip and if so, call it
function RunFlip()
for k,v in pairs(objecttable) do
if v.Flip ~= nil then
v:Flip()
end
end
end

while (KeyHit(KEY_ESCAPE) == 0)

fw:Update()
fw:Render()

RunFlip() -- Calling this which will loop through objecttable (which is every model script in the scene) and if a Flip function is defined it calls it

Flip(0)
end

 

Then in your model script you would do:

 


function class:CreateObject(model)
local object=self.super:CreateObject(model)

function object:Flip()
-- do your 2D drawing here
end
end

Link to comment
Share on other sites

Thanks Rick!

 

model scripts aren't called at the 2D drawing part you want (3D rendering and 2D rendering are done a different times). If you want to do this inside a model script you need to hook into the Flip function I believe it is, and then do it. The Flip function that you hook to however I believe will be global and not linked to the model script you hooked it in, in any way. I find it pretty lame and I believe the hooking ability was added at a later time as sort of a hack (in my mind). I'm in your boat, sort of, in that a 2D Draw() function should be available for all model scripts and automatically called by the engine.

 

The way I simulated this, is by just making a function called Flip (or whatever you want) inside the model script. Then my main lua game script I created a function call RunFlip() that would cycle through every model script, check if the Flip function exists and if it does call it. Then I call RunFlip() at the correct time in the main loop. Shown below:

 

 

main lua game script

-- objecttable holds all the loaded objects in your scene so we simply loop through them seeing if they have a function called Flip and if so, call it
function RunFlip()
for k,v in pairs(objecttable) do
if v.Flip ~= nil then
v:Flip()
end
end
end

while (KeyHit(KEY_ESCAPE) == 0)

fw:Update()
fw:Render()

RunFlip() -- Calling this which will loop through objecttable (which is every model script in the scene) and if a Flip function is defined it calls it

Flip(0)
end

 

Then in your model script you would do:

 


function class:CreateObject(model)
local object=self.super:CreateObject(model)

[code]function object:Flip()
-- do your 2D drawing here
end

end

[/code]

 

that sounds so logically! I think I can make something on that... like:

 

if EntityDistance(fw.main.camera, self.model) <2 then
function object:Flip()
-- do your 2D drawing here
end
else
end

 

for example....

Link to comment
Share on other sites

or just use the inherent function already available for use in object scripts...

require("scripts/class")
local class=CreateClass(...)
function class:CreateObject(model)
 local object=self.super:CreateObject(model)

 function FlipHook()
	 if EntityDistance(fw.main.camera, object.model)<2 then
		 SetBlend(1)
		 DrawText("test", 100, 100)
		 SetBlend(0)
	 end
 end
end

 

also look at CameraUnproject in the wiki and then draw the text for a specific model based on its location in screen space... i dont have a good connection or access to LE at the moment, so thats about all i can suggest...

Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590

LE / 3DWS / BMX / Hexagon

macklebee's channel

Link to comment
Share on other sites

Even better ...

 

 

Maybe not better. This seems flawed in some respects. If I have 2 different model scripts and I put this in, only 1 wins out. So it works but with an *. Then if I delete the instance I added last the other one doesn't seem to come back with the flip. Even if I have 2 of the same instance, then delete the last one, the text goes away.

Link to comment
Share on other sites

The catch with AddHook() is that the function needs to be on it's own. It can't be inside the script function class:CreateObject() (I get an error when trying to do so anyway, which makes sense) which then means you can't refer to that object directly because inside the flip function it knows nothing of the object it happens to be in the same script with (or AddHook() was called from). Instead you have to loop through objecttable to find the object in question to get it's variables/methods/etc (if you wish to reference objects inside it like in this case). So in this case using object.model no longer works without first finding the object in question by looping through objecttable.

 

This is why I eventually came to my solution I posted above as it overcomes the other 2 ways limitations. If I have to loop through the objecttable anyway in the AddHook() way, then I might as well only do it once in the main game loop than possibly multiple times in each Flip hook that I might need to define in multiple scripts. You could only have 1 main drawing method but it's breaking the object oriented theme then which to each their own in their views on that. It then gets the advantage of being able to access that object variables directly from inside the function. The function also is directly part of the object which is nice and clean I think too when looking at it from an OO perspective and having the object data being it's own instance from the other instances of the same object.

 

Just like objects have SetKey() and Update() I really wish Josh would have created Draw2D() as well to handle this directly.

 

 

So Dennis, I'm just trying to show you the evolution of 2D drawing in Lua that I came to and how I solved it. I, like you, wanted to have each object have it's own ability to draw in 2D independently from any other object while still having direct access to that object instance data.

Link to comment
Share on other sites

Thanks Rick!

 

 

 

that sounds so logically! I think I can make something on that... like:

 

if EntityDistance(fw.main.camera, self.model) <2 then
function object:Flip()
-- do your 2D drawing here
end
else
end

 

for example....

 

Be sure to put all your code inside the function. In your post you have the if statement outside the function. That won't work (unless you just copied and pasted incorrectly).

Link to comment
Share on other sites

The catch with AddHook() is that the function needs to be on it's own. It can't be inside the script function class:CreateObject() (I get an error when trying to do so anyway, which makes sense) which then means you can't refer to that object directly because inside the flip function it knows nothing of the object it happens to be in the same script with (or AddHook() was called from). Instead you have to loop through objecttable to find the object in question to get it's variables/methods/etc (if you wish to reference objects inside it like in this case). So in this case using object.model no longer works without first finding the object in question by looping through objecttable.

 

while i agree it would be nice to have an entity 2D drawing function available, I don't understand some of the things you are stating above... i have used the AddHook() repeatedly in the past inside the CreateObject() without any issues... unless you are referring to issue of not being able to call it as an object function? which i agree is annoying but not a showstopper... the only issue i can really remember is when you delete an object that uses the same name AddHook("flip") function as other objects, the last object added to the scene will have its AddHook removed as well (assuming you do use RemoveHook in the object:Free() )

 

are you saying you would have errors or issues with something like this?

 


require("scripts/class")

require("scripts/hooks")

local class=CreateClass(...)

 

function class:CreateObject(model)

local object=self.super:CreateObject(model)

 

function DrawMyName()

if object.model~=nil and object.model:Culled(fw.main.camera)==0 then

local pos = CameraUnproject(fw.main.camera,object.model.position)

DrawText(object.model:GetKey("name"),pos.x,pos.y)

end

end

AddHook("Flip", DrawMyName)

end

Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590

LE / 3DWS / BMX / Hexagon

macklebee's channel

Link to comment
Share on other sites

Nope, you are correct. I think my problem was I probably had AddHook() before the function was declared and for some reason I then moved the function outside CreateObject() and it worked but then you have to the whole objecttable thing, but you're right in what you have there. Thanks for clearing that up.

Link to comment
Share on other sites

well my memory is slipping but i know i had used the hooks in the past without any issues... see the video that MG posted at one time with the cctv camera, cctv screen, and switch with the hand icons... we had made those all lua scripted objects calling 2D drawing functions and it worked fine at the time... doubt if they work now with all of the engine updates though... also, the fliphook() seems to be more of a game script function whereas only one can exist in a scene at a time

Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590

LE / 3DWS / BMX / Hexagon

macklebee's channel

Link to comment
Share on other sites

So mack, you simply told me that the whole system I wrote was not necessarily and I made it for nothing?

yes essentially

but thanks anyway works better this way

im not a professional programmer by any means, but cycling through objecttables every flip seems to be unnecessary waste of cycle time...

  • Upvote 1

Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590

LE / 3DWS / BMX / Hexagon

macklebee's channel

Link to comment
Share on other sites

  • 3 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...