using System.Collections; using System.Collections.Generic; using System; using UnityEngine; using UnityEngine.InputSystem; public class Move : MonoBehaviour { [Header("相机远景原点")] public Vector3 CameraCenterPos; [Header("中心点插值")] public Vector2 offsetv2; private CameraMove inputActions; private Vector2 mouseDelta; private bool isDragging = false; private bool MustMove = false; // 强制移动禁止拖拽 private Transform CameraTrans; [Header("摄像机移动速度")] public float moveSpeed = 0.1f; [Header("丝滑度")] public float lerpSpeed = 5f; [Header("缩放速度")] public float zoomSpeed = 10f; [Header("视角最小")] public float minZoom = 2f; [Header("视角最大")] public float maxZoom = 10f; [Header("显示名字视角大小")] public Vector2 UINameZoom; [Header("摄像机移动边界")] public Vector2 minBounds; // 移动区域的最小值 public Vector2 maxBounds; // 移动区域的最大值 private Vector3 targetPosition; private float targetZoom; public Camera cam; private Action MoveStyle; private Action ZoomStyle; private Action UICloseStyle; private Action UINameStyle; private Vector3 InfoPos;//初始位置 public float InfoZoom;//初始大小 private Vector2 otherDeviceMoveDirection; private Vector3 BeforeCameraPos; private void Awake() { inputActions = new CameraMove(); targetZoom = cam.orthographicSize; CameraTrans = cam.transform; UINameStyle = UINameOpen; InfoPos = CameraTrans.position; } private void OnEnable() { //cam.orthographicSize = maxZoom; targetZoom = InfoZoom; //ZoomStyle = ZoomLerp; cam.gameObject.SetActive(true); inputActions.Enable(); inputActions.Tree.LeftClick.started += OnClickStarted; inputActions.Tree.LeftClick.canceled += OnClickCanceled; inputActions.Tree.Move.performed += OnMovePerformed; //inputActions.Tree.Zoom.performed += OnZoomPerformed; inputActions.Tree.OtherDeviceMove.performed += context => { otherDeviceMoveDirection = context.ReadValue(); MoveStyle = MoveHard; }; inputActions.Tree.OtherDeviceMove.canceled += context => { otherDeviceMoveDirection = Vector2.zero; MoveStyle = null; }; } private void OnDisable() { CameraTrans.position = InfoPos; cam.gameObject.SetActive(false); SceneTransitionManager.Instance.gameObject.SetActive(true); inputActions.Disable(); } private void Update() { targetPosition += (Vector3)otherDeviceMoveDirection.normalized * moveSpeed; MoveStyle?.Invoke(); ZoomStyle?.Invoke(); UICloseStyle?.Invoke(); UINameStyle?.Invoke(); } private void OnClickStarted(InputAction.CallbackContext context) { GameObject obj = gameObject; if (CheckRaycast2D(ref obj)) { //MustMove = true; TreeControl.Instance.currentobj = obj; TreeControl.Instance.ChangeUIcontect(obj.transform); Vector3 pos = obj.transform.position; Vector3 afterpos= targetPosition = new Vector3(pos.x - offsetv2.x, pos.y - offsetv2.y, CameraTrans.position.z); //From https://discussions.unity.com/t/how-to-keep-an-object-within-the-camera-view/117989 Vector3 posClamp = cam.WorldToViewportPoint (afterpos); // print($"Pos Clamp: {posClamp}"); posClamp.x = Mathf.Clamp(posClamp.x, 0.2f, 0.8f); posClamp.y = Mathf.Clamp(posClamp.y, 0.3f, 0.8f); posClamp = cam.ViewportToWorldPoint(posClamp); // // Debug.Log(obj.name + "--" + pos); //MoveStyle = MoveLerp; //targetZoom = minZoom; //ZoomStyle = ZoomLerp; BeforeCameraPos = CameraTrans.position; // TreeControl.Instance.ActiveUITrue(afterpos); TreeControl.Instance.ActiveUITrue(posClamp); UICloseStyle = UIClose; TreeControl.Instance.BtnDowm(); return; } targetPosition = CameraTrans.position; isDragging = true; mouseDelta = Vector2.zero; } private void OnClickCanceled(InputAction.CallbackContext context) { TreeControl.Instance.BtnUp(); isDragging = false; } /// /// 这里处理除了鼠标以外其他部分输入设备的移动 /// /// private void OnOtherMovePerformed(InputAction.CallbackContext context) { mouseDelta = context.ReadValue(); // 更新目标位置 targetPosition += new Vector3(-mouseDelta.x, -mouseDelta.y, 0) * moveSpeed; MoveStyle = MoveLerp; // 启用平滑移动 } private void OnMovePerformed(InputAction.CallbackContext context) { Debug.LogWarning(isDragging + "--" + MustMove); if (isDragging && !MustMove) { mouseDelta = context.ReadValue(); // 更新目标位置 targetPosition += new Vector3(-mouseDelta.x, -mouseDelta.y, 0) * moveSpeed; MoveStyle = MoveLerp; // 启用平滑移动 } } //#region 滚轮缩放 //private void OnZoomPerformed(InputAction.CallbackContext context) //{ // if (!MustMove) // { // float scrollValue = context.ReadValue().y; // targetZoom -= scrollValue * zoomSpeed * Time.deltaTime; // targetZoom = Mathf.Clamp(targetZoom, minZoom, maxZoom); // 限制缩放范围 // ZoomStyle = ZoomLerp; // } // // if (cam.orthographicSize>=maxZoom)//已经超过了最大;该退出场景 // // { // // ExitTreeScreen(); // // } //} //public void ZoomLerp() //{ // cam.orthographicSize = Mathf.Lerp(cam.orthographicSize, targetZoom, Time.deltaTime * lerpSpeed); // if (Mathf.Abs(cam.orthographicSize - targetZoom) < 0.05f) // { // cam.orthographicSize = targetZoom; // ZoomStyle = null; // } //} //#endregion public void MoveLerp() { // 限制目标位置在边界内 targetPosition = ClampPosition(targetPosition); // 使用 Lerp 插值移动摄像机 CameraTrans.position = Vector3.Lerp(CameraTrans.position, targetPosition, Time.deltaTime * lerpSpeed); if (Vector3.Distance(CameraTrans.position, targetPosition) < 0.05f) { CameraTrans.position = targetPosition; MoveStyle = null; if (MustMove) { //TreeControl.Instance.ActiveUITrue(targetPosition); //UICloseStyle = UIClose; } MustMove = false; } } /// /// 没有过渡效果的移动 /// public void MoveHard() { CameraTrans.position = ClampPosition(targetPosition); } // 限制摄像机位置在给定的边界内 private Vector3 ClampPosition(Vector3 position) { // 限制X和Y轴在边界范围内 float clampedX = Mathf.Clamp(position.x, minBounds.x, maxBounds.x); float clampedY = Mathf.Clamp(position.y, minBounds.y, maxBounds.y); // Debug.Log(clampedY + "---" + clampedX); return new Vector3(clampedX, clampedY, position.z); } #region 2D 射线检测 private bool CheckRaycast2D(ref GameObject obj) { Vector2 mousePosition = cam.ScreenToWorldPoint(Mouse.current.position.ReadValue()); RaycastHit2D hit = Physics2D.Raycast(mousePosition, Vector2.zero); if (hit.collider != null && hit.collider.gameObject.layer == LayerMask.NameToLayer("TreeNode")) { obj = hit.collider.gameObject; return true; } return false; } #endregion #region UI退出 private void UIClose() { if (Vector2.Distance(BeforeCameraPos, CameraTrans.position) > 3 )//|| cam.orthographicSize > UINameZoom.y) { Debug.LogWarning("关闭UI"); TreeControl.Instance.ActiveUIFalse(); UICloseStyle = null; } } private void UINameClose() { if (cam.orthographicSize >= UINameZoom.y) { TreeControl.Instance.UINameOpen(false); UINameStyle = UINameOpen; } } private void UINameOpen() { if (cam.orthographicSize <= UINameZoom.x) { TreeControl.Instance.UINameOpen(true); UINameStyle = UINameClose; } } #endregion /// /// 退出科技树 /// public void ExitTreeScreen() { targetZoom = minZoom; // SceneTransitionManager.Instance.gameObject.SetActive(true); gameObject.SetActive(false); TreeControl.Instance.UINameOpen(false); } }