216 lines
8.1 KiB
C#
216 lines
8.1 KiB
C#
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using DG.Tweening;
|
|
using TMPro;
|
|
|
|
public class MouseFollowAndZoom : MonoBehaviour
|
|
{
|
|
public float parallaxEffectMultiplier = 0.1f;
|
|
public Vector2 maxOffset = new Vector2(2f, 2f);
|
|
public GameObject targetIndicator; // UI 目标框
|
|
public TMP_Text targetNameText; // 显示目标名称的文本
|
|
public Button exitZoomButton; // 退出缩放的按钮
|
|
public float zoomInScale = 1.5f; // 缩放倍数
|
|
public float zoomDuration = 1.0f; // 缩放持续时间(减慢)
|
|
public Vector2 sceneBoundsMin; // 场景边界的左下角
|
|
public Vector2 sceneBoundsMax; // 场景边界的右上角
|
|
public Camera viewCamera;
|
|
private Camera MainCamera;
|
|
private Vector3 initialPosition;
|
|
private Vector3 zoomedInPosition; // 保存缩放时的相机位置
|
|
private bool isZoomedIn = false;
|
|
private Transform currentTarget;
|
|
|
|
private float viewOffset=40.3f;
|
|
|
|
private bool isActive=false;
|
|
|
|
// 只读访问
|
|
public bool GetMyPrivateVariable()
|
|
{
|
|
return isActive;
|
|
}
|
|
|
|
// 读写访问
|
|
public void SetIsActive(bool value)
|
|
{
|
|
isActive = value;
|
|
}
|
|
|
|
|
|
void Start()
|
|
{
|
|
MainCamera = Camera.main;
|
|
initialPosition = transform.position;
|
|
targetIndicator.SetActive(false); // 初始时隐藏目标框
|
|
exitZoomButton.gameObject.SetActive(false); // 初始时隐藏退出按钮
|
|
exitZoomButton.onClick.AddListener(ExitZoom);
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
//if (isZoomedIn) return; // 如果已经缩放,不再更新位置
|
|
|
|
//if(!isActive) return;
|
|
|
|
HandleMouseMovement();
|
|
HandleTargetIndicator();
|
|
}
|
|
|
|
void HandleMouseMovement()
|
|
{
|
|
// 获取鼠标位置
|
|
Vector3 mousePosition = Input.mousePosition;
|
|
Vector3 worldMousePosition = viewCamera.ScreenToWorldPoint(mousePosition);
|
|
worldMousePosition.z = 0; // 确保 z 为 0
|
|
|
|
// 计算偏移量并反向
|
|
Vector3 offset = (viewCamera.transform.position - worldMousePosition) * parallaxEffectMultiplier;
|
|
offset.x = Mathf.Clamp(offset.x, -maxOffset.x, maxOffset.x);
|
|
offset.y = Mathf.Clamp(offset.y, -maxOffset.y, maxOffset.y);
|
|
|
|
// 更新位置
|
|
Vector3 targetPosition = initialPosition + offset;
|
|
transform.DOMove(targetPosition, 0.2f).SetEase(Ease.OutSine);
|
|
}
|
|
|
|
void HandleTargetIndicator()
|
|
{
|
|
// 获取鼠标位置
|
|
Vector3 mousePosition = Input.mousePosition;
|
|
mousePosition.x+=viewOffset;
|
|
Vector3 worldPosition = viewCamera.ScreenToWorldPoint(mousePosition);
|
|
//worldPosition.x+=viewOffset;
|
|
RaycastHit2D hit = Physics2D.Raycast(worldPosition, Vector2.zero);
|
|
|
|
if(hit.collider!=null)
|
|
{
|
|
Debug.Log(hit.collider.gameObject.name);
|
|
}
|
|
|
|
|
|
if (hit.collider != null && hit.collider.CompareTag("EyeTarget")) // 检查是否是目标 Sprite
|
|
{
|
|
Debug.Log("find target");
|
|
targetIndicator.SetActive(true);
|
|
BoxCollider2D boxCollider = hit.collider.GetComponent<BoxCollider2D>();
|
|
|
|
if (boxCollider != null)
|
|
{
|
|
// 获取 BoxCollider2D 的大小和位置
|
|
Vector3 boxCenter = boxCollider.bounds.center;
|
|
//boxCenter.x-=viewOffset;
|
|
Vector3 boxSize = boxCollider.bounds.size;
|
|
|
|
//Vector3 boxCenterModify=new Vector3(boxCenter.x-viewOffset,boxCenter.y,boxCenter.z);
|
|
Vector3 boxCenterModify=boxCenter;
|
|
|
|
// 转换为屏幕坐标
|
|
Vector3 screenCenter = viewCamera.WorldToScreenPoint(boxCenterModify);
|
|
Vector2 screenSize = viewCamera.WorldToScreenPoint(boxCenterModify + boxSize) - viewCamera.WorldToScreenPoint(boxCenterModify);
|
|
|
|
// 设置目标框位置和大小
|
|
RectTransform indicatorRectTransform = targetIndicator.GetComponent<RectTransform>();
|
|
indicatorRectTransform.position = screenCenter;
|
|
|
|
// 动画效果:先放大再缩小
|
|
//indicatorRectTransform.localScale = Vector3.one * 1.5f;
|
|
//indicatorRectTransform.DOScale(Vector3.one, 0.2f).SetEase(Ease.OutBounce);
|
|
indicatorRectTransform.sizeDelta = screenSize;
|
|
|
|
// 设置目标名称
|
|
targetNameText.text = hit.collider.name;
|
|
}
|
|
|
|
// 点击目标框触发缩放
|
|
// if (Input.GetMouseButtonDown(0))
|
|
// {
|
|
// currentTarget = hit.collider.transform;
|
|
// ZoomIn();
|
|
// }
|
|
}
|
|
else
|
|
{
|
|
targetIndicator.SetActive(false);
|
|
}
|
|
}
|
|
|
|
void ZoomIn()
|
|
{
|
|
isZoomedIn = true;
|
|
targetIndicator.SetActive(false); // 隐藏目标框
|
|
|
|
Vector3 targetPosition = currentTarget.position;
|
|
targetPosition.z = -10; // 确保 Z 轴位置为 -10
|
|
|
|
// 防止相机超出场景边界
|
|
float cameraHalfHeight = MainCamera.orthographicSize;
|
|
float cameraHalfWidth = cameraHalfHeight * MainCamera.aspect;
|
|
targetPosition.x = Mathf.Clamp(targetPosition.x, sceneBoundsMin.x + cameraHalfWidth, sceneBoundsMax.x - cameraHalfWidth);
|
|
targetPosition.y = Mathf.Clamp(targetPosition.y, sceneBoundsMin.y + cameraHalfHeight, sceneBoundsMax.y - cameraHalfHeight);
|
|
|
|
// 动画效果:缩放相机
|
|
MainCamera.transform.DOMove(targetPosition, zoomDuration).SetEase(Ease.OutExpo); // 使用更平滑的缓动
|
|
MainCamera.DOOrthoSize(MainCamera.orthographicSize / zoomInScale, zoomDuration).SetEase(Ease.OutExpo).OnComplete(() =>
|
|
{
|
|
// 缩放结束后显示退出按钮
|
|
ShowExitButton();
|
|
});
|
|
}
|
|
|
|
void ShowExitButton()
|
|
{
|
|
// 设置按钮位置在目标上方
|
|
Vector3 buttonPosition = currentTarget.position;
|
|
buttonPosition.z = 0; // 确保 z 为 0
|
|
buttonPosition.y += 1.0f; // 根据需要调整按钮的高度
|
|
|
|
exitZoomButton.transform.position = MainCamera.WorldToScreenPoint(buttonPosition); // 将按钮位置设置为目标上方
|
|
exitZoomButton.gameObject.SetActive(true); // 显示退出缩放按钮
|
|
}
|
|
|
|
void ExitZoom()
|
|
{
|
|
if (!isZoomedIn) return; // 如果没有缩放则直接返回
|
|
|
|
isZoomedIn = false;
|
|
targetIndicator.SetActive(false); // 确保在退出缩放时隐藏目标框
|
|
exitZoomButton.gameObject.SetActive(false); // 隐藏退出缩放按钮
|
|
|
|
// 计算目标缩放
|
|
float targetOrthoSize = MainCamera.orthographicSize * zoomInScale;
|
|
|
|
// 获取缩放时的目标位置
|
|
Vector3 targetPosition = currentTarget.position;
|
|
targetPosition.z = -10; // 确保 Z 轴位置为 -10
|
|
|
|
// 确保目标位置在边界内
|
|
float cameraHalfHeight = targetOrthoSize; // 使用目标缩放计算边界
|
|
float cameraHalfWidth = cameraHalfHeight * MainCamera.aspect;
|
|
|
|
targetPosition.x = Mathf.Clamp(targetPosition.x, sceneBoundsMin.x + cameraHalfWidth, sceneBoundsMax.x - cameraHalfWidth);
|
|
targetPosition.y = Mathf.Clamp(targetPosition.y, sceneBoundsMin.y + cameraHalfHeight, sceneBoundsMax.y - cameraHalfHeight);
|
|
|
|
// 动画效果:先缩放再移动
|
|
Sequence zoomOutSequence = DOTween.Sequence();
|
|
zoomOutSequence.Append(MainCamera.DOOrthoSize(targetOrthoSize, zoomDuration).SetEase(Ease.OutExpo));
|
|
zoomOutSequence.Join(MainCamera.transform.DOMove(targetPosition, zoomDuration).SetEase(Ease.OutExpo));
|
|
}
|
|
|
|
void OnDrawGizmos()
|
|
{
|
|
// 设置 Gizmos 颜色
|
|
Gizmos.color = Color.red;
|
|
|
|
// 绘制场景边界
|
|
Vector3 bottomLeft = new Vector3(sceneBoundsMin.x, sceneBoundsMin.y, 0);
|
|
Vector3 topRight = new Vector3(sceneBoundsMax.x, sceneBoundsMax.y, 0);
|
|
|
|
// 绘制边界框
|
|
Gizmos.DrawLine(bottomLeft, new Vector3(bottomLeft.x, topRight.y, 0));
|
|
Gizmos.DrawLine(bottomLeft, new Vector3(topRight.x, bottomLeft.y, 0));
|
|
Gizmos.DrawLine(topRight, new Vector3(bottomLeft.x, topRight.y, 0));
|
|
Gizmos.DrawLine(topRight, new Vector3(topRight.x, bottomLeft.y, 0));
|
|
}
|
|
}
|