I have made a simple light manager script, it moves the lamps to empties at the nearest locations around the player.
script will explain itself, have fun with it.
#
# Light manager by Cotax
#
# on lamp(s) add property: light
# on placeholders(empties) add properties:
# - light_source -> boolean -> True (on/off)
# - energy -> float -> 1.0
# - distance -> float -> 4.0
# - color -> string -> 111 (rgb)
#run scriptname.place_light from any object you like with always(true)->python(module)
def first_run(cont):
own = cont.owner
own['lights'] = [obj for obj in own.scene.objects if 'light' in obj]
own['light_sources'] = [obj for obj in own.scene.objects if 'light_source' in obj if obj['light_source'] == True]
own['light_manager'] = True
def place_light(cont):
own = cont.owner
camera = own.scene.active_camera
if not 'light_manager' in own:
first_run(cont)
lights = own['lights']
light_sources = own['light_sources']
placeholders = sorted(light_sources, key=lambda light_source: camera.getDistanceTo(light_source))
i = 0
for lamp in lights:
if (i+1) <= len(light_sources):
lamp.worldPosition = placeholders[i].worldPosition
lamp.energy = placeholders[i]['energy']
lamp.distance = placeholders[i]['distance']
r = float(placeholders[i]['color_rgb'][0])
g = float(placeholders[i]['color_rgb'][1])
b = float(placeholders[i]['color_rgb'][2])
lamp.color = [r,g,b]
i+=1
#else:
#print('there are more lights then placeholders!')
you are free to use whatever you like, i am using blender and blender alone. And this works for my needs, donāt need anything fancy just something that works. I share it for people who like it and or can use it.
also added first_run():, so you donāt scan every frame for the lights and light sources.
That would probably be a lot faster but IMHO a really flexible light manager needs to be able to deal with moving lightsources and new light sources being added to the scene. Iāve built mine in to my particles manager so I can have light emitting particles. Iāve not found it to be that slow as long as I donāt have like a million light sources.
@cotax
I usually use a for i in range(number of lights) loop rather than a for light in lights loop. Then it doesnāt matter if you have more lights than placeholders:
lights = [particle for particle in self.particles if particle.light]
light_casting = sorted(lights, key = lambda particle: self.get_light_distance(particle))
for i in range(len(self.dynamic_lights)):
lamp = self.dynamic_lights[i]
if i < len(light_casting):
light_particle = light_casting[i]
lamp.worldPosition = light_particle.object_box.worldPosition.copy()
lamp.energy = light_particle.light_energy
lamp.color = light_particle.light_color
lamp.distance = light_particle.light_distance
else:
lamp.energy = 0.0
I set up self.dynamic lights at the start, but get my list of hooks/placeholders each tic, in this case all my lights are particles (but not all my particles are lights ).
Ok nice to know, i didnt now this and always tought that KDtree was an addon.
But for this its not needed (my case) due to i want to have control over it, spawning lights and removing them, playing actions etc (remember i have no clue how KDTree works) so i rather make my own script. and does not grab much reso. from anything.
I usually use a for i in range(number of lights) loop rather than a for light in lights loop. Then it doesn't matter if you have more lights than placeholders:
so you do actually the same, for i in range(light) or for light in lights. both ends up looping trough the lights.
the script i posted doesnāt care about having 100 lamps and only 2 place holders, thatās why i count the light_sources, the script stops when all light sources are taken. That is why i have the else: commented out, its just a check that you can use, or use it to set the energy to 0 like you do.
but get my list of hooks/placeholders each tic
same i do it every tic aswell, t just depends on what you use it for, i updated the script to just scan it once at game start, for people who like that over scanning every tic. and everyone should be good enough to remove those parts to get it every tic.
Ah ok. I see.
You can use the built in method for i in range() to do the same as you did there though. Itās not really better but might be more recognizable to other people (like me)
itās similar to a script that i made: original post from fisicomolon
there was a bug with loaded scenes that prevented new lights from being created, so i made a light manager to move lights around to objects with the correct properties. my method uses a navmesh and precreated lights. dinamic loading and light manager blend
maybe you can use it to improve your script: