require "bit" MainCamera = MainCamera or BaseClass(BaseModel) local MainCamera = MainCamera local Scene = Scene local GlobalEventSystem = GlobalEventSystem local SceneEventType = SceneEventType local IsTableEmpty = IsTableEmpty local GameMath = GameMath local Time = Time local math_abs = math.abs local math_sin = math.sin local table_remove = table.remove local table_insert = table.insert local GameMath_Lerp = GameMath.Lerp local ReleaseTemporary = UnityEngine.RenderTexture.ReleaseTemporary local Clamp = Mathf.Clamp --摄像机和主角的平面距离 CameraDistanceWithMainRole = 10.7 --摄像机可视范围 CameraDefaultFieldofView = 37 --摄像机和地面夹角 SceneCameraRotate = 40.0 --摄像机离地面高度 SceneCameraHeigth = 10.0 MainCamera.PixelsToUnits = 100 --像素坐标比例 MainCamera.SmoothMode = true --摄像机开启平滑 MainCamera.SmoothTime = 0.1 --摄像机平滑时间 MainCamera.ScreenCenterOffset = 0 --摄像机偏移主角位置像素值 MainCamera.ScreenScale = 1.1 --摄像机视窗缩放 MainCamera.SizeSmoothSpeed = 1 --摄像机缩放的时候的默认速度 MainCamera.SmoothState = { --摄像机缓动类型,对应着不同参数 Normal = 0, Jump = 1, Skill = 2, Jump_Point = 3, Horse = 4, Speed_Buff = 5, Quiz = 6, NewBieTask = 7, TaskJump = 8, Flash = 9, None = 10, SpecialDun = 11, JUMP_ONE = 12, } --摄像机旋转相关参数 MainCamera.role_last_angle = 0 MainCamera.role_cur_angle = 0 MainCamera.role_angle_off = 0 MainCamera.role_from_camera_angle = 0 MainCamera.role_last_rotate_area = false MainCamera.camera_cur_angle = 0 MainCamera.camera_target_angle = 0 MainCamera.camera_enable_rotate = false -------------------------------------高斯模糊相关------------------------------------- -- 屏幕后处理预设 -- MainCamera.RenderEffectPreset = { -- Grayed = {brightness = 1, saturation = 0, contrast = 1}, -- 灰化预设 -- } -- 激活了后处理效果 -- MainCamera.Activiting_Render_Effect = false -- 特效相机类型 默认情况下,黑白化只需要MainCamera,一般大界面(全屏显示)的高斯模糊只需要模糊UI摄像机 MainCamera.EffectCameraType = { MainCamera = 0, -- 主场景摄像机 UICamera = 1, -- ui摄像机(由于渲染顺序的问题,只要处理了UI摄像机,主摄像机的画面效果也会被影响,后续处理中注意避免两个特效同时开启) } -- 激活了模糊效果 MainCamera.Activiting_Blur_Effect = false MainCamera.FreeCameraViewOpened = false -- 是否打开了自由摄像机调试界面 function MainCamera:__init() if MainCamera.Instance ~= nil then LogError("MainCamera is a singleton class") end MainCamera.Instance = self self.smoothTarget = nil self.firstMove = true self.rendering_blur_screenShot = false self.round_robin_cache_list = {} self.gameObject = GameObject.Find("root/MainCameraRoot") --3D中摄像机分成两个层级控制,ROOT中控制旋转和位置,Camera控制俯视角度以及摄像机与玩家的距离 if self.gameObject then self.transform = self.gameObject.transform self.camera_gameObject = GameObject.Find("root/MainCameraRoot/MainCamera") self.camera = self.camera_gameObject:GetComponent("Camera") --这里用GetComponentInChildren总是报错不知道为啥 SetGlobalPosition(self.camera.transform, 0, 0, -CameraDistanceWithMainRole) self.camera.backgroundColor = Color(0,0,0,0) self.camera.farClipPlane = 1900 self.camera_base_size_original = ScreenHeight / MainCamera.PixelsToUnits * 0.5 self.camera_base_size = CameraDefaultFieldofView self:SetCameraSize(60) self.camera_curr_size = self.camera_base_size self.uiCamera_gameObject=GameObject.Find("root/UICamera") self.uiCamera=self.uiCamera_gameObject:GetComponent("Camera") self.camera.fieldOfView = CameraDefaultFieldofView --剧情动画摄像机 self.story_cam_obj = GameObject.Find("root/StoryCamera") if self.story_cam_obj then self.story_cam_obj:SetActive(false) end -- 剧情摄像机添加径向模糊 self.story_radiusBlur = self.story_cam_obj:AddComponent(typeof(RadiusBlur)) self.story_radiusBlur.enabled = false self.story_radiusBlur.radius_material = ShaderTools.GetRadiusMaterial() -- 添加径向模糊默认值 self:SetStoryCameraRadiusData(0.5, 0.5, 0.01) self:SetStoryCameraRadiusIteration(10) -- 高斯模糊摄像机 -- self.blurCamera_gameObject = GameObject.Find("root/BlurCamera") -- self.blurCamera = self.blurCamera_gameObject:GetComponent("Camera") -- 获取到摄像机后就隐藏起来 -- self.blurCamera.enabled = false ------------//////////////////////////// -- 整合屏幕后处理效果PostEffect -- 目标的纹理降低采样率比率和迭代次数设置 self.main_blur_downSample_value = 4 self.ui_blur_downSample_value = 5 -- 主摄像机后处理 self:ApplyMainPostEffect() -- UI摄像机后处理 -- if not self.ui_postEffect then -- self.ui_postEffect = self.uiCamera_gameObject:GetComponent(typeof(PostEffect)) -- end -- if not IsNull(self.ui_postEffect) then -- -- if not self:IsSupportPostEffect() then -- -- self.ui_postEffect.enabled = false -- -- else -- -- self.ui_postEffect.enabled = true -- -- 设置FXAA参数 -- self.ui_postEffect.EnableFXAA = false -- -- 设置泛光模糊参数 -- self.ui_postEffect.EnableBloom = false -- -- 设置模糊参数 -- self.ui_postEffect.EnableBlur = true -- self.ui_postEffect.recurveMaxNum = 4 -- self.ui_postEffect.blurSpread = 2 -- self.ui_postEffect.use_dual_blur = true -- -- 应用数据到材质球 -- self.ui_postEffect:ApplyBloomMaterialProperties() -- self.ui_postEffect:ApplyFXAAMaterialProperties() -- -- end -- end -- 检测设备是否支持后处理 self:SetRenderSupport() if not self.is_screen_effect_supported then if not IsNull(self.main_postEffect) then self.main_postEffect.enabled = false end -- if not IsNull(self.ui_postEffect) then -- self.ui_postEffect.enabled = false -- end end ------------//////////////////////////// end self.screen_obj_count = 0 --屏幕摄像机对象数量 self.is_update_camera = true self.is_lock_camera = false --是否锁定摄像机 self.lock_camera_pos = false --锁定的位置 self.lock_move_speed = 0 --锁定的时候的移动速度 self.is_change_size = false --摄像机是否在改变大小 self.camera_move_speed = co.Vector2(0,0) self.real_now_pos = co.Vector2(0,0) self.orthographic_state = false --默认正交摄像机 self.rotate_around = 0 self.maxDistance = 2 --摄像机跟随的最大距离限制,超过这个距离就会达到最大速度也就是刚好跟着主角移动 self.maxSpeed = 0.2 --摄像机跟随移动的最大速度,需要大于等于人物的移动速度 self.isSmooth = MainCamera.SmoothMode self.targetSmoothSpeed = self.maxSpeed self.smoothState = MainCamera.SmoothState.Normal --相机平滑移动的状态,不同状态速度不同 self.can_scale_camera = true self.shake_elements_list = {} self.temp_pos = {x = 0,y = 0,z = 0} self.temp_shake_pos = {x = 0,y = 0} self.camera.transform.localRotation = Quaternion.Euler(SceneCameraRotate,0,0) self.size_smooth_list ={} self.is_showing_sky_res = false --是否正常显示全屏天空盒 self.cur_terrain_alpha = false local function sceneChanged() ---在切换场景的时候,取消缓动效果 self.isSmoothing = false if not SceneManager.Instance:IsPkRankFightScene() and self.smoothTarget and self.is_update_camera then self.transform.position = self.smoothTarget --处理重复进入同一个场景的时候,比如切换角色但是选择的还是当前角色 self.size_smooth_list = {} GlobalEventSystem:Fire(SceneEventType.CAMERA_MOVE) end local dun_id = SceneManager.Instance:GetCurrDunId() local camera_config = Config.ConfigSceneCamera.LockDungeon[dun_id] if camera_config then local function on_set_camera_mode( ) local cur_dun_id = SceneManager.Instance:GetCurrDunId() if cur_dun_id ~= dun_id then return end self.use_special_camera = true self:SetSpecialDunMode(camera_config) MainCamera.camera_enable_rotate = false end if camera_config.is_delay then setTimeout(on_set_camera_mode, 1) else on_set_camera_mode() end elseif self.use_special_camera then self.use_special_camera = false self:QuitSpecialDunMode() end self.block_smooth = false print("MainCamera Load Complete") self:HideBlackSky(self.black_sky_res) end local function ReEnter() if SceneManager:getInstance():IsGemDungeon() or SceneManager:getInstance():IsGodHoodDungeon() then --这两个副本,在第一次进去的时候,不要无缝切换,第二次开始才无缝切换 self.size_smooth_list = {} self.isSmoothing = false self.block_smooth = true GlobalEventSystem:Fire(SceneEventType.CAMERA_MOVE) end self:HideBlackSky(self.black_sky_res) end GlobalEventSystem:Bind(EventName.SCENE_LOAD_VIEW_COMPLETE,sceneChanged) GlobalEventSystem:Bind(SceneEventType.SCENE_REENTER, ReEnter) local load_call_back = function(objs) if objs and objs[0] then self.intoscene_effect = newObject(objs[0]) self.intoscene_effect.transform:SetParent(self.camera.transform) self.intoscene_effect.transform.localEulerAngles = Vector3(0, 0, 0) SetLocalPosition(self.intoscene_effect.transform,0) self.intoscene_effect:SetActive(false) end end local change_scene_particle = "camfx_scenetransform" lua_resM:loadPrefab(self, change_scene_particle, change_scene_particle, load_call_back, nil, ASSETS_LEVEL.LOW) local main_canvas_change = function( state ) if state then self.isSmooth = MainCamera.SmoothMode else self.isSmooth = false end end LuaViewManager.Instance:Bind(LuaViewManager.BOCAST_MAIN_CANVAS_LAST_STATE,main_canvas_change) end function MainCamera:getInstance() if MainCamera.Instance == nil then MainCamera.New() end return MainCamera.Instance end function MainCamera:ApplyMainPostEffect( ) self.is_login_post_effect_state = false if not self.main_postEffect then self.main_postEffect = self.camera_gameObject:GetComponent(typeof(PostEffect)) end if not IsNull(self.main_postEffect) then -- 主摄像机,高端设备上开泛光 if not self:IsSupportPostEffect() then self.main_postEffect.enabled = false else self.main_postEffect.enabled = true -- 设置泛光模糊参数 self.main_postEffect.EnableBloom = true self.main_postEffect.threshold = 0.65 self.main_postEffect.intensity = 1.2 self.main_postEffect.blurSize = 1 self.main_postEffect.blurIterations = 1 self.main_postEffect.use_dual_bloom = true -- 设置FXAA参数 self.main_postEffect.EnableFXAA = false -- 设置模糊参数 self.main_postEffect.EnableBlur = false -- 应用数据到材质球 self.main_postEffect:ApplyBloomMaterialProperties() end end end --登录镜头特殊处理 function MainCamera:ApplyLoginPostEffect( ) self.is_login_post_effect_state = true local function on_login_effect( ) if not self.main_postEffect then self.main_postEffect = self.camera_gameObject:GetComponent(typeof(PostEffect)) end if not IsNull(self.main_postEffect) then -- 主摄像机,中高端设备上开泛光 if SystemMemoryLevel.Cur == SystemMemoryLevel.Low then self.main_postEffect.enabled = false else self.main_postEffect.enabled = true -- 设置泛光模糊参数 self.main_postEffect.EnableBloom = true self.main_postEffect.threshold = 0.8 self.main_postEffect.intensity = 2.64 self.main_postEffect.blurSize = 2.5 self.main_postEffect.blurIterations = 3 self.main_postEffect.use_dual_bloom = true -- 设置FXAA参数 self.main_postEffect.EnableFXAA = false -- 设置模糊参数 self.main_postEffect.EnableBlur = false -- 应用数据到材质球 self.main_postEffect:ApplyBloomMaterialProperties() end end end on_login_effect() setTimeout(on_login_effect, 0.1) end function MainCamera:ShowEnterSceneEffect() -- 新手2002副本出来要衔接剧情,不用特效 local last_dun_id = SceneManager:getInstance():GetLastDunId() if last_dun_id and last_dun_id == 2002 then return end local hide_func = function() if self.intoscene_effect then self.intoscene_effect:SetActive(false) self.effect_id = nil end end if self.effect_id then GlobalTimerQuest:CancelQuest(self.effect_id) self.effect_id = nil if self.intoscene_effect then self.intoscene_effect:SetActive(false) end end if self.intoscene_effect then self.intoscene_effect:SetActive(true) end if not self.effect_id then self.effect_id = GlobalTimerQuest:AddDelayQuest(hide_func,3) end end function MainCamera:GetScreenEffectCamere() if self.screen_effect_camera == nil then self.screen_effect_camera = UiFactory.createChild(self.transform, UIType.Camera3D, "Camera3D") self.screen_effect_camera.transform.localRotation = Quaternion.Euler(30,-90,0) self.screen_effect_camera:SetActive(not lua_settingM:GetBlockProperty("scenePtc")) end return self.screen_effect_camera end function MainCamera:DestoryScreenEffectCamere() if self.screen_effect_camera then destroy(self.screen_effect_camera) self.screen_effect_camera = nil end end function MainCamera:SetScreenEffectCamereState( state ) if self.screen_effect_camera then self.screen_effect_camera:SetActive(state) end end --[[设置摄像机的视野范围 注意:修改的参数是 fieldOfView 而不是transform的scale或者位置 size 需要的目标大小 isSmooth 是否平滑过渡,如果否,将会取消当前的平滑列表(如果正在平滑过程中) ]] function MainCamera:SetCameraSize(size, isSmooth) if self.camera.fieldOfView == size then return end if isSmooth then if not self.size_smooth_list then self.size_smooth_list = {} end table_insert(self.size_smooth_list,size) else self.size_smooth_list = nil self.size_smooth_list = {} self.camera_curr_size = size self.camera.fieldOfView = size if self.screencamera then self.screencamera.fieldOfView = size end end -- if Scene.Instance and not specialScene then -- local now_pos = self.real_now_pos -- local cam_scale = MainCamera.ScreenScale * size / self.camera_base_size -- local half_target_width = SrcScreenWidth * cam_scale / 2 -- local half_target_height = ScreenHeight * cam_scale / 2 -- local scene_size = Scene.Instance:GetSceneSize() -- local scene_width = scene_size.x - half_target_width -- local scene_height = scene_size.y - half_target_height -- if half_target_width < scene_width then -- if now_pos.x < half_target_width then -- return -- elseif now_pos.x > scene_width then -- return -- end -- else -- return -- end -- if half_target_height < scene_height then -- if now_pos.y < half_target_height then -- return -- elseif now_pos.y > scene_height then -- return -- end -- else -- return -- end -- end GlobalEventSystem:Fire(SceneEventType.CAMERA_CHANGE_SIZE, self.camera_curr_size / self.camera_base_size) -- if Scene.Instance and Scene.Instance.main_role then --3D项目就不用改变玩家模型大小了 -- local curr_scale = math.pow(self.camera_curr_size / self.camera_base_size, Config.otherFightInfo.mainrole_jump_scale) -- if Scene.Instance.main_role.name_board then -- Scene.Instance.main_role.name_board:SetScale(curr_scale) -- end -- Scene.Instance.main_role:SetScale(curr_scale) -- end end function MainCamera:SetBaseCameraSize(size) if not self.can_scale_camera then return end self.camera_curr_size = size self:SetCameraSize(size) end function MainCamera:GetCameraRatio() -- return self.camera_curr_size / self.camera_base_size_original return self.camera_curr_size / self.camera_base_size end function MainCamera:ScaleCamera( scale ) self:SetCameraSize(self.camera_base_size * scale) end function MainCamera:GetCameraPos() return self.real_now_pos end function MainCamera:ScreenToWorldPoint( x, y ) return self.camera:ScreenToWorldPoint(Vector3(x,y,0)) end function MainCamera:WorldToViewportPoint( x,y,z ) return Vector3(x - self.real_now_pos.x,y - self.real_now_pos.y,z) / MainCamera.ScreenScale end function MainCamera:WorldToScreenPoint( vect ) return self.camera:WorldToScreenPoint(vect) end function MainCamera:CameraBoundHandle(to_set_pos) local now_pos = to_set_pos local cam_scale = MainCamera.ScreenScale * self.camera_curr_size / self.camera_base_size local half_target_width = SrcScreenWidth * cam_scale / 2 local half_target_height = ScreenHeight * cam_scale / 2 local scene_size = Scene.Instance:GetSceneSize() local scene_width = scene_size.x - half_target_width local scene_height = scene_size.y - half_target_height if half_target_width < scene_width then if now_pos.x < half_target_width then now_pos.x = half_target_width elseif now_pos.x > scene_width then now_pos.x = scene_width end else now_pos.x = scene_size.x/ 2 end if half_target_height < scene_height then if now_pos.y < half_target_height then now_pos.y = half_target_height elseif now_pos.y > scene_height then now_pos.y = scene_height end else now_pos.y = scene_size.y / 2 end return now_pos end function MainCamera:JoyStickState( state ) self.is_joystick_state = state end function MainCamera:IsJoyStickState( ) return self.is_joystick_state end function MainCamera:UpdateCameraPosDirect(posx,posy,height) if self.update_direct_pos == nil then self.update_direct_pos = co.TableXY(posx,posy + MainCamera.ScreenCenterOffset) else self.update_direct_pos.x = posx self.update_direct_pos.y = posy + MainCamera.ScreenCenterOffset end --self.update_direct_pos = self:CameraBoundHandle(self.update_direct_pos) --target_pos.x = bit.toint(target_pos.x) --target_pos.y = bit.toint(target_pos.y) -- local x = math.abs(target_pos.x - self.real_now_pos.x) -- local y = math.abs(target_pos.y - self.real_now_pos.y) -- if self.is_joystick_state and ( x > 10 or y > 10) then -- end self:SetPos(self.update_direct_pos.x, self.update_direct_pos.y,height) self.camera_move_speed.x = 0 self.camera_move_speed.y = 0 end function MainCamera:Update(now_time, elapse_time) -- if self.is_update_camera then -- --self:UpdateCamera(target_pos, is_in_move, main_move_dir, elapse_time) -- end if not self.is_update_camera then return end if MainCamera.FreeCameraViewOpened then -- 打开了自由摄像机界面后,该值为true return end self:UpdateShakeScreen(now_time, elapse_time) -- self:UpdateLockCamera(now_time,elapse_time) self:UpdateCameraSize(now_time,elapse_time) --self:UpdateCamerView() self:SmoothPosToTarget() end --震屏处理 function MainCamera:UpdateShakeScreen(now_time, elapse_time) if not Scene.Instance.main_role then return end if IsTableEmpty(self.shake_elements_list) then self.is_shaking = false else self.is_shaking = true local curr_shake_range_x = 0 local curr_shake_range_y = 0 local curr_shake_range_s = 0 local curr_shake_range = 0 local ratio = 0 local radian_off = 0 local past_time = 0 for i, vo in ipairs(self.shake_elements_list) do past_time = Status.NowTime - vo.add_list_time if past_time >= vo.shake_start_time then ratio = (past_time - vo.shake_start_time) / vo.shake_lase_time ratio = ratio > 1 and 1 or ratio curr_shake_range = vo.shake_max_range * math_sin((ratio * vo.shake_angle + vo.start_angle) * math.pi / 180) if vo.shake_type == 1 then --上下 if math_abs(curr_shake_range) > math_abs(curr_shake_range_y) then curr_shake_range_y = curr_shake_range end elseif vo.shake_type == 2 then --左右 if math_abs(curr_shake_range) > math_abs(curr_shake_range_x) then curr_shake_range_x = curr_shake_range end elseif vo.shake_type == 3 then --拉伸 if math_abs(curr_shake_range) > math_abs(curr_shake_range_s) then curr_shake_range_s = curr_shake_range end end if ratio >= 1 then table_remove(self.shake_elements_list, i) end end end if curr_shake_range_x ~= 0 or curr_shake_range_y ~= 0 then local role_real_pos = Scene.Instance.main_role.real_pos if math_abs(self.real_now_pos.x - role_real_pos.x - curr_shake_range_x) > 100 or math_abs(self.real_now_pos.y - role_real_pos.y - MainCamera.ScreenCenterOffset - curr_shake_range_y) > 100 then self.temp_shake_pos.x = role_real_pos.x + curr_shake_range_x self.temp_shake_pos.y = role_real_pos.y + curr_shake_range_y self:UpdateCamera(self.temp_shake_pos, nil, nil, true) else self:UpdateCameraPosDirect(role_real_pos.x + curr_shake_range_x, role_real_pos.y + curr_shake_range_y) end end if curr_shake_range_s ~= 0 then self:SetCameraSize(CameraDefaultFieldofView + curr_shake_range_s / MainCamera.PixelsToUnits) end if IsTableEmpty(self.shake_elements_list) then self.is_shaking = false self:SetCameraSize(CameraDefaultFieldofView) -- 2D用 self.camera_base_size if Scene.Instance.main_role then self:UpdateCamera(Scene.Instance.main_role.real_pos) end end end end --添加震屏项 function MainCamera:AddShakeElement(shake_start_time, shake_type, shake_lase_time, shake_max_range, shake_angle, start_angle) if shake_lase_time == 0 or shake_max_range == 0 or shake_angle == 0 or lua_settingM:ExistBlockSet("shakeScreen") then return end if (not lua_viewM.main_cancas_last_visible) or lua_viewM.is_lock_screen then return end local shake_info = { shake_type = shake_type, shake_lase_time = shake_lase_time, shake_max_range = shake_max_range or 15, --start_shake_pos = co.TableXY(RoleManager.Instance.mainRoleInfo.pos_x, RoleManager.Instance.mainRoleInfo.pos_y), shake_angle = shake_angle or 180, start_angle = start_angle, -- start_camera_size = self.camera_curr_size, shake_start_time = shake_start_time, add_list_time = Status.NowTime, } table_insert(self.shake_elements_list, shake_info) self.is_shaking = true end function MainCamera:ClearShakeElement() self.shake_elements_list = {} end function MainCamera:SetUpdateCameraEnabled(flag) self.is_update_camera = flag local game_vector2 = self.transform.position self.real_now_pos.x = game_vector2.x * MainCamera.PixelsToUnits self.real_now_pos.y = game_vector2.z * MainCamera.PixelsToUnits self.camera_move_speed.x = 0 self.camera_move_speed.y = 0 self.last_t_pos = nil if flag then self.camera.transform.localRotation = Quaternion.Euler(SceneCameraRotate,0,0) self.transform.rotation = Quaternion.Euler(0,0,0) SetLocalPosition(self.camera.transform, 0, 0, -CameraDistanceWithMainRole) end end function MainCamera:UpdateCameraPos(dest_pos,time,elapse_time) if self.move_start_time < time then self.move_start_time = self.move_start_time + Time.deltaTime if self.move_constant then local now_pos = GameMath_Lerp(self.move_start_pos,dest_pos,self.move_start_time/time) self:SetPos(now_pos.x,now_pos.y) else local x = GameMath.EaseInOutQuad(self.move_start_pos.x,dest_pos.x,self.move_start_time/time) local y = GameMath.EaseInOutQuad(self.move_start_pos.y,dest_pos.y,self.move_start_time/time) self:SetPos(x,y) end else self.lock_camera_pos = false end end function MainCamera:UpdateCameraSizeBySize(elapse_time) if self.change_start_time < self.change_size_time then self.change_start_time = self.change_start_time + Time.deltaTime local scale = GameMath_Lerp(self.change_start_scale,self.dest_camera_scale,self.change_start_time/self.change_size_time) self:ScaleCamera(scale) else self.is_change_size = false end end function MainCamera:RandFunc(x) local ret_val = math.floor(x) local val = x - ret_val if val >= 0.5 then ret_val = ret_val + 1 end return ret_val end function MainCamera:UpdateCamera(t_pos, is_in_move, elapse_time, force_update) if self.is_shaking and not force_update then return end if self.last_t_pos and self.last_t_pos.x == t_pos.x and self.last_t_pos.y == t_pos.y then return end elapse_time = 1.0/LuaFPS.FPS if self.target_pos == nil then self.target_pos = co.Vector2(t_pos.x,t_pos.y + MainCamera.ScreenCenterOffset) else self.target_pos.x = t_pos.x self.target_pos.y = t_pos.y + MainCamera.ScreenCenterOffset end --暂时直接将主角当为摄像机目标 if self.inteval_pos == nil then self.inteval_pos = self.target_pos - self.real_now_pos else self.inteval_pos.x = self.target_pos.x - self.real_now_pos.x self.inteval_pos.y = self.target_pos.y - self.real_now_pos.y end if self.inteval_pos.x < -1000 or self.inteval_pos.x > 1000 or self.inteval_pos.y < -1000 or self.inteval_pos.y > 1000 then self.target_pos = self:CameraBoundHandle(self.target_pos) --self.target_pos.x = bit.toint(self.target_pos.x) --self.target_pos.y = bit.toint(self.target_pos.y) self.camera_move_speed.x = 0 self.camera_move_speed.y = 0 --self.real_now_pos.x = self.target_pos.x --self.real_now_pos.y = self.target_pos.y self:SetPos(self.target_pos.x, self.target_pos.y, nil , force_update) return end local smooth_time = MainCamera.SmoothTime local tem_pos = self.target_pos -- tem_pos, self.camera_move_speed = -- GameMath.Smooth(self.real_now_pos, self.target_pos, -- self.camera_move_speed, -- smooth_time, -- elapse_time) if self.last_t_pos == nil then self.last_t_pos = co.TableXY(tem_pos.x, tem_pos.y - MainCamera.ScreenCenterOffset) else self.last_t_pos.x, self.last_t_pos.y = tem_pos.x, tem_pos.y - MainCamera.ScreenCenterOffset end tem_pos = self:CameraBoundHandle(tem_pos) tem_pos.x = self:RandFunc(tem_pos.x) tem_pos.y = self:RandFunc(tem_pos.y) self:SetPos(tem_pos.x, tem_pos.y, nil, force_update) end --摄像机跟随 function MainCamera:Follow(pos,now_time,elapse_time,dontCheckBound) if pos then local tem_pos = {} tem_pos.x = GameMath_Lerp(self.real_now_pos.x,pos.x,elapse_time * 2) tem_pos.y = GameMath_Lerp(self.real_now_pos.y,pos.y,elapse_time * 2) if dontCheckBound then self:SetPos(tem_pos.x,tem_pos.y) else local real_now_pos = self:CameraBoundHandle(tem_pos) self:SetPos(real_now_pos.x,real_now_pos.y) end end end function MainCamera:SetPos( posx, posy,height,force_update) if SceneManager:getInstance():IsStarFightScene() then return end if self.real_now_pos and self.real_now_pos.x == posx and self.real_now_pos.y == posy and not height and not force_update then return end self.real_now_pos.x, self.real_now_pos.y = posx, posy local mainrole_height = 0 local mainrole = Scene.Instance:GetMainRole() if mainrole then mainrole_height = mainrole.obj_pos_height if mainrole_height == 0 and self.last_role_height then mainrole_height = self.last_role_height end if mainrole_height > 0 then self.last_role_height = mainrole_height end end height = height or 0 self.temp_pos.x = posx / MainCamera.PixelsToUnits; --transform.x self.temp_pos.y = posy / MainCamera.PixelsToUnits --transform.z self.temp_pos.z = SceneCameraHeigth + mainrole_height + height / MainCamera.PixelsToUnits--transform.y --摄像机的y轴给一个插值过渡 -- if(math.abs(self.transform.position.y - realz) < 3) then -- realz = GameMath_Lerp(realz,self.transform.position.y,0.01) -- end if self.isSmoothing then self.smoothTarget = Vector3(self.temp_pos.x,self.temp_pos.z,self.temp_pos.y) --self:SmoothPosToTarget() else self.smoothTarget = nil SetGlobalPosition3D(self.transform, self.temp_pos.x, self.temp_pos.y, self.temp_pos.z) GlobalEventSystem:Fire(SceneEventType.CAMERA_MOVE) end end function MainCamera:SetSmoothingState(bool) self.isSmoothing = bool end function MainCamera:GetCameraRealHeight() local mainrole_height = 0 local mainrole = Scene.Instance:GetMainRole() if mainrole then mainrole_height = mainrole.obj_pos_height end local realz = SceneCameraHeigth + mainrole_height return realz end --@pos:摄像机的目标坐标 --@immediately:是立即跳至目标点还是缓动移过去 --@constant:是否匀速移动 function MainCamera:SetLockCameraPos(x,y,time,immediately,constant) self.is_lock_camera = true self.lock_camera_pos = co.TableXY(x,y + MainCamera.ScreenCenterOffset) self.move_immediately = immediately self.move_constant = constant self.move_camera_time = time self.move_start_time = 0 self.move_start_pos = co.Vector2(self.real_now_pos.x,self.real_now_pos.y) end function MainCamera:SetCameraChangeSize(scale,time,immediately) self.is_change_size = true self.dest_camera_scale = scale self.change_start_time = 0 self.change_start_scale = self.camera_curr_size / self.camera_base_size self.change_size_time = time self.change_immediately = immediately end function MainCamera:UpdateCameraPosByMainRole(force_update) if Scene.Instance.main_role == nil then return end self.is_lock_camera = false self.lock_camera_pos = false if Scene.Instance.main_role then self:UpdateCamera(Scene.Instance.main_role.real_pos,nil,nil,force_update) end end --摄像机是否锁定不跟随主角 function MainCamera:IsLockCamera() return self.is_lock_camera end --摄像机是否在改变大小 function MainCamera:IsChangeSize() return self.is_change_size end --摄像机是否在改变大小 function MainCamera:IsMoveCamera() return self.lock_camera_pos end --摄像机是否震屏 function MainCamera:IsShakeCamera() return self.is_shaking end --摄像机是否锁定不跟随主角 function MainCamera:UpdateLockCamera(now_time, elapse_time) --如果外部指定的摄像机坐标就指定坐标 if self.is_lock_camera and self.lock_camera_pos then if not self.move_immediately then self:UpdateCameraPos(self.lock_camera_pos,self.move_camera_time,elapse_time) else self:SetPos(self.lock_camera_pos.x, self.lock_camera_pos.y) self.lock_camera_pos = false end end end --摄像机是否锁定不跟随主角 function MainCamera:UpdateCameraSize(now_time, elapse_time) --如果外部指定的摄像机坐标就指定坐标 if self.is_change_size and self.dest_camera_scale ~= nil then if not self.change_immediately then self:UpdateCameraSizeBySize(elapse_time) else self:ScaleCamera(self.dest_camera_scale) self.is_change_size = false end end end --更新摄像机视野范围的平滑动画 function MainCamera:UpdateCamerView( ) if not(IsTableEmpty(self.size_smooth_list))then local target = self:GetNextSmoothTarget() if not(target == -1 ) then if not (target) then return end local temp = target - self.camera.fieldOfView local sign = 1 if(temp < 0) then sign = -1 end self.camera.fieldOfView = (self.camera.fieldOfView + MainCamera.SizeSmoothSpeed * sign) if self.screencamera then self.screencamera.fieldOfView = (self.camera.fieldOfView + MainCamera.SizeSmoothSpeed * sign) end if(math_abs(self.camera.fieldOfView - target) < MainCamera.SizeSmoothSpeed*2) then self.camera_curr_size = target self.camera.fieldOfView = target if self.screencamera then self.screencamera.fieldOfView = target end end end end end function MainCamera:GetNextSmoothTarget() if not(self.size_smooth_list) then return -1 end if not(IsTableEmpty(self.size_smooth_list)) then if(self.camera.fieldOfView == self.size_smooth_list[1]) then table_remove(self.size_smooth_list,1) self:GetNextSmoothTarget() else return self.size_smooth_list[1] end else return -1 end end --恢复摄像机初始设置 function MainCamera:InitCameraSetting() self.is_lock_camera = false self.lock_camera_pos = false self.isSmoothing = false self.real_now_pos.x, self.real_now_pos.y = 0, 0 self.last_t_pos = nil self.shake_elements_list = {} -- if SceneManager.Instance:IsPkRankFightScene() then -- local mainrole = Scene.Instance:GetMainRole() -- if mainrole then -- local newHeight = Scene.Instance:GetZoneHeight(4880/SceneObj.LogicRealRatio.x,4300/SceneObj.LogicRealRatio.y) -- mainrole.obj_pos_height = newHeight -- end -- self:SetCameraSize(55) -- self:SetPos(4880, 4300) -- end end function MainCamera:RotateAround( position, dir, value ) self.rotate_around = self.rotate_around + value if math_abs(self.rotate_around) > 360 then if self.rotate_around > 0 then self.rotate_around = self.rotate_around - 360 else self.rotate_around = self.rotate_around + 360 end end self.transform:RotateAround( position, dir, value) end --改变相机的移动是否平滑过渡 isActive = true or false function MainCamera:ChangeSmoothActive(isActive) self.isSmooth = isActive end function MainCamera:ChangeSmoothState(state) self.smoothState = state if state == MainCamera.SmoothState.Normal then -- self.maxDistance = 2 -- self.maxSpeed = 0.15 -- self.targetSmoothSpeed = 0.15 self.maxDistance = 2 self.maxSpeed = 0.22 self.targetSmoothSpeed = 2 self.isSmooth = true elseif state == MainCamera.SmoothState.Jump then self.maxDistance = 2 -- self.maxSpeed = 0.35 self.targetSmoothSpeed = 0.5 elseif state == MainCamera.SmoothState.Skill then self.maxDistance = 2 self.maxSpeed = 0.22 self.targetSmoothSpeed = 2 elseif state == MainCamera.SmoothState.Jump_Point then self.maxDistance = 3.5 self.maxSpeed = 0.4 self.targetSmoothSpeed = 2 elseif state == MainCamera.SmoothState.JUMP_ONE then self.maxDistance = 3.5 self.maxSpeed = 0.4 self.targetSmoothSpeed = 2 elseif state == MainCamera.SmoothState.Horse then self.maxDistance = 3 self.maxSpeed = 0.5 self.targetSmoothSpeed = 1 elseif state == MainCamera.SmoothState.Speed_Buff then self.maxDistance = 2 self.maxSpeed = 3 self.targetSmoothSpeed = 3 elseif state == MainCamera.SmoothState.Quiz then self.maxDistance = 3 self.maxSpeed = 0.22 self.targetSmoothSpeed = 1 elseif state == MainCamera.SmoothState.NewBieTask then self.maxDistance = 2 self.maxSpeed = 0.6 self.targetSmoothSpeed = 0.25 elseif state == MainCamera.SmoothState.TaskJump then self.maxDistance = 4 self.maxSpeed = 0.3 self.targetSmoothSpeed = 0.3 elseif state == MainCamera.SmoothState.Flash then self.maxDistance = 6 self.maxSpeed = 0.4 self.targetSmoothSpeed = 0.4 elseif state == MainCamera.SmoothState.SpecialDun then self.maxDistance = 3 self.maxSpeed = 0.3 self.targetSmoothSpeed = 0.25 self.isSmoothing = true elseif state == MainCamera.SmoothState.None then self.maxDistance = 6 self.maxSpeed = 0.4 self.targetSmoothSpeed = 0 self.isSmoothing = false self.isSmooth = false end -- print("改变了摄像机参数 ",state,self.maxSpeed) end function MainCamera:ChangePosFllowMainrole(pos_x,pos_y,jump_height) if SceneManager:getInstance():IsStarFightScene() then return end -- 以下是2D相机的逻辑 -- local radian = math.abs(self.rotate_around) % 180 / 180 * math.pi -- local asin = math.sin(radian) -- local acos = math.cos(radian) -- local x = math.abs(asin * CameraDistanceWithMainRole) -- local y = math.abs(acos * CameraDistanceWithMainRole) -- if self.rotate_around > 0 then -- if self.rotate_around < -270 then -- elseif self.rotate_around > 180 then -- y = -y -- elseif self.rotate_around > 90 then -- x = -x -- y = -y -- else -- x = -x -- end -- else -- if self.rotate_around < -270 then -- x = -x -- elseif self.rotate_around < -180 then -- x = -x -- y = -y -- elseif self.rotate_around < -90 then -- y = -y -- end -- end -- 以上 -- if self.firstMove then -- self:UpdateCameraPosDirect(pos_x, pos_y,jump_height ) -- self.firstMove = false -- return -- end -- local mainrole_height = 0 -- local mainrole = Scene.Instance:GetMainRole() -- if mainrole then -- mainrole_height = mainrole.obj_pos_height -- end -- -- self.smoothTarget.x = pos_x / MainCamera.PixelsToUnits; --transform.x -- -- self.smoothTarget.y = pos_y / MainCamera.PixelsToUnits --transform.z -- -- local off_height = jump_height / MainCamera.PixelsToUnits -- -- self.smoothTarget.z = SceneCameraHeigth + mainrole_height + off_height--transform.y -- local x = pos_x / MainCamera.PixelsToUnits; --transform.x -- local y = pos_y / MainCamera.PixelsToUnits --transform.z -- local off_height = jump_height / MainCamera.PixelsToUnits -- local z = SceneCameraHeigth + mainrole_height + off_height--transform.y -- self.smoothTarget = Vector3(x,y,z) if self.isSmooth and not self.block_smooth then self.isSmoothing = true else self.isSmoothing = false end self:UpdateCameraPosDirect(pos_x, pos_y,jump_height ) --MainCamera.Instance:SetCameraSize(MainCamera.Instance.camera_base_size * (1 + jump_height * 0.0011)) end function MainCamera:SmoothPosToTarget() if not self.smoothTarget then return end if not self.isSmoothing then return end -- if SceneManager:getInstance():IsStarFightScene() then -- return -- end local abs = math_abs(self.targetSmoothSpeed - self.maxSpeed) if abs > 0.01 then if self.targetSmoothSpeed >= self.maxSpeed then self.maxSpeed = self.maxSpeed + 0.01 else self.maxSpeed = self.maxSpeed - 0.01 end end local distance = Vector3.Distance(self.transform.position,self.smoothTarget) if distance < 0.01 then self.isSmoothing = false return end if distance > self.maxDistance * 2 then --超过最大距离的两倍,就不缓动了 self.transform.position = self.smoothTarget GlobalEventSystem:Fire(SceneEventType.CAMERA_MOVE) return end local temp_fps = 60 if LuaFPS.FPS and LuaFPS.FPS ~= 0 then temp_fps = LuaFPS.FPS end local real_max_speed = 60/temp_fps * self.maxSpeed local speed = distance/self.maxDistance * real_max_speed speed = self:GetClamp(speed,-real_max_speed,real_max_speed) local nextStep = Vector3.MoveTowards(self.transform.position,self.smoothTarget,speed) SetGlobalPosition3D(self.transform, nextStep.x, nextStep.z,nextStep.y) GlobalEventSystem:Fire(SceneEventType.CAMERA_MOVE) end function MainCamera:GetClamp(value,min,max) if value < min then return min end if value > max then return max end return value end function MainCamera:Distance(value1,value2) return math.sqrt(math.pow(2,(value1.x - value2.x)) + math.pow(2,(value1.y - value2.y)) + math.pow(2,(value1.z - value2.z))) end function MainCamera:GetNameBoardPoint( x,y,z ) local pos = self.camera:WorldToScreenPoint(Vector3(x,y,z)) pos = self.uiCamera:ScreenToWorldPoint(pos) return pos end function MainCamera:CreateScreenCamera() local screencameraobj = GameObject.New("ScreenCamera") screencameraobj:AddComponent(typeof(UnityEngine.Camera)) screencameraobj.layer = LayerMask.NameToLayer("Screen") self.screencamera = screencameraobj:GetComponent("Camera") self.screencamera.depth = 0 self.screencamera.cullingMask = 2048 self.screencamera.clearFlags = UnityEngine.CameraClearFlags.Depth self.screencamera.orthographic = false self.screencamera.transform:SetParent(self.transform) self.screencamera.fieldOfView = self.camera_curr_size self.screencamera.transform.localRotation = Quaternion.Euler(SceneCameraRotate,0,0) SetLocalPosition(self.screencamera.transform,0,0,-CameraDistanceWithMainRole) end function MainCamera:AddScreenObj( transform ) do return end if tonumber(AppConst.EnglineVer) <= 72 then return end if not self.screencamera then self:CreateScreenCamera() end if self.screen_obj_count == 0 then self.screencamera.gameObject:SetActive(true) end self.screen_obj_count = self.screen_obj_count + 1 local layer = LayerMask.NameToLayer("Screen") self:SetCustomLayer(transform,layer) end function MainCamera:RemoveScreenObj( transform ) do return end if not self.screencamera then return end self.screen_obj_count = self.screen_obj_count - 1 local layer = LayerMask.NameToLayer("Default") self:SetCustomLayer(transform,layer) if self.screen_obj_count <= 0 then self.screencamera.gameObject:SetActive(false) end end function MainCamera:HideScreenCamera() self.screen_obj_count = 0 if self.screencamera and self.screencamera.gameObject.activeSelf then self.screencamera.gameObject:SetActive(false) end end function MainCamera:SetCustomLayer( obj, layer ) if IsNull(obj) then return end for i = 0,obj.childCount - 1 do obj:GetChild(i).gameObject.layer = layer self:SetCustomLayer(obj:GetChild(i),layer) end end function MainCamera:AddSelectRoleMode() self.can_scale_camera = false SetGlobalPosition(self.transform, 0, 0, 0) SetGlobalPosition(self.camera.transform, -0.14, 0.965, -4.83) self.camera.transform.localRotation = Quaternion.Euler(-1.50,-3.47,0) self.camera.fieldOfView = 30 end function MainCamera:AddCreateRoleMode( ) self.can_scale_camera = false SetGlobalPosition(self.transform, 0, 0, 0) SetGlobalPosition(self.camera.transform, -0.14, 0.965, -4.83) self.camera.transform.localRotation = Quaternion.Euler(-1.50,-3.47,0) self.camera.fieldOfView = 30 end function MainCamera:ResetNormalMode() self:RecoverCameraParm() self.can_scale_camera = true SetLocalPosition(self.camera.transform, 0, 0, -CameraDistanceWithMainRole) self.camera.transform.localRotation = Quaternion.Euler(SceneCameraRotate,0,0) self.camera.fieldOfView = self.camera_curr_size end function MainCamera:BackupCameraParm( ) if self.has_backup then return end self.backup_distance = CameraDistanceWithMainRole self.backup_rotate_x = SceneCameraRotate self.backup_field = self.camera_curr_size self.backup_height = SceneCameraHeigth self.has_backup = true end function MainCamera:RecoverCameraParm( ) if not self.backup_distance then return end CameraDistanceWithMainRole = self.backup_distance SceneCameraRotate = self.backup_rotate_x self.camera_curr_size = self.backup_field SceneCameraHeigth = self.backup_height self.has_backup = false end function MainCamera:SetSpecialDunMode( cfg ) -- self:SetUpdateCameraEnabled(false) self:BackupCameraParm() CameraDistanceWithMainRole = cfg.distance SceneCameraRotate = cfg.rotate self.camera_curr_size = cfg.field SceneCameraHeigth = cfg.height self:ChangeSmoothState(MainCamera.SmoothState.SpecialDun) self:SetUpdateCameraEnabled(true) self.transform.localRotation = Quaternion.Euler(0,cfg.angle,0) self:UpdateCameraPosByMainRole() end function MainCamera:QuitSpecialDunMode( ) self:SetUpdateCameraEnabled(true) self:ResetNormalMode() self:UpdateCameraPosByMainRole() end function MainCamera:SetFishingCameraPos( angle) --self:SetRoleDirection() self:SetUpdateCameraEnabled(false) local x, y, z = 0, 0, 0 x, z = Scene.Instance.main_role:GetRealPos() x = x / MainCamera.PixelsToUnits z = z / MainCamera.PixelsToUnits y = self.transform.position.y - Config.ConfigFishSceneCamera.height SetGlobalPosition(self.transform, x, y, z) self.camera.transform.localRotation = Quaternion.Euler(Config.ConfigFishSceneCamera.rotate,0,0) self.transform.localRotation = Quaternion.Euler(0,angle,0) end function MainCamera:SetMateCamera(pos_x,pos_y,type_id ) self:SetUpdateCameraEnabled(false) -- if type_id == "x" then if true then self:SetPos( pos_x, pos_y + 700,-800) self.camera.transform.localRotation = Quaternion.Euler(13,0,0) elseif type_id == "y" then self.camera.transform.localRotation = Quaternion.Euler(13,-90,0) self:SetPos( pos_x+600, pos_y + 1300,-800) end end function MainCamera:QuitMateCamera( ) self:SetUpdateCameraEnabled(true) self:ResetNormalMode() self:UpdateCameraPosByMainRole() end function MainCamera:SetCameraMoveToZ( cfg ) if not cfg then return end if self.time_id then GlobalTimerQuest:CancelQuest(self.time_id) self.time_id = nil end local z = cfg.distance local animation_time = cfg.time or 1 local time, step = 0, 0.02 local function Move( ) time = time + step if time >= animation_time then if self.time_id then GlobalTimerQuest:CancelQuest(self.time_id) self.time_id = nil end else local now_pos = GameMath_Lerp(self.camera.transform.localPosition.z, z, time/animation_time) SetLocalPosition(self.camera.transform, 0, 0, now_pos) GlobalEventSystem:Fire(SceneEventType.CAMERA_MOVE) end end self.time_id = GlobalTimerQuest:AddPeriodQuest(Move,0.02,-1) end function MainCamera:ResetExitFishCameraPos() local cfg = Config.ConfigFishSceneCamera if not cfg then return end if self.time_id then GlobalTimerQuest:CancelQuest(self.time_id) self.time_id = nil end self:SetUpdateCameraEnabled(true) self.camera.transform.localRotation = Quaternion.Euler(SceneCameraRotate,0,0) self.transform.localRotation = Quaternion.Euler(0,0,0) if Scene.Instance.main_role then local x, y, z = 0, 0, 0 x, z = Scene.Instance.main_role:GetRealPos() x = x / MainCamera.PixelsToUnits z = z / MainCamera.PixelsToUnits y = self.transform.position.y + cfg.height SetGlobalPosition(self.transform, x, y, z) SetLocalPosition(self.camera.transform, 0, 0, -CameraDistanceWithMainRole) end end --更改渲染层级 function MainCamera:SetMainCameraCullingMask( layer, flag ) if not self.camera then return end if flag then self.camera.cullingMask = bit.bor(self.camera.cullingMask, bit.lshift(1,layer)) else self.camera.cullingMask = bit.band(self.camera.cullingMask, bit.bnot(bit.lshift(1,layer))) end end --切换泛光效果开关 function MainCamera:SetPostEffectEnable( flag ) if self.is_login_post_effect_state then return end if not IsNull(self.main_postEffect) and self:IsSupportPostEffect() then self.main_postEffect.enabled = flag end end function MainCamera:IsSupportPostEffect( ) -- if G_DEBUG_MODE then -- return false -- end if self.is_support_post_effect ~= nil then return self.is_support_post_effect end self.is_support_post_effect = SystemMemoryLevel.Cur == SystemMemoryLevel.Top return self.is_support_post_effect end function MainCamera:IsSupportFAXX( ) if G_DEBUG_MODE then return false end if self.is_support_faxx ~= nil then return self.is_support_faxx end self.is_support_faxx = SystemMemoryLevel.Cur == SystemMemoryLevel.Hight return self.is_support_faxx end --------------------------------------------屏幕后处理相关start-------------------------------------------- -- 获取当前设备是否支持使用屏幕后处理特效 function MainCamera:SetRenderSupport( ) self.is_screen_effect_supported = self.main_postEffect and self.main_postEffect:GetSupported() or false -- and self.ui_postEffect and self.ui_postEffect:GetSupported() end function MainCamera:GetRenderSupport( ) return self.is_screen_effect_supported end --------------------------------------------高斯模糊相关start-------------------------------------------- -- 启用主摄像机和UI摄像机的渲染截图 camera_type:特效相机类型,默认模糊UI摄像机 anim_time:模糊动画时间 -- function MainCamera:EnableBlurEffect(camera_type, anim_time) -- local top_canvas_node = panelMgr:GetParent("Top"):GetComponent("Canvas") -- if not top_canvas_node then return end -- -- 已经存在了进行模糊的摄像机时,直接跳过 -- if MainCamera.Activiting_Blur_Effect then return end -- camera_type = camera_type or MainCamera.EffectCameraType.UICamera -- -- 将TopUI层的渲染摄像机改为不参与模糊的摄像机 -- top_canvas_node.worldCamera = self.blurCamera -- self.blurCamera.enabled = true -- self.blurCamera_gameObject.transform.localRotation = Quaternion.Euler(0,0,0) -- if camera_type == MainCamera.EffectCameraType.MainCamera then -- -- self.main_screen_effect.enabled = true -- -- self.main_screen_effect.render_blur_effect = true -- self.main_postEffect.render_blur_effect = true -- MainCamera.Activiting_Blur_Effect = true -- elseif camera_type == MainCamera.EffectCameraType.UICamera then -- -- self.ui_screen_effect.enabled = true -- -- self.ui_screen_effect.render_blur_effect = true -- self.ui_postEffect.render_blur_effect = true -- MainCamera.Activiting_Blur_Effect = true -- end -- -- 启用渐变动画效果 -- self:StartBlurAmountBlend(true, anim_time) -- end -- -- 关闭模糊效果 -- function MainCamera:DisableBlurEffect(anim_time) -- if not MainCamera.Activiting_Blur_Effect then return end -- self:StartBlurAmountBlend(false, anim_time) -- MainCamera.Activiting_Blur_Effect = false -- end -- -- 关闭模糊脚本运作 -- function MainCamera:ShutDownBlurEffect( ) -- if self.main_postEffect then -- self.main_postEffect.render_blur_effect = false -- end -- if self.ui_postEffect then -- self.ui_postEffect.render_blur_effect = false -- end -- -- 将Top层的UI渲染摄像机还原为UIcamera -- local top_canvas_node = panelMgr:GetParent("Top"):GetComponent("Canvas") -- if top_canvas_node then -- top_canvas_node.worldCamera = self.uiCamera -- self.blurCamera.enabled = false -- end -- end -- -- 模糊效果缓动 show 显示模糊或者关闭模糊 anim_time 缓动时间 -- function MainCamera:StartBlurAmountBlend(show, anim_time) -- -- 获取当前激活渲染效果的摄像机 -- local anim_camera = self.main_postEffect.render_blur_effect and self.main_postEffect or nil -- anim_camera = anim_camera or (self.ui_postEffect.render_blur_effect and self.ui_postEffect) -- if not anim_camera then return end -- self:ClearBlurAnimId() -- -- 目标模糊混合值 -- local target_amount = show and 1 or 0 -- local start_amount = show and 0 or 1 -- -- 目标降低采样率值 -- local max_downSample = anim_camera == self.main_postEffect and -- self.main_blur_downSample_value or self.ui_blur_downSample_value -- local target_downSample = show and max_downSample or 1 -- local start_downSample = show and 1 or max_downSample -- local anim_time = anim_time or 0.3 -- local downSample_time = anim_time * (target_downSample-1)/target_downSample -- -- 如果是要显示出来,则先从原始图片渐变到模糊图片 -- local callback = nil -- if show and anim_time ~= 0 then -- anim_camera.blur_amount = 0 -- anim_camera.downSample = 1 -- end -- -- 添加动画(2019年11月16日修改:修改动画参数,增强模糊动画效果,代码参考tweenlite) -- if anim_time ~= 0 then -- local start_time = Status.NowTime -- local function blur_anim_func() -- local use_time = Status.NowTime - start_time -- local progress = use_time / anim_time -- anim_camera.blur_amount = use_time >= anim_time and target_amount or GameMath_Lerp(start_amount, target_amount, progress) -- anim_camera.downSample = use_time >= downSample_time and target_downSample or GameMath_Lerp(start_downSample, target_downSample, progress) -- if use_time >= anim_time then -- self:ClearBlurAnimId() -- if not show then -- self:ShutDownBlurEffect() -- end -- end -- end -- self.blur_anim_func_id = GlobalTimerQuest:AddPeriodQuest(blur_anim_func, 0.03, -1) -- blur_anim_func() -- else -- anim_camera.blur_amount = target_amount -- anim_camera.downSample = max_downSample -- if not show then -- self:ShutDownBlurEffect() -- end -- end -- end -- function MainCamera:ClearBlurAnimId( ) -- if self.blur_anim_func_id then -- GlobalTimerQuest:CancelQuest(self.blur_anim_func_id) -- self.blur_anim_func_id = nil -- end -- end -- 直接获取当前目标摄像机的模糊效果(目前模糊样式固定,且直接获取模糊后的图) -- callback:必传,第一个参数一定是接收RenderTexture -- camera_type:模糊摄像机格式,默认是UI摄像机 -- function MainCamera:GetCameraBlurScreenShot(callback, camera_type) -- if not callback then -- 没有回调,则读取缓存,并跳出本轮模糊 -- self:CheckCacheBlurList() -- return -- end -- -- 当前正在等待处理的话,则缓存列表 -- if self.rendering_blur_screenShot then -- self.round_robin_cache_list[#self.round_robin_cache_list+1] = { -- callback = callback, -- camera_type = camera_type, -- } -- return -- end -- camera_type = camera_type or MainCamera.EffectCameraType.UICamera -- local target_effect, max_downSample -- if camera_type == MainCamera.EffectCameraType.MainCamera then -- target_effect = self.main_postEffect -- max_downSample = self.main_blur_downSample_value -- elseif camera_type == MainCamera.EffectCameraType.UICamera then -- target_effect = self.ui_postEffect -- max_downSample = self.ui_blur_downSample_value -- end -- local function screenshot_callback(args) -- -- 首个参数既是RenderTexture -- callback(args and args[0]) -- -- 状态置false,检查缓存队列中是否有其他模糊请求 -- self.rendering_blur_screenShot = false -- self:CheckCacheBlurList() -- end -- target_effect:RenderBlurScreenShot(1, max_downSample, screenshot_callback) -- self.rendering_blur_screenShot = true -- end -- -- 缓存模糊需求列表 -- function MainCamera:CheckCacheBlurList( ) -- if TableSize(self.round_robin_cache_list) == 0 then return end -- if self.check_blur_delay_id then -- GlobalTimerQuest:CancelQuest(self.check_blur_delay_id) -- self.check_blur_delay_id = nil -- end -- local function delay_method( ) -- local data = table.remove(self.round_robin_cache_list, 1) -- if data then -- self:GetCameraBlurScreenShot(data.callback, data.camera_type) -- end -- end -- -- 下一帧再读取缓存 -- self.check_blur_delay_id = setTimeout(delay_method, 0.01) -- end -- -- 释放RT缓存 -- function MainCamera:ClearScreenShotCache(rt) -- if not IsNull(rt) then -- ReleaseTemporary(rt) -- end -- end -- -- (测试用)切换模糊截屏渲染模式 -- function MainCamera:SwitchToDualBlur(camera_type, use_dual_blur) -- camera_type = camera_type or MainCamera.EffectCameraType.UICamera -- local target_effect, max_downSample, recurveMaxNum, blurSpread -- -- 根据不同的采样shader选取不一样的默认参数 -- max_downSample = use_dual_blur and 5 or 4 -- recurveMaxNum = use_dual_blur and 3 or 4 -- blurSpread = use_dual_blur and 5 or 1 -- if camera_type == MainCamera.EffectCameraType.MainCamera then -- target_effect = self.main_postEffect -- self.main_blur_downSample_value = max_downSample -- elseif camera_type == MainCamera.EffectCameraType.UICamera then -- target_effect = self.ui_postEffect -- self.ui_blur_downSample_value = max_downSample -- end -- target_effect.use_dual_blur = use_dual_blur -- target_effect.downSample = max_downSample -- target_effect.blurSpread = blurSpread -- target_effect.recurveMaxNum = recurveMaxNum -- end --------------------------------------------高斯模糊相关end-------------------------------------------- --------------------------------------------屏幕后处理相关end-------------------------------------------- function MainCamera:ShowBlackSky( sky_res, target_alpha, step_alpha) if self.is_showing_sky_res then return end self.is_showing_sky_res = true local target_alpha = target_alpha local step_alpha = step_alpha local is_need_alpha = false if target_alpha and step_alpha then is_need_alpha = true end self.black_sky_res = sky_res or "mrsd_skills_skybox01" local function load_call_back( objs, is_gameObject ) if not objs or not objs[0] then return end if self.black_sky_obj then destroy(self.black_sky_obj) end self.black_sky_obj = is_gameObject and objs[0] or newObject(objs[0]) self.black_sky_transform = self.black_sky_obj.transform self.black_sky_transform:SetParent(self.transform) self.black_sky_transform.localScale = Vector3.one self.black_sky_transform.localPosition = Vector3.zero self.black_sky_renders = self.black_sky_obj:GetComponentsInChildren(typeof(UnityEngine.MeshRenderer)) if is_need_alpha then self.cur_terrain_alpha = self.cur_terrain_alpha or 1 local function on_alpha_callback( ) self:SetMainCameraCullingMask(UIPartical.RenderingOther_List.Ground, false) self:SetMainCameraCullingMask(UIPartical.RenderingOther_List.Reflection, false) end self:StartTerrainAlphaTimer(self.cur_terrain_alpha, target_alpha, step_alpha, on_alpha_callback) else self:SetMainCameraCullingMask(UIPartical.RenderingOther_List.Ground, false) self:SetMainCameraCullingMask(UIPartical.RenderingOther_List.Reflection, false) end end LuaResManager:getInstance():loadPrefab(self, self.black_sky_res, self.black_sky_res, load_call_back, false) end function MainCamera:HideBlackSky( sky_res, target_alpha, step_alpha) if self.terrain_alpha_timer then GlobalTimerQuest:CancelQuest(self.terrain_alpha_timer) self.terrain_alpha_timer = nil end if not self.black_sky_obj then return end local target_alpha = target_alpha local step_alpha = step_alpha local is_need_alpha = false if target_alpha and step_alpha then is_need_alpha = true end local function on_hide_callback( ) if self.black_sky_obj then if self.black_sky_res and sky_res == self.black_sky_res then lua_resM:AddObjToPool(self, self.black_sky_res, self.black_sky_res, self.black_sky_obj) else destroy(self.black_sky_obj) end self.black_sky_obj = nil self.black_sky_transform = nil end self.is_showing_sky_res = false end if is_need_alpha then self:SetMainCameraCullingMask(UIPartical.RenderingOther_List.Ground, true) self:SetMainCameraCullingMask(UIPartical.RenderingOther_List.Reflection, true) self.cur_terrain_alpha = self.cur_terrain_alpha or 0 self:StartTerrainAlphaTimer(self.cur_terrain_alpha, target_alpha, step_alpha, on_hide_callback) else on_hide_callback() self:SetMainCameraCullingMask(UIPartical.RenderingOther_List.Ground, true) self:SetMainCameraCullingMask(UIPartical.RenderingOther_List.Reflection, true) end end function MainCamera:StartTerrainAlphaTimer(cur_value, target_value, step_alpha, call_back) if self.terrain_alpha_timer then GlobalTimerQuest:CancelQuest(self.terrain_alpha_timer) self.terrain_alpha_timer = nil end local cur_alpha = cur_value or 0 step_alpha = step_alpha or 0.02 local target_value = target_value or 1 local is_add = cur_alpha < target_value local function on_step( ) cur_alpha = is_add and cur_alpha + step_alpha or cur_alpha - step_alpha self.cur_terrain_alpha = cur_alpha local is_finish = false if is_add then is_finish = cur_alpha >= target_value else is_finish = cur_alpha <= target_value end if is_finish then if self.terrain_alpha_timer then GlobalTimerQuest:CancelQuest(self.terrain_alpha_timer) self.terrain_alpha_timer = nil end self:SetTerrainAlpha(target_value) if call_back then call_back() end else self:SetTerrainAlpha(cur_alpha) end end self.terrain_alpha_timer = GlobalTimerQuest:AddPeriodQuest(on_step, 0.02, -1) on_step() end function MainCamera:SetTerrainAlpha( value ) self.cur_terrain_alpha = value Shader.SetGlobalFloat("_GlobalSceneAlpha", value) end function MainCamera:GetMovieCamera( ) if not self.story_camera then self.story_camera = self.story_cam_obj:GetComponent("Camera") end self.story_camera.fieldOfView = self.camera_curr_size self.story_camera.transform.localRotation = Quaternion.Euler(SceneCameraRotate,0,0) SetLocalPosition(self.story_camera.transform,0,0,-CameraDistanceWithMainRole) return self.story_cam_obj, self.story_camera end function MainCamera:AddCameraAction( ab_name, res_name, action_name, call_back ) local function load_finish_func(objs, is_gameObject) if not objs or not objs[0] then return end local main_role = Scene.Instance:GetMainRole() if main_role and not main_role:IsInState(PoseState.STORY) then return end local temp_controller = objs[0] if not self.story_camera then self.story_camera = self.story_cam_obj:GetComponent("Camera") self.story_camera.enabled = true end self.story_camera.fieldOfView = 22 self.story_camera.depth = 6 self.story_cam_obj.transform.localRotation = Quaternion.Euler(0,0,0) SetLocalPosition(self.story_cam_obj.transform,0,0,0) self.story_cam_obj:SetActive(true) if not self.camera_animator then self.camera_animator = self.story_cam_obj:AddComponent(typeof(UnityEngine.Animator)) end self.camera_animator.runtimeAnimatorController = temp_controller self.camera_animator:CrossFade(action_name, 0) if call_back then call_back() end end lua_resM:loadObject(self, ab_name, res_name, load_finish_func) end function MainCamera:RemoveCameraAction( ) if self.camera_animator then destroy(self.camera_animator) self.camera_animator = false end if self.story_cam_obj then SetLocalPosition(self.story_cam_obj.transform, 0, 0, 0) self.story_cam_obj.transform.localRotation = Quaternion.Euler(0,0,0) end if self.story_cam_obj then self.story_cam_obj:SetActive(false) end end --------------------- 剧情摄像机径向模糊相关 start --------------------- -- 启动径向模糊 function MainCamera:EnableStoryCameraRadiusBlur(show) if self.story_radiusBlur then self.story_radiusBlur.enabled = show return true end return false end -- 设置径向模糊的中心点和模糊半径 中心点坐标范围0~1 模糊半径范围 0~0.03 function MainCamera:SetStoryCameraRadiusData(centerX, centerY, radius_offset) if self.story_radiusBlur then -- 获取默认值 local cur_blurData = self.story_radiusBlur.radius_data centerX = centerX or cur_blurData.x Clamp(centerX, 0, 1) centerY = centerY or cur_blurData.y Clamp(centerY, 0, 1) radius_offset = radius_offset or cur_blurData.z Clamp(radius_offset, 0, 0.03) self.story_radiusBlur.radius_data = Vector3(centerX, centerY, radius_offset) end end -- 设置径向模糊的迭代次数 function MainCamera:SetStoryCameraRadiusIteration(iteration) if self.story_radiusBlur then -- 获取默认值 local cur_iteration = self.story_radiusBlur.iteration iteration = iteration or cur_iteration Clamp(iteration, 1, 30) self.story_radiusBlur.iteration = iteration end end --------------------- 剧情摄像机径向模糊相关 end --------------------- function MainCamera:ResetAutoRotateInfo( ) MainCamera.role_last_angle = 0 MainCamera.role_cur_angle = 0 MainCamera.role_angle_off = 0 MainCamera.role_from_camera_angle = 0 MainCamera.role_last_rotate_area = false MainCamera.camera_cur_angle = 0 MainCamera.camera_target_angle = 0 MainCamera.camera_enable_rotate = false if not IsNull(self.transform) then SetLocalRotation(self.transform) end end