Reflect Instance Properties

I’m trying to create a palette system in my game so I can have bodies of terrain water that are different colors as my player moves through zones.

I want to cache the default Terrain settings and then apply a diff to them like so:

game.ReplicatedStorage.Sig.ChangePlayerTerrainSettings.OnClientEvent:Connect(function(settings)
	
	-- First apply defaults
	game.Workspace.Terrain.WaterColor = Color3.fromRGB(23,166,182)
	game.Workspace.Terrain.WaterReflectance = .5
	game.Workspace.Terrain.WaterTransparency = .9
	game.Workspace.Terrain.WaterWaveSize = .15
	game.Workspace.Terrain.WaterWaveSpeed = 10
	-- todo material colors?
	
	
	-- Then modify
	if (settings["WaterColor"] ~= nil) then
		game.Workspace.Terrain.WaterColor = settings["WaterColor"]
	end
	
	if (settings["WaterReflectance"] ~= nil) then
		game.Workspace.Terrain.WaterReflectance = settings["WaterReflectance"]
	end
	
	if (settings["WaterTransparency"] ~= nil) then
		game.Workspace.Terrain.WaterTransparency = settings["WaterTransparency"]
	end
	
	if (settings["WaterWaveSize"] ~= nil) then
		game.Workspace.Terrain.WaterWaveSize = settings["WaterWaveSize"]
	end
	
	if (settings["WaterWaveSpeed"] ~= nil) then
		game.Workspace.Terrain.WaterWaveSpeed = settings["WaterWaveSpeed"]
	end
	
	
end)

But I would love to not have to spell out every single property I want to override. I was surprised that there was no way to simply iterate over all the properties an Instance has.

I searched around here and found other devs doing some crazy stuff to hack around this limitation.

There should be an API like the one that was recently added for Attributes.

26 Likes

So if I’m understanding this correctly

for i,property in pairs(part:GetProperties()) do
      if settings[property.Name] then
            property.Value = settings[property.Name]
      end
end
2 Likes

Exactly. Much better than my word wall.

4 Likes
2 Likes

I feel like when I use other scripting languages with bad OOP support, like Javascript, I use reflection often.

So I find the incredulity in that thread incredulous.

4 Likes

One thing that will make the code slightly simpler (short of having a full reflection API) is that the . operator is really syntactic sugar for [string] operator:

t = {Transparency= 0.5} for k,v in pairs(t) do workspace.Part[k] = v end

so, as long as all keys in your table are valid property names, you can use a simple for loop to set every property listed in the table on the given object (without needing to copy-paste lines for every possible property).

If you are willing to only give the users a specific subset of properties that you want to allow them to modify, this is sufficient (just make a table where the properties you want to make edit-able are “whitelisted” by being keys in the table). This might be a reasonable limitation anyway for your usecase (e.g. you may not want users to be able to set other properties of Terrain, like CanCollide, Name, etc.)

6 Likes

You took me half the way there.

I need to play with that idiom. It seems really close to what I tried to do the first time. But I don’t think it gets my code into a 3-liner for loop over properties I want to alter.

I’m open to the possibility that I’m just an idiot. You guys wrote like 1.4M lines of Lua code for player, so if this never came up maybe I’m just slow/bad at programming.

3 Likes

This came up again today.

I have sections of my game map that I want to have different Lighting service properties for.

There is no way to swap a new Lighting service in, so the properties on Lighting service need to be patched.

Applying patches is tedious without reflection.

2 Likes

I very much agree. I’ve done this exact thing and had to manually keep a list of Lighting properties (which also means trusting the Properties pane and/or the dev hub).

Even more so, I’ve needed reflection for gui related plugins and scripts. A common action in creating UI in studio is to switch from a TextButton to an ImageButton or some other Instance transformation, but keep all the common properties the same (Size, Position, etc). Which is, as you said, tedious without reflection.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.