unityzgy/Assets/Scripts/PublicTool/CameraCtrl.cs
ayuan9957 bf12e02276 feat: 多语言本地化系统 - 支持中/英/法/俄实时切换
- LocalizationManager: 新增翻译表(SetFormatted/SetDuration/LocalizeOperateMsg)
- LoginPanel: InputField placeholder本地化、字体颜色保持
- HistoryPanel: 用时数据本地化、placeholder本地化
- RecordDetailPanel: 操作详情消息本地化(LanguageChanged重建)
- AppraiseWindowBase: 评价等级本地化、操作消息重建
- EditorAppraiser: 所有评估消息改用InjectOperateMsgLocalized
- StudentOperateRecorder: 新增InjectOperateMsgLocalized方法
- LocalizationLanguageTestBar: 单例模式、ScreenSpaceOverlay筛选
- 字体切换时保留颜色和verticalOverflow
2026-07-16 10:05:59 +08:00

400 lines
11 KiB
C#

using UnityEngine;
using DG.Tweening;
using DG.Tweening.Core;
using DG.Tweening.Plugins.Options;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using System;
using GOEventSystem;
using DevelopEngine;
using System.Collections.Generic;
using XFramework;
using System.IO;
public partial class CameraCtrl : MonoSingleton<CameraCtrl>
{
CameraPos pos = CameraPos.OutRoom;
Camera mainCamera;//主摄像机
public Camera Camera
{
get
{
return mainCamera;
}
}
private float camerHor;//相机水平转动输入值
private float camerVer;//相机垂直转动输入值
public UnityAction rightButtonEvent;//右键空白地面事件
bool moveWithRect = true;//边缘检测移动相机
public bool MoveWithRect
{
get
{
return moveWithRect;
}
set
{
this.moveWithRect = value;
}
}
/// <summary>
/// 类似游戏 通过鼠标移动到屏幕边界控制镜头移动
/// </summary>
private Rect rectUp;
private Rect rectDown;
private Rect rectLeft;
private Rect rectRight;
public float rectSize=30;
public float cameraMoveSpeed=5f;
[SerializeField]
int mouseKey=0;
Terrain terrain;
protected void Start()
{
Init();
GetConfigFromText();
mainCamera = this.GetComponentInChildren<Camera>();
ChangeCameraCtrlType(CamerViewType.Third);
//this.enabled = false;
//根据屏幕尺寸确定检测范围
rectUp = new Rect(0, Screen.height - rectSize, Screen.width, rectSize);
rectDown = new Rect(0, 0, Screen.width, rectSize);
rectLeft = new Rect(0, 0, rectSize, Screen.height);
rectRight = new Rect(Screen.width - rectSize, 0, rectSize, Screen.height);
cameraMoveSpeed = 120;
terrain = Terrain.activeTerrain;
//Debug.Log();
}
EventSystem_Camera eventSystem_Camera;
//添加交互检测器
internal void AddGOEventSystem()
{
eventSystem_Camera = gameObject.AddComponent<EventSystem_Camera>();
}
public void ChangeCameraEvent(bool isUsed)
{
eventSystem_Camera?.SetUsed(isUsed);
}
void Update()
{
//Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
//Debug.DrawRay(ray.origin, ray.direction * 2000);
if (EventSystem.current != null && EventSystem.current.IsPointerOverGameObject()) return; //相机控制时屏蔽UI部分
UpdateThird();
}
/// <summary>
/// 改变相机控制状态
/// </summary>
/// <param name="ctrlType"></param>
public void ChangeCameraCtrlType(CamerViewType ctrlType)
{
StartThird();
}
public void ChangeCamerPosSet(CameraPos cameraPos)
{
this.pos = cameraPos;
}
//开始第三人称控制视角
void StartThird()
{
switch (pos)
{
case CameraPos.OutRoom:
UpdateFarZoonMoveClamp();
break;
case CameraPos.InRoom:
UpdateNearZoonMoveClamp();
break;
default:
break;
}
ResetCameraAngY(0);
ResetCameraAngX(45);
//this.gameObject.transform.DOMove(startThirdPos, 0.3f);
}
//增大缩放空间
public void UpdateFarZoonMoveClamp()
{
m_ZoonMoveClamp = new Vector2(-150, -35);
ResetCameraContainerPos(-50);
}
//减小缩放空间
public void UpdateNearZoonMoveClamp()
{
m_ZoonMoveClamp = new Vector2(-10, -2);
ResetCameraContainerPos(-5);
}
//第三人称控制循环
void UpdateThird()
{
//镜头拉近拉远
ZoonMove(Input.GetAxis("Mouse ScrollWheel"));
//右键发射射线确定新的锚点 并移动过去
//if (Input.GetMouseButtonDown(1))
//{
// RaycastHit hit;//鼠标射线检测
// Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
// if (Physics.Raycast(ray, out hit, 2000, LayerMask.GetMask("Floor")))
// {
// this.gameObject.transform.DOMove(hit.point, 0.3f);
// }
//}
//右键
if (Input.GetMouseButtonDown(1))
{
rightButtonEvent?.Invoke();
}
//左键按下拖动旋转镜头角度
if (Input.GetMouseButton(mouseKey))
{
camerHor = -Input.GetAxis("Mouse X");
camerVer = -Input.GetAxis("Mouse Y");
if (Mathf.Abs(camerHor) > 0.2f || Mathf.Abs(camerVer) > 0.2f)
{
HerRot(camerHor);
UpOrDownRot(camerVer);
}
}
//Debug.Log(Input.mousePosition);
#region//鼠标边界平移 保持距离地面的高度
if (moveWithRect)
{
float terrainHeightChangeValue = 0;//相机正下方地形高度变化值
float cueeentHeight = 0;//当前相机正下方地面高度
float movedHeight = 0;//移动后相机下方地面高度
if (terrain)
{
cueeentHeight = terrain.SampleHeight(mainCamera.transform.position);//当前相机高度减去地面高度
}
if (rectUp.Contains(Input.mousePosition))
{
this.transform.position += Vector3.ProjectOnPlane(mainCamera.transform.forward, Vector3.up).normalized * cameraMoveSpeed * Time.deltaTime; //获取相机正前方在水平面的投影向量后改变位置
}
if (rectDown.Contains(Input.mousePosition))
{
this.transform.position -= Vector3.ProjectOnPlane(mainCamera.transform.forward, Vector3.up).normalized * cameraMoveSpeed * Time.deltaTime;
}
if (rectRight.Contains(Input.mousePosition))
{
this.transform.position += Vector3.ProjectOnPlane(mainCamera.transform.right, Vector3.up).normalized * cameraMoveSpeed * Time.deltaTime;
}
if (rectLeft.Contains(Input.mousePosition))
{
this.transform.position -= Vector3.ProjectOnPlane(mainCamera.transform.right, Vector3.up).normalized * cameraMoveSpeed * Time.deltaTime;
}
if (terrain)
{
movedHeight = terrain.SampleHeight(mainCamera.transform.position);//当前相机高度减去地面高度
}
terrainHeightChangeValue = movedHeight - cueeentHeight;
this.transform.position += new Vector3(0, terrainHeightChangeValue, 0);
}
#endregion
}
//获取鼠标点击的某层的物体 无法被其他物体遮挡
#region
public bool IsLockHerVerAng;
//展示单个设备控制相机转动
public void ShowEquipmentCameraCtrl(int hor, int ver)
{
camerHor = hor;
camerVer = ver;
}
//展示单独设备循环
void UpdateShowEquipment()
{
float scrollWheel = Input.GetAxis("Mouse ScrollWheel");
ZoonMove(scrollWheel);
#region ui
//if (IsLockHerVerAng) //ui 控制
//{
// if (camerHor != 0 || camerVer != 0)
// {
// this.transform.RotateAround(lookAtTarget.position, new Vector3(camerVer, camerHor, 0), 20 * Time.deltaTime);
// }
//}
//else
//{
//}
#endregion
if (Input.GetMouseButton(mouseKey))
{
camerHor = -Input.GetAxis("Mouse X");
camerVer = -Input.GetAxis("Mouse Y");
if (Mathf.Abs(camerHor) > 0.2f || Mathf.Abs(camerVer) > 0.2f)
{
HerRot(camerHor);
UpOrDownRot(camerVer);
}
}
}
#endregion
private Transform m_CameraUpOrDown;
private Transform m_CameraZoomContainer;
private Transform m_CameraContainer;
public float m_HerRotSpeed = 200;
public float m_VerRotSpeed = 200;
public float m_ZoonMoveSpeed = 500;
public Vector2 m_VerRotAngClamp = new Vector2(-90, 90);
public Vector2 m_ZoonMoveClamp = new Vector2(-float.MaxValue, -5);
private void Init()
{
m_CameraUpOrDown = transform.Find("CameraUpAndDown");
m_CameraZoomContainer = m_CameraUpOrDown.Find("CameraZoomContainer");
m_CameraContainer = m_CameraZoomContainer.Find("CameraContainer");
}
#region
/// <summary>
/// 水平转动
/// </summary>
/// <param name="rotNum"></param>
public void HerRot(float rotNum)
{
transform.Rotate(Vector3.up * Time.deltaTime * m_HerRotSpeed * rotNum);
}
/// <summary>
/// 上下转动
/// </summary>
/// <param name="rotNum"></param>
public void UpOrDownRot(float rotNum)
{
m_CameraUpOrDown.Rotate(-Vector3.right * Time.deltaTime * m_VerRotSpeed * rotNum);
m_CameraUpOrDown.localRotation = Quaternion.Euler(new Vector3(Mathf.Clamp(GetAng(m_CameraUpOrDown.eulerAngles.x), m_VerRotAngClamp.x, m_VerRotAngClamp.y), 0, 0));
}
/// <summary>
/// 缩放 拉近 拉远
/// </summary>
/// <param name="zoonNum"></param>
public void ZoonMove(float zoonNum)
{
m_CameraContainer.Translate(Vector3.forward * Time.deltaTime * m_ZoonMoveSpeed * zoonNum);
m_CameraContainer.localPosition = new Vector3(0, 0, Mathf.Clamp(m_CameraContainer.localPosition.z, m_ZoonMoveClamp.x, m_ZoonMoveClamp.y));
}
/// <summary>
/// 移动到目标位置 并观察目标
/// </summary>
/// <param name="target"></param>
public void LookAtTarget(Transform target)
{
this.gameObject.transform.DOMove(target.position, 0.3f);
}
/// <summary>
/// 更新位置
/// </summary>
/// <param name="pos"></param>
public void UpdatePostion(Vector3 pos)
{
transform.position = pos;
}
private float GetAng(float ang)
{
if (ang > 180)
{
ang -= 360;
}
return ang;
}
#endregion
public void ResetCameraContainerPos(float distZ)
{
m_CameraContainer.localPosition = new Vector3(0, 0, distZ);
}
public void ResetCameraAngX(float angX)
{
m_CameraUpOrDown.localEulerAngles = new Vector3(angX, 0, 0);
}
public void ResetCameraAngY(float angY)
{
transform.localEulerAngles = new Vector3(0, angY, 0);
}
private void GetConfigFromText()
{
string [] strs= File.ReadAllLines(StreamingAssetsManager.GetPath("CameraCtrl"));
for (int i = 0; i < strs.Length; i++)
{
string oneLine = strs[i].Trim();
if (oneLine.StartsWith("RotateKey:"))
{
mouseKey = int.Parse(oneLine.Split(':')[1]);
}
}
}
}
public enum CameraPos
{
OutRoom,//室外
InRoom,//室内
}
//相机视角模式
public enum CamerViewType
{
Tween,//动画
First,//第一人称
Third,//电子沙盘
ShowEquipment,//展示单个设备
}
//相机移动控制类型
public enum CameraMoveType
{
//右键点击地面
rightButtonHitFloor,
//
}