源战役客户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

394 lines
17 KiB

-- <*
-- @Author: Saber
-- @Description: 发行需求:全自由摄像机
-- *>
CheatFreeCameraView = CheatFreeCameraView or BaseClass(BaseView)
local CheatFreeCameraView = CheatFreeCameraView
local math_random = math.random
local Clamp = Mathf.Clamp
function CheatFreeCameraView:__init()
self.base_file = "cheat"
self.layout_file = "CheatFreeCameraView"
self.layer_name = "Top"
self.destroy_imm = true
self.use_background = false --全屏界面默认使用这个参数,非全屏界面自行设置
self.is_show = true
self.mc_camera = nil -- 主摄像机组件
self.mc_trans = nil -- 主摄像机transform
self.mc_node_trans = nil -- 主摄像机父节点transform
self.mc_offset = Vector3(0, 0, 12) -- 主摄像机的节点内偏移
self.main_role = Scene.Instance:GetMainRole()
-- 参数相关
self.view_mask_last_pos = Vector2(0, 0) -- 摄像机视角点击UV位置
self.view_asix_speed = 0.1 -- 摄像机轴移动速度
self.move_mask_start_pos = Vector2(0, 0) -- 摄像机移动起始点击UV位置
self.move_input = Vector2(0, 0) -- 摄像机自由移动输入方向
self.cam_move_speed = 0.2 -- 摄像机轴移动速度
self.cam_asix_radius = 50 -- 滑动移动轴半径
self.can_auto_round = false -- 是否可以自动环绕
self.auto_rotate_speed = 0 -- 自动环绕速度
self.camera_radius = 5 -- 摄像机定位半径
self.height_offset = 2 -- 摄像机Z轴offset
self.show_main_canvas_flag = true -- 显示主界面canvas
self.fixed_relative_camera_pos = nil -- 跟随移动时的相对摄像机位置
self.load_callback = function ()
self:LoadSuccess()
self:AddEvent()
end
self.open_callback = function ( )
self:UpdateView()
end
self.destroy_callback = function ( )
self:DestroySuccess()
end
end
function CheatFreeCameraView:Open( )
MainCamera.FreeCameraViewOpened = true
BaseView.Open(self)
end
function CheatFreeCameraView:LoadSuccess()
local nodes = {
"free_camera_view_mask:obj", -- 全自动摄像机视角方向mask
"free_camera_move_mask:obj", -- 全自动摄像机移动mask
"closeBtn:obj",
"hideBtn:obj",
-- 自动操作按钮
"front_btn:obj", -- 主角正向
"back_btn:obj", -- 主角背面
"random_btn:obj", -- 主角随机环绕角度
"auto_round_btn:obj", -- 主角自动环绕
}
self:GetChildren(nodes)
-- 主摄FOV
self.main_cam_fov_sl = self:GetChild("main_cam_fov/main_cam_fov_sl"):GetComponent("Slider")
self.main_cam_fov_val = self:GetChild("main_cam_fov/main_cam_fov_val"):GetComponent(typeof(TMPro.TextMeshProUGUI))
-- 摄像机自动环绕速度
self.auto_round_sl = self:GetChild("auto_round/auto_round_sl"):GetComponent("Slider")
self.auto_round_val = self:GetChild("auto_round/auto_round_val"):GetComponent(typeof(TMPro.TextMeshProUGUI))
-- 摄像机定位半径
self.radius_sl = self:GetChild("radius/radius_sl"):GetComponent("Slider")
self.radius_val = self:GetChild("radius/radius_val"):GetComponent(typeof(TMPro.TextMeshProUGUI))
-- 摄像机Z轴offset
self.height_offset_sl = self:GetChild("height_offset/height_offset_sl"):GetComponent("Slider")
self.height_offset_val = self:GetChild("height_offset/height_offset_val"):GetComponent(typeof(TMPro.TextMeshProUGUI))
-- 全自由摄像机
self.free_camera_tog = self:GetChild("free_camera"):GetComponent("Toggle")
-- 显示mainCanvas
self.show_main_canvas_tog = self:GetChild("show_main_canvas"):GetComponent("Toggle")
SetSizeDelta(self.free_camera_view_mask, ScreenWidth / 2, ScreenHeight)
SetSizeDelta(self.free_camera_move_mask, ScreenWidth / 2, ScreenHeight)
SetAnchoredPositionX(self.free_camera_move_mask, -366 - ScreenWidth / 2)
SetAnchoredPosition(self.transform, -ClientConfig.iphone_x_offset_right, 0)
end
function CheatFreeCameraView:AddEvent()
local function onOrientationChange()
SetAnchoredPosition(self.transform, -ClientConfig.iphone_x_offset_right, 0)
end
self:BindEvent(GlobalEventSystem, EventName.ORIENTATION_DID_CHANGE, onOrientationChange)
local function click_event(target)
if target == self.closeBtn_obj then -- 关闭界面
local function ok( ... )
self:Close()
end
local ask_str = "(防止点错)是否确定关闭测试界面?"
Alert.show(ask_str, Alert.Type.Two, ok, nil, "确定", "不不不我这是乱点的")
elseif target == self.hideBtn_obj then -- 隐藏界面
self:HideAction(not self.is_show)
elseif target == self.free_camera_tog.gameObject then -- 全自由摄像机,是则打开操作mask
local isOn = self.free_camera_tog.isOn
self.free_camera_move_mask_obj:SetActive(isOn)
self.free_camera_view_mask_obj:SetActive(isOn)
-- 如果使用全自由摄像机,那就要强制关闭自动环绕
self.can_auto_round = self.can_auto_round and not isOn
elseif target == self.show_main_canvas_tog.gameObject then -- 是否显示主界面UI
self.show_main_canvas_flag = self.show_main_canvas_tog.isOn
self:ShowMainCanvas()
elseif target == self.front_btn_obj then -- 摄像机朝向主角正面
-- 强制关闭自动环绕
self.can_auto_round = false
self:SetCameraLookAtRoleFront()
elseif target == self.back_btn_obj then -- 摄像机朝向主角背面
-- 强制关闭自动环绕
self.can_auto_round = false
self:SetCameraLookAtRoleBack()
elseif target == self.random_btn_obj then -- 摄像机随机角度于主角
-- 强制关闭自动环绕
self.can_auto_round = false
self:SetCameraLookAtRoleWithRandomAngle()
elseif target == self.auto_round_btn_obj then -- 摄像机自动环绕主角
self:SetCameraAutoRotateAroundRole()
-- 自动环绕要关闭全自由摄像机
self.free_camera_tog.isOn = false
self.free_camera_move_mask_obj:SetActive(false)
self.free_camera_view_mask_obj:SetActive(false)
end
end
AddClickEvent(self.closeBtn_obj, click_event)
AddClickEvent(self.hideBtn_obj, click_event)
AddClickEvent(self.free_camera_tog.gameObject, click_event)
AddClickEvent(self.show_main_canvas_tog.gameObject, click_event)
AddClickEvent(self.front_btn_obj, click_event)
AddClickEvent(self.back_btn_obj, click_event)
AddClickEvent(self.random_btn_obj, click_event)
AddClickEvent(self.auto_round_btn_obj, click_event)
local function onSliderDrag(target)
local value = target:GetComponent("Slider").value
if target == self.main_cam_fov_sl.gameObject then
self.main_cam_fov_val.text = value
if self.mc_camera then
self.mc_camera.fieldOfView = value
end
elseif target == self.auto_round_sl.gameObject then
self.auto_round_val.text = tonumber(string.format("%.2f", value))
self.auto_rotate_speed = value
elseif target == self.radius_sl.gameObject then
self.radius_val.text = tonumber(string.format("%.2f", value))
self.camera_radius = value
elseif target == self.height_offset_sl.gameObject then -- z轴offset
self.height_offset_val.text = tonumber(string.format("%.2f", value))
self.height_offset = value
end
end
AddDragEvent(self.main_cam_fov_sl.gameObject, onSliderDrag)
AddDragEvent(self.auto_round_sl.gameObject, onSliderDrag)
AddDragEvent(self.radius_sl.gameObject, onSliderDrag)
AddDragEvent(self.height_offset_sl.gameObject, onSliderDrag)
-- 全自由摄像机转动
local function onPressViewMask(target, x, y)
self.view_mask_last_pos = Vector2(x, y)
end
local function onDragViewMask(target, x, y)
local pos_offset_x = x - self.view_mask_last_pos.x
local pos_offset_y = y - self.view_mask_last_pos.y
local angel_delta = Vector2(-pos_offset_y * self.view_asix_speed, pos_offset_x * self.view_asix_speed)
local cam_angel = self:GetCameraYEulerAngle()
local new_angle = Vector3(cam_angel.x + angel_delta.x, cam_angel.y + angel_delta.y, cam_angel.z)
self:SetCameraYEulerAngle(new_angle)
self.view_mask_last_pos = Vector2(x, y)
end
local function onExitViewMask(target)
self.view_mask_last_pos = Vector2(0, 0)
end
AddDragBeginEvent(self.free_camera_view_mask_obj, onPressViewMask)
AddDragEvent(self.free_camera_view_mask_obj, onDragViewMask)
AddDragEndEvent(self.free_camera_view_mask_obj, onExitViewMask)
-- 全自由摄像机移动
local function onPressMoveMask(target, x, y)
self.move_mask_start_pos = Vector2(x, y)
end
local function onDragMoveMask(target, x, y)
local pos_offset_x = x - self.move_mask_start_pos.x
local pos_offset_y = y - self.move_mask_start_pos.y
local input = Vector2(pos_offset_x, pos_offset_y) / self.cam_asix_radius
input.x = Clamp(input.x, -1, 1)
input.y = Clamp(input.y, -1, 1)
self.move_input = input
end
local function onExitMoveMask(target)
self.move_mask_start_pos = Vector2(0, 0)
self.move_input = Vector2(0, 0)
end
AddDragBeginEvent(self.free_camera_move_mask_obj, onPressMoveMask)
AddDragEvent(self.free_camera_move_mask_obj, onDragMoveMask)
AddDragEndEvent(self.free_camera_move_mask_obj, onExitMoveMask)
end
function CheatFreeCameraView:UpdateView()
self:GetMainCamera()
self:InitOptionsData()
self:HideAction(true)
self:BindCameraMoveEvent()
self:ShowMainCanvas()
end
-- 获取主摄像机
function CheatFreeCameraView:GetMainCamera( )
-- 获取摄像机
if not self.mc_camera or not self.mc_trans or not self.mc_node_trans then
self.mc_camera = MainCamera.Instance.camera
self.mc_trans = MainCamera.Instance.camera_gameObject.transform
self.mc_node_trans = MainCamera.Instance.transform
end
end
-- 初始化设置选项
function CheatFreeCameraView:InitOptionsData( )
self.main_cam_fov_sl.value = self.mc_camera.fieldOfView
self.main_cam_fov_val.text = self.mc_camera.fieldOfView
self.main_camera_fov = self.mc_camera.fieldOfView -- 用于复原摄像机
self.auto_round_sl.value = self.auto_rotate_speed
self.auto_round_val.text = self.auto_rotate_speed
self.radius_sl.value = self.camera_radius
self.radius_val.text = self.camera_radius
self.height_offset_sl.value = self.height_offset
self.height_offset_val.text = self.height_offset
self.show_main_canvas_tog.isOn = self.show_main_canvas_flag
end
-- 获取主角当前真实世界坐标
function CheatFreeCameraView:GetMainRoleRealWorldPos( )
return self.main_role.modelObj_transform.position + Vector3(0, self.height_offset, 0)
end
function CheatFreeCameraView:GetMainRoleForwardDir( )
return self.main_role.modelObj_transform.forward
end
function CheatFreeCameraView:GetMainRoleUpDir( )
return self.main_role.modelObj_transform.up
end
function CheatFreeCameraView:GetCameraYEulerAngle( )
return self.mc_trans.eulerAngles
end
function CheatFreeCameraView:SetCameraYEulerAngle(val)
self.mc_trans.rotation = Quaternion.Euler(val)
end
function CheatFreeCameraView:GetCameraForwardDir( )
return self.mc_trans.forward
end
function CheatFreeCameraView:GetCameraRightDir( )
return self.mc_trans.right
end
function CheatFreeCameraView:GetCameraNodePosition( )
return self.mc_node_trans.position
end
function CheatFreeCameraView:SetCameraNodePosition(val)
self.mc_node_trans.position = val
end
-- 摄像机位置按钮相关
-- 摄像机朝向主角正面
function CheatFreeCameraView:SetCameraLookAtRoleFront( )
local role_pos = self:GetMainRoleRealWorldPos()
local role_forward = self:GetMainRoleForwardDir()
local camera_pos = role_forward * self.camera_radius + role_pos + self.mc_offset
if self.mc_node_trans and self.mc_trans then
self.mc_node_trans.position = camera_pos
self.mc_trans:LookAt(role_pos)
end
end
-- 摄像机朝向主角背面
function CheatFreeCameraView:SetCameraLookAtRoleBack( )
local role_pos = self:GetMainRoleRealWorldPos()
local role_forward = self:GetMainRoleForwardDir()
local camera_pos = - role_forward * self.camera_radius + role_pos + self.mc_offset
if self.mc_node_trans and self.mc_trans then
self.mc_node_trans.position = camera_pos
self.mc_trans:LookAt(role_pos)
end
end
-- 摄像机随机角度于主角
function CheatFreeCameraView:SetCameraLookAtRoleWithRandomAngle( )
local role_pos = self:GetMainRoleRealWorldPos()
local role_forward = self:GetMainRoleForwardDir()
local role_up = self:GetMainRoleUpDir()
local random_angle = math_random(-180, 180)
local camera_pos = Quaternion.AngleAxis(random_angle, role_up) * role_forward * self.camera_radius + role_pos + self.mc_offset
if self.mc_node_trans and self.mc_trans then
self.mc_node_trans.position = camera_pos
self.mc_trans:LookAt(role_pos)
end
end
-- 摄像机自动环绕主角
function CheatFreeCameraView:SetCameraAutoRotateAroundRole( )
self.can_auto_round = true
self.last_node_time = Status.NowTime
local start_angle = 0
if not self.auto_rotate_camera_id then
local function auto_rotate()
if self.can_auto_round then
local role_pos = self:GetMainRoleRealWorldPos()
local role_forward = self:GetMainRoleForwardDir()
local role_up = self:GetMainRoleUpDir()
local past_time = Status.NowTime - self.last_node_time
local speed_per_frame = self.auto_rotate_speed / 30
start_angle = start_angle + speed_per_frame * past_time / 0.02
local camera_pos = Quaternion.AngleAxis(start_angle, role_up) *
role_forward * self.camera_radius + role_pos + self.mc_offset
if self.mc_node_trans and self.mc_trans then
self.mc_node_trans.position = camera_pos
self.mc_trans:LookAt(role_pos)
end
end
self.last_node_time = Status.NowTime
end
self.auto_rotate_camera_id = GlobalTimerQuest:AddPeriodQuest(auto_rotate, 0.02, -1)
end
end
function CheatFreeCameraView:HideAction(show)
self:StopHideAction()
self.is_show = show
self.hideBtn.transform.localRotation = Quaternion.Euler(Vector3(0, 0, self.is_show and 90 or 270))
local target_pos_x = (self.is_show and 0 or 366 ) - ClientConfig.iphone_x_offset_right
self.con_anim_id = TweenLite.to(self, self.transform, TweenLite.UiAnimationType.ANCHORED_POSX, target_pos_x, 0.3, nil, TweenFunc.EASE_OUT_QUINT)
end
function CheatFreeCameraView:StopHideAction( )
if self.con_anim_id then
TweenLite.Stop(self.con_anim_id)
SetAnchoredPositionX(self.transform, (self.is_show and 0 or 366) - ClientConfig.iphone_x_offset_right)
end
end
function CheatFreeCameraView:BindCameraMoveEvent( )
if not self.camera_move_event_id then
local function camera_move_func()
if self.free_camera_tog.isOn then
self.fixed_relative_camera_pos = nil
if self.move_input.x ~= 0 or self.move_input.y ~= 0 then
local input = self.move_input
local forward_dir = self:GetCameraForwardDir()
local right_dir = self:GetCameraRightDir()
local cur_pos = self:GetCameraNodePosition()
local new_pos = cur_pos + forward_dir * input.y * self.cam_move_speed + right_dir * input.x * self.cam_move_speed
self:SetCameraNodePosition(new_pos)
end
else
if not self.fixed_relative_camera_pos then
self.fixed_relative_camera_pos = self:GetCameraNodePosition() - self:GetMainRoleRealWorldPos()
end
self:SetCameraNodePosition(self:GetMainRoleRealWorldPos() + self.fixed_relative_camera_pos)
end
end
self.camera_move_event_id = GlobalTimerQuest:AddPeriodQuest(camera_move_func, 0.02, -1)
end
end
function CheatFreeCameraView:ShowMainCanvas( )
panelMgr:GetParent("Main").gameObject:SetActive(self.show_main_canvas_flag)
panelMgr:GetParent("NameBoard").gameObject:SetActive(self.show_main_canvas_flag)
panelMgr:GetParent("Dynamic_NameBoard").gameObject:SetActive(self.show_main_canvas_flag)
end
function CheatFreeCameraView:DestroySuccess( )
self:StopHideAction()
if self.auto_rotate_camera_id then
GlobalTimerQuest:CancelQuest(self.auto_rotate_camera_id)
self.auto_rotate_camera_id = nil
end
if self.camera_move_event_id then
GlobalTimerQuest:CancelQuest(self.camera_move_event_id)
self.camera_move_event_id = nil
end
-- 复原摄像机
if self.mc_camera then
self.mc_camera.fieldOfView = self.main_camera_fov
end
self.mc_trans.localRotation = Quaternion.Euler(SceneCameraRotate,0,0)
MainCamera.FreeCameraViewOpened = false
end