Jump to content

Global variable


AggrorJorn
 Share

Recommended Posts

I'm wondering how to use global variables with LUA. I have a fuse/generator which you can turn on and of. Every single light in my scene can be turned on or off depending on whether the generator is active (on).

These are the variables that i use in the generator script. I have declared them before I create the object.

fuseActive = 0
lightsHide = 1

I can activate the generator with a use message. The fuseActive variable is used to either turn on or off the generator. When the generator is activated, all the light-switches have to make use of the lightsHide variable.

This is a part from the light-switch script:

if lightsHide == 0 then
if lightOn==1 then
	target:Hide()
	lightOn=0
else
	target:Show()
	lightOn=1
end
end

The lightsHide variable in the light-switch script should use the value from the variable in the generator script. How can I make the lightHide variable in the generator script global, so that I can use it in the light-switch script? Any other suggestions whether scripting like this is efficient, is also welcome.

Link to comment
Share on other sites

SetGlobalNumber( "variablename", value ) should do it. Omitting the Local keyword inside Model scripts makes them only global per model, but not for the whole Lua scope.

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

I was wondering about this too. Why would that be the case? If we have the single lua state, I was under the impression that any variable that didn't have local or wasn't part of a "class" (like class.variable), was global to the lua state.

 

it does... i don't know what lumooja is talking about...

 

i have two entity scripts that prove that a variable can be global between two different models and is actually global to the lua state.

first entity script:

require("scripts/class")

local class=CreateClass(...)

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

function object:Render()
	if variable == 1 then
	object.box = CreateCube(model)
	end
end
end

 

and the second entity script:

require("scripts/class")

local class=CreateClass(...)

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

 

as soon as you place the second model into the scene it will create a cube on the first model

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

Ah ok, I just heard from wh1sp3r today that his "global" variable was only per-model global. I need to sue him for giving me wrong information! :)

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

Spot the error! no seriously, perhaps I'm declaring the value in the wrong location.

fuse:

require("scripts/class")
local class=CreateClass(...)

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

local fuseActive = 0
lightsHide = 1

function object:ReceiveMessage(message,extra)
	if message=="use" then
		local n,target,targetmessage,args,delay
		for n=0,7 do
			target=self.model:GetTarget(n)
			if target~=nil then
				if object.fuseActive == 1 then
					fuseActive = 0
					lightsHide = 1
				else	
					fuseActive = 1
					lightsHide = 0
				end
			end
		end
	end
end	
end

Link to comment
Share on other sites

well you have a local n in the function and a local n in the if loop.

 

Which one are you calling here:

target=self.model:GetTarget(n)

Are you getting target is nil error?

 

because as soon as you exit the for loop, n becomes nil.

  • Upvote 1

AMD Phenom II x6 1100T - 16GB RAM - ATI 5870 HD - OCZ Vertex 2 60GB SSD

76561197984667096.png

Link to comment
Share on other sites

well you have a local n in the function and a local n in the if loop.

 

Which one are you calling here:

target=self.model:GetTarget(n)

Are you getting target is nil error?

 

because as soon as you exit the for loop, n becomes nil.

Well the local variables just overwrite each other and are not giving an error. But I removed them since they are pointless. Thx

 

Since it looks like you want fuseActive to be local to this thingoid try doing this instead:

 

object.fuseActive = 0

 

Then use that to check in the ReceiveMessage()

if object.fuseActive then ...

That certainly works but that's not the problem of the disfunctioning I think. The lightswitch script doesn't seem to read the lightHide value from the fuse.

Link to comment
Share on other sites

Are you sure is not the if object.target ~= nil that is failing?

 

You can put some Print(blah blah blah) statements within your for loop, then check the editor consol after you exit the game mode, and find out whats going on.

 

Its hard to say whats wrong with out the rest of the script that go to this

 

Edit also, change this line

target=self.model:GetTarget(n)

 

to

target=object.model:GetTarget(n)

 

Sorry one more thing.

 

The wiki states that SetTarget

 

entity:SetTarget( target, index ) 

 

I am assuming you have 7 targets set somewhere else?

AMD Phenom II x6 1100T - 16GB RAM - ATI 5870 HD - OCZ Vertex 2 60GB SSD

76561197984667096.png

Link to comment
Share on other sites

The self = object, so that will work. Also, the 'target ~= nil' check is there so he doesn't need all 8 targets...

 

and actually now that this is a single state, the only reason i could see why you would need to set the target is if you are trying to gather info from the target itself. If you are just setting a global variable that the lights respond to, then no reason to even use linking...

 

this is basic generator script thats not giving a method to toggle the FuseActive variable (i will let Aggror do that)

require("scripts/class")
local class=CreateClass(...)

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

 

and this is the basic lights script:

require("scripts/class")
local class=CreateClass(...)

function class:CreateObject(model)
local object=self.super:CreateObject(model)
object.light = CreatePointLight(10,model)
HideEntity(object.light)

function object:Render()
	if FuseActive==1 then
		ShowEntity(object.light)
	else
		HideEntity(object.light)
	end
end
end

 

you can test it by opening the 'generator' script and just changing the value of FuseActive and saving the script... you will see the light go on and off... you may have to position the object.light...

  • 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

I am assuming you have 7 targets set somewhere else?

 

What I am getting at is if target IS nil, then his script will do nothing.....

 

well, I assume he has at least one target linked or yes, his script will not work. But your statement above suggested that he needed 7 other targets or the script would not work at all...

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

Shouldn't you declare fuseActive as a member of the object, since that is how you are accessing it for the targets?:

 

object.fuseActive = 0

 

It's hard to tell what you are doing without seeing the full scripts, if there is another one.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

It is kinda embarrassing :lol: , but after reading your replies I see what you mean. In the first place I didn't need to create those links at all. I totally focused on the wrong problem. I linked the fuse to the lights even before I started trying to make the script, because I thought I would need it. After the script was pretty much done, I must have totally forgotten that those links are not being used by the script. (no messages doink :blink: )

 

I know that using links wasn't good anyway because if I had more than 8 lights, I would have a problem. But then again, it was more testing if it really worked.

 

On the other hand: the fuse has links in the scene, so 'target ~= nill'. This would mean that the script works, independent from whether the script is logical.

 

Cant wait to try this at home...

 

Thanks for your replies. I'll let you know how it goes.

Link to comment
Share on other sites

The self = object, so that will work.

 

 

Now I could be wrong, but there is a situation where this would be different.

 

self = object but not all the time.

 

Say your function is class:something() {}

 

self would then = class not object.

 

if your function object:something() {}

 

then self = object.

 

There could be a situation where this will mess you up, and I have seen places where using self instead of object didn't work, so its always better to use exactly what you want, and not just assume.

 

Now of course this is assuming that my logic is correct, and if its not, then I will accept defeat. ;) lol

AMD Phenom II x6 1100T - 16GB RAM - ATI 5870 HD - OCZ Vertex 2 60GB SSD

76561197984667096.png

Link to comment
Share on other sites

It works just as I want it now. Thanks for the help everyone. (Community +1 (couldn't find the + sign :) ))

 

1 question though: When the fuse is turned of, all lights that were shown, have to be automaticly hidden. I used this code and it works:

function object:Update()
	if lightsHide == 1 then
		local n,target,targetmessage,args,delay
		for n=0,7 do
			target=self.model:GetTarget(n)
			if target~=nil then
				target:Hide()
			end
		end	
	end
end

 

Instead of object:Update() I can also use object:Update(). The result is the same, but I would like to which one is better.

 

I'm also thinking of putting up a tutorial about this. nice lua code sample...

Link to comment
Share on other sites

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...