跳转到内容

变换天空盒

变换天空盒

--使用方法:
--[[local DynamicSky = require "DynamicSky"
-- -- 客户端游戏启动时入口
function GameClient:OnStart()
UI:RegisterPressed(100047,function()
DynamicSky:start()
end)
]]
local DynamicSky = {}
--具体参数根据需要配置
-- 配置常量
local DAY_LENGTH = 24 -- 一天的总长度(小时)
local MAX_LIGHT_INTENSITY = 10 -- 最大光强
local MIN_LIGHT_INTENSITY = 0.1 -- 最小光强
local MORNING_START = 6 -- 日出时间(小时)
local EVENING_START = 17 -- 日落时间(小时)
local NIGHT_START = 21 -- 夜晚开始时间(小时)
local SKYLIGHT_MAX_INTENSITY = 2 -- 天光最大强度(对应API上限)
local SKYLIGHT_MIN_INTENSITY = 0.02 -- 天光最小强度
-- 全局速率参数:只需要调节这个参数即可全局调整效果
local TIME_SCALE = 1 -- 时间速率控制(1 为正常速度,<1 为减速,>1 为加速)
-- 天空盒配置表
local skybox_config = {
day = {key = SkyBox.SkyboxIndex.Daytime, transition_time = 1}, -- 白天
dusk = {key = SkyBox.SkyboxIndex.Twilight, transition_time = 1}, -- 黄昏
night = {key =SkyBox.SkyboxIndex.Night, transition_time = 1}, -- 夜晚
}
-- 光照参数表
local sun_config = {
elevation_range = {min = -30, max = 60}, -- 高度角范围(光源高度角,Pitch)
azimuth_range = {min = -90, max = 90}, -- 方位角范围(光源方位角,Yaw)
rotation_range = {min = -180, max = 180}, -- 天空盒旋转范围
light_colors = { -- 光线颜色配置(RGB 格式)
morning = {r = 255, g = 223, b = 186}, -- 清晨颜色
noon = {r = 255, g = 255, b = 255}, -- 正午颜色
evening = {r = 255, g = 183, b = 76}, -- 傍晚颜色
night = {r = 100, g = 100, b = 200} -- 夜晚颜色
}
}
-- 将 RGB 转换为十六进制颜色码
local function rgb_to_hex(r, g, b)
return string.format("#%02X%02X%02X", r, g, b)
end
-- 获取当前时间进度(0 到 1)
local function get_time_progress(current_time)
return (current_time % DAY_LENGTH) / DAY_LENGTH
end
-- 计算光照强度
local function calculate_light_intensity(current_time)
if current_time >= MORNING_START and current_time <= EVENING_START then
return MAX_LIGHT_INTENSITY
elseif current_time > EVENING_START and current_time <= NIGHT_START then
-- 傍晚光强逐渐减弱
return MAX_LIGHT_INTENSITY * (NIGHT_START - current_time) / (NIGHT_START - EVENING_START)
elseif current_time >= 0 and current_time < MORNING_START then
-- 清晨光强逐渐增强
return MIN_LIGHT_INTENSITY + (MAX_LIGHT_INTENSITY - MIN_LIGHT_INTENSITY) * (current_time / MORNING_START)
else
-- 夜晚光强保持最小
return MIN_LIGHT_INTENSITY
end
end
-- 计算光线颜色
local function calculate_light_color(current_time)
local color
if current_time >= MORNING_START and current_time < EVENING_START then
color = sun_config.light_colors.noon
elseif current_time >= EVENING_START and current_time < NIGHT_START then
color = sun_config.light_colors.evening
elseif current_time >= 0 and current_time < MORNING_START then
color = sun_config.light_colors.morning
else
color = sun_config.light_colors.night
end
-- 返回十六进制颜色码
return rgb_to_hex(color.r, color.g, color.b)
end
-- 计算光源角度和天空盒旋转角度
local function calculate_sun_angles(current_time)
-- 动态计算时间进度
local time_progress = get_time_progress(current_time)
-- 计算高度角(Pitch)
local pitch = sun_config.elevation_range.min
+ (sun_config.elevation_range.max - sun_config.elevation_range.min) * time_progress
-- 计算方位角(Yaw)
local yaw = sun_config.azimuth_range.min
+ (sun_config.azimuth_range.max - sun_config.azimuth_range.min) * time_progress
-- 计算天空盒旋转角度
local rotation = sun_config.rotation_range.min
+ (sun_config.rotation_range.max - sun_config.rotation_range.min) * time_progress
return -1*pitch, yaw, rotation
end
local Current_skybox=0
-- 动态调整天空盒
local function update_skybox(current_time)
if current_time >= MORNING_START and current_time < EVENING_START and Current_skybox~='day' then
SkyBox:SetSkyboxDisplayID(skybox_config.day.key,1) -- 白天
Current_skybox='day'
elseif current_time >= EVENING_START and current_time < NIGHT_START and Current_skybox~='Twilight' then
print('zhongwu')
SkyBox:SetSkyboxDisplayID(skybox_config.dusk.key, 1) -- 黄昏
Current_skybox='Twilight'
else
if Current_skybox~='night' then
print('wanshang')
SkyBox:SetSkyboxDisplayID(skybox_config.night.key, 1) -- 夜晚
Current_skybox='night'
end
end
end
-- 计算天光强度比例(将方向光强度映射到天光范围)
local function calculate_skylight_scale(light_intensity)
-- 线性映射公式:(当前强度 - 原最小)/(原最大 - 原最小) * (新最大 - 新最小) + 新最小
return ((light_intensity - MIN_LIGHT_INTENSITY) /
(MAX_LIGHT_INTENSITY - MIN_LIGHT_INTENSITY)) *
(SKYLIGHT_MAX_INTENSITY - SKYLIGHT_MIN_INTENSITY) + SKYLIGHT_MIN_INTENSITY
end
-- 更新光源参数
local function update_sunlight(current_time)
local light_intensity = calculate_light_intensity(current_time)
local skylight_scale = calculate_skylight_scale(light_intensity)
local light_color_hex = calculate_light_color(current_time)
local pitch, yaw, rotation = calculate_sun_angles(current_time)
print("light_intensity"..tostring( light_intensity))
-- 更新光照服务
SkyBox:SetDirectionalLightIntensity(light_intensity) -- 设置光照强度
print("light_intensity"..tostring( light_intensity))
SkyBox:SetDirectionalLightColor(light_color_hex) -- 设置光照颜色(十六进制)
SkyBox:SetDirectionalLightPitch(pitch) -- 设置光源高度角(Pitch)
print("pitch"..tostring( pitch))
SkyBox:SetDirectionalLightYaw(yaw) -- 设置光源方位角(Yaw)
print("yaw"..tostring( yaw))
SkyBox:SetSkyBoxRotation(rotation/3) -- 设置天空盒旋转角度
SkyBox:SetSkylightIntensityScale(skylight_scale) -- 天光强度设置
end
DynamicSky.current_time=0
DynamicSky.time_step = 0.05 * TIME_SCALE
-- 启动动态阳光功能
function DynamicSky:start()
DynamicSky.current_time = 0 -- 当前时间变量
DynamicSky.time_step = 0.05 * TIME_SCALE -- 根据时间速率调整步长
TimerManager:AddLoopTimer(0.03 * TIME_SCALE,
function ()
update_sunlight(DynamicSky.current_time) -- 更新阳光状态
update_skybox(DynamicSky.current_time) -- 动态调整天空盒
DynamicSky.current_time = DynamicSky.current_time + DynamicSky.time_step -- 时间递增
if DynamicSky.current_time >= DAY_LENGTH then
DynamicSky.current_time = 0 -- 一天结束,重置时间为凌晨
end
end,0.03 * TIME_SCALE)
end
return DynamicSky