MayHeCome/Assets/三问c#/Move.cs
2024-12-18 17:55:34 +08:00

293 lines
9.0 KiB
C#

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<Vector2>();
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;
}
/// <summary>
/// 这里处理除了鼠标以外其他部分输入设备的移动
/// </summary>
/// <param name="context"></param>
private void OnOtherMovePerformed(InputAction.CallbackContext context)
{
mouseDelta = context.ReadValue<Vector2>();
// 更新目标位置
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<Vector2>();
// 更新目标位置
targetPosition += new Vector3(-mouseDelta.x, -mouseDelta.y, 0) * moveSpeed;
MoveStyle = MoveLerp; // 启用平滑移动
}
}
//#region 滚轮缩放
//private void OnZoomPerformed(InputAction.CallbackContext context)
//{
// if (!MustMove)
// {
// float scrollValue = context.ReadValue<Vector2>().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;
}
}
/// <summary>
/// 没有过渡效果的移动
/// </summary>
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
/// <summary>
/// 退出科技树
/// </summary>
public void ExitTreeScreen()
{
targetZoom = minZoom;
// SceneTransitionManager.Instance.gameObject.SetActive(true);
gameObject.SetActive(false);
TreeControl.Instance.UINameOpen(false);
}
}