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(); 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(); 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)); } }