Files
aibis-dream/Assets/Scripts/FixSystem/Effect/MouseFollowEffect.cs
T

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