Files
3d-fengji/Assets/Scripts/MainCamera/DoubleClickToFocus.cs
2026-05-20 17:05:47 +08:00

368 lines
19 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections;
using System.Collections.Generic;
//using System.Diagnostics;
using UnityEngine;
using UnityEngine.EventSystems;
//这个脚本的名字是双击跳转,按照庄公的需求全部改成单击,名字的问题就先不考虑了,这里给他修改成单击,但是保留了双击的逻辑,以便以后方便切换回来
//把脚本复制一份上面是单击版本,下面是双击版本
//单击双击问题最终确定图标单击传感器和房子双击这样唯一问题就是双击图标怎么办算了妥协吧设置为blocking objects为3d这样不能跨越穿越妥协了
//public class DoubleClickToFocus : MonoBehaviour
//{
// private Dictionary<string, Vector3> targetObjectAndPosition = new Dictionary<string, Vector3>();//使用字典数据类型来定义每一个物体自己对应的观察点位置
// [Tooltip("平滑过渡所用时间(秒)")] public float transitionDuration = 1.0f;
// [Header("双击设置")]
// [Tooltip("双击间隔时间阈值(秒)")] public float doubleClickInterval = 0.3f;
// //private float lastClickTime = 0f;
// //private bool waitingSecondClick = false;
// bool flying = false;//双击不需要用这种方式来确定,单击的话还是要的。
// private Camera mainCamera;
// public Vector3 core;
// private void Awake()
// {
// core = new Vector3(-50f, 20f, -30f);//初始旋转中心
// }
// void Start()
// {
// mainCamera = Camera.main;//主相机的那个Camera组件跳转到的观测点
// //targetObjectAndPosition.Add("tt_zhuta", new Vector3(53f, 16.3f, 27.62f));
// //targetObjectAndPosition.Add("sb_fengsufengxiang400", new Vector3(12.23f, 11.38f, 27.62f));
// //targetObjectAndPosition.Add("sb_gnss01", new Vector3(15.6f, 2f, 12f));
// //targetObjectAndPosition.Add("sb_gnss02", new Vector3(13.18f, 2f, 33.3f));
// //targetObjectAndPosition.Add("sb_gnss03", new Vector3(1.4f, 2f, 22.3f));
// //targetObjectAndPosition.Add("sb_jiasudu01", new Vector3(11.45f, 13.1f, 31.9f));
// //targetObjectAndPosition.Add("sb_jiasudu02", new Vector3(2.55f, 13.1f, 32));
// //targetObjectAndPosition.Add("sb_jiasudu03", new Vector3(2.55f, 13.1f, 24.6f));
// //targetObjectAndPosition.Add("sb_jiasudu04", new Vector3(11.1f, 13.1f, 24.6f));
// //targetObjectAndPosition.Add("sb_qingjiaoiji01", new Vector3(10.67f, 11.2f, 32.8f));
// //targetObjectAndPosition.Add("sb_qingjiaoiji02", new Vector3(2.9f, 11.2f, 32.5f));
// //targetObjectAndPosition.Add("sb_qingjiaoiji03", new Vector3(2.9f, 11.2f, 24f));
// //targetObjectAndPosition.Add("sb_qingjiaoiji04", new Vector3(10.7f, 11.2f, 24.1f));
// //targetObjectAndPosition.Add("sb_shexiangtou", new Vector3(11.27f, 17.37f, 31.78f));
// //targetObjectAndPosition.Add("sb_shujucaijiyi", new Vector3(10.3f, 14.2f, 33.8f));
// //targetObjectAndPosition.Add("sb_wenshiya", new Vector3(11.3f, 11f, 29f));
// //targetObjectAndPosition.Add("sb_yachashi01", new Vector3(13f, 0.36f, 12.1f));
// //targetObjectAndPosition.Add("sb_yachashi02", new Vector3(13f, 0.5f, 23f));
// //targetObjectAndPosition.Add("sb_yachashi03", new Vector3(13f, 0.5f, 33.5f));
// //targetObjectAndPosition.Add("sb_yachashi04", new Vector3(1.57f, 0.27f, 34.5f));
// //targetObjectAndPosition.Add("sb_yachashi05", new Vector3(1.56f, 0.3f, 22f));
// //targetObjectAndPosition.Add("sb_yingbianji01", new Vector3(10.46f, 13f, 32.5f));
// //targetObjectAndPosition.Add("sb_yingbianji02", new Vector3(3.1f, 13f, 32.5f));
// //targetObjectAndPosition.Add("sb_yingbianji03", new Vector3(3.1f, 13f, 24.1f));
// //targetObjectAndPosition.Add("sb_yingbianji04", new Vector3(10.4f, 13f, 23.8f));
// //targetObjectAndPosition.Add("tt_changjianzhub001", new Vector3(24f, 10f, -19f));
// //targetObjectAndPosition.Add("tt_changjianzhud", new Vector3(1f, 10f, -80f));
// //targetObjectAndPosition.Add("tt_changjianzhud001", new Vector3(24f, 10f, -60f));
// //targetObjectAndPosition.Add("tt_changjianzhuc", new Vector3(-71f, 10f, -65f));
// //targetObjectAndPosition.Add("tt_changjianzhub", new Vector3(-49f, 10f, -19f));
// //targetObjectAndPosition.Add("tt_changjianzhua", new Vector3(-34f, 10f, -19f));
// targetObjectAndPosition.Add("bx_talou", new Vector3(-82f, 37f, -100f));
// targetObjectAndPosition.Add("bx_langqiao", new Vector3(-35f, 30f, -59f));
// targetObjectAndPosition.Add("bx_qiaozha", new Vector3(-26f, 35f, -74f));
// targetObjectAndPosition.Add("bx_zhafang1", new Vector3(-64f, 21f, -102f));
// targetObjectAndPosition.Add("bx_zhafang2", new Vector3(-8f, 26f, -173f));
// targetObjectAndPosition.Add("bx_zhafang3", new Vector3(12f, 23f, -37f));
// targetObjectAndPosition.Add("bx_diaosu", new Vector3(-18f, 18f, 13f));
// targetObjectAndPosition.Add("sb_shujucaijiyi", new Vector3(-26f, 19f, 11f));
// targetObjectAndPosition.Add("sb_shujucaijiyi (1)", new Vector3(31f, 17f, -60f));
// targetObjectAndPosition.Add("bx_zhafang5", new Vector3(53f, 26f, -23f));
// targetObjectAndPosition.Add("pj_tingzi", new Vector3(67f, 20f, -97f));
// targetObjectAndPosition.Add("sb_qixiangzu001", new Vector3(14.2f, 24.8f, 11.5f));
// targetObjectAndPosition.Add("sb_wuxianqingjiaoji001", new Vector3(-118.4f, 18f, -82.9f));
// targetObjectAndPosition.Add("sb_wuxianqingjiaoji002", new Vector3(-110f, 18f, -78f));
// targetObjectAndPosition.Add("sb_wuxianqingjiaoji003", new Vector3(-114f, 18f, -70.3f));
// targetObjectAndPosition.Add("sb_wuxianqingjiaoji004", new Vector3(-121.8f, 18f, -74.3f));
// }
// void Update()
// {
// if (Input.GetMouseButtonUp(0))
// {
// if (!flying)
// {
// HandleClick();
// }
// }
// }
// public void HandleClick()
// {
// Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
// if (Physics.Raycast(ray, out RaycastHit hit, Mathf.Infinity) && hit.collider.CompareTag("Target"))//应该给被打中的物体加一个标签不然正常物体也会影响core,判断是否打中浮标或者是传感器本体2者都要加上Target标签
// {
// Transform finalObject = hit.transform;//用浮标嫁祸给真实物体浮标用ICON结尾去除这个后缀就得到了真实物体的名字不然浮标得单独打点打点跳转也不好
// if (finalObject.gameObject.name.EndsWith("ICON"))
// {
// string realObjName = finalObject.gameObject.name.Substring(0, finalObject.gameObject.name.Length - 4);//去尾法得到传感器名字浮标名字只是在传感器名字后面加ICON其他的不能动
// finalObject = GameObject.Find(realObjName).transform;
// }
// foreach (KeyValuePair<string, Vector3> pair in targetObjectAndPosition)
// {
// if (finalObject.gameObject.name == pair.Key)
// {
// Vector3 targetPos = pair.Value;
// StartCoroutine(MoveCamera(mainCamera, targetPos, transitionDuration, finalObject));
// }
// }
// core = finalObject.position;//这里只要有 Target 被打中的话,你的旋转中心就会变,所以要确保被打中的物体一定是可以跳转的
// }
// }
// private IEnumerator MoveCamera(Camera cam, Vector3 targetPos, float duration, Transform focusTarget)
// {
// flying = true;
// Vector3 startPos = cam.transform.position;
// float elapsed = 0f;
// while (elapsed < duration)
// {
// float t = Mathf.Lerp(0f, 1f, elapsed / duration);
// cam.transform.position = Vector3.Lerp(startPos, targetPos, t);
// if (focusTarget != null)
// cam.transform.LookAt(focusTarget);
// elapsed += Time.deltaTime;
// yield return null;
// }
// cam.transform.position = targetPos;
// cam.transform.LookAt(focusTarget);
// flying = false;
// if (cam.transform.position.y < 0.01f) //这个是为了防止部分设备太贴近地面导致穿透地面里面出不来。让你的相机永远都在地面0.1米以上
// {
// Vector3 newPos = cam.transform.position;
// // 2. 修改y轴值x、z保持不变
// newPos.y = 0.1f;
// // 3. 重新赋值给position
// cam.transform.position = newPos;
// }
// }
//}
//-------------------------------------------------------------------------------------------单击双击分界线
public class DoubleClickToFocus : MonoBehaviour
{
private Dictionary<string, Vector3> targetObjectAndPosition = new Dictionary<string, Vector3>();//使用字典数据类型来定义每一个物体自己对应的观察点位置
[Tooltip("平滑过渡所用时间(秒)")] public float transitionDuration = 1.5f;
[Header("双击设置")]
[Tooltip("双击间隔时间阈值(秒)")] public float doubleClickInterval = 0.3f;
private float lastClickTime = 0f;
private bool waitingSecondClick = false;
private Camera mainCamera;
public Vector3 core;
bool flying = false;
private void Awake()
{
core = new Vector3(-50f, 20f, -30f);//初始旋转中心
}
void Start()
{
mainCamera = Camera.main;//主相机的那个Camera组件跳转到的观测点
targetObjectAndPosition.Add("bx_talou", new Vector3(-82f, 37f, -100f));
targetObjectAndPosition.Add("bx_langqiao", new Vector3(-35f, 30f, -59f));
targetObjectAndPosition.Add("bx_qiaozha", new Vector3(-26f, 35f, -74f));
targetObjectAndPosition.Add("bx_zhafang1", new Vector3(-64f, 21f, -102f));
targetObjectAndPosition.Add("bx_zhafang2", new Vector3(-8f, 26f, -173f));
targetObjectAndPosition.Add("bx_zhafang3", new Vector3(12f, 23f, -37f));
targetObjectAndPosition.Add("bx_diaosu", new Vector3(-18f, 18f, 13f));
targetObjectAndPosition.Add("sb_shujucaijiyi", new Vector3(-28f, 20.7f, 4.5f));
targetObjectAndPosition.Add("sb_shujucaijiyi (1)", new Vector3(31.3f, 19.7f, -66.3f));
targetObjectAndPosition.Add("bx_zhafang5", new Vector3(53f, 26f, -23f));
targetObjectAndPosition.Add("pj_tingzi", new Vector3(67f, 20f, -97f));
targetObjectAndPosition.Add("sb_qixiangzu001", new Vector3(14.2f, 24.8f, 11.5f));
targetObjectAndPosition.Add("sb_wuxianqingjiaoji001", new Vector3(-35.69f, 62.82f, -12.18f));
targetObjectAndPosition.Add("sb_wuxianqingjiaoji002", new Vector3(-39.52f, 62.94f, -14.66f));
targetObjectAndPosition.Add("sb_wuxianqingjiaoji003", new Vector3(-35.82f, 63f, -16.84f));
targetObjectAndPosition.Add("sb_wuxianqingjiaoji004", new Vector3(-121.8f, 18f, -74.3f));
targetObjectAndPosition.Add("sb_gnss001", new Vector3(-27.6f, 52f, -18.12f));
targetObjectAndPosition.Add("sb_gnss002", new Vector3(-68f, 20.6f, -60f));
targetObjectAndPosition.Add("sb_gnss003", new Vector3(-18.4f, 19.5f, -35f));
targetObjectAndPosition.Add("sb_gnss004", new Vector3(-28.8f, 20.4f, -23.5f));
targetObjectAndPosition.Add("sb_liefengji001", new Vector3(-82f, 17.87f, -70.26f));
targetObjectAndPosition.Add("sb_liefengji002", new Vector3(-70.2f, 18f, -58.4f));
targetObjectAndPosition.Add("sb_liefengji003", new Vector3(-55.84f, 18.145f, -47.3f));
targetObjectAndPosition.Add("sb_liefengji004", new Vector3(-42.8f, 18.25f, -35.47f));
targetObjectAndPosition.Add("sb_liefengji005", new Vector3(-30.5f, 18f, -22.5f));
targetObjectAndPosition.Add("sb_yachashi001", new Vector3(-25f, 50.28f, -17.22f));
targetObjectAndPosition.Add("sb_yachashi002", new Vector3(-36.94f, 50.28f, -10.91f));
targetObjectAndPosition.Add("sb_yachashi003", new Vector3(-36.97f, 50.28f, -18.37f));
targetObjectAndPosition.Add("sb_yachashi004", new Vector3(-33.5f, 50.28f, -14.65f));
targetObjectAndPosition.Add("sb_yachashi005", new Vector3(-40.59f, 50.28f, -14.65f));
targetObjectAndPosition.Add("sb_yingbianji001", new Vector3(-37.96f, 73.14f, -12f));
targetObjectAndPosition.Add("sb_yingbianji002", new Vector3(-39.83f, 73f, -14.74f));
targetObjectAndPosition.Add("sb_yingbianji003", new Vector3(-37.86f, 73f, -17f));
targetObjectAndPosition.Add("sb_yingbianji004", new Vector3(-35f, 73.14f, -16.23f));
targetObjectAndPosition.Add("sb_yingbianji005", new Vector3(-34.88f, 73f, -13.06f));
targetObjectAndPosition.Add("sb_fengjizhendong001", new Vector3(-34.38f, 118.09f, -14.05f));
targetObjectAndPosition.Add("sb_fengjizhendong002", new Vector3(-34.52f, 118.09f, -15.17f));
targetObjectAndPosition.Add("sb_yulaingji001", new Vector3(-103.65f, 29.63f, 125.45f));
targetObjectAndPosition.Add("sb_wenshiya001", new Vector3(-106.73f, 29.08f, 125.36f));
targetObjectAndPosition.Add("sb_qixiangfengxiang001", new Vector3(-105.29f, 29.16f, 127.22f));
targetObjectAndPosition.Add("sb_qixiangfengsu001", new Vector3(-104.87f, 29.06f, 123.55f));
targetObjectAndPosition.Add("全部ViewPort", new Vector3(16f, 113f, -167f));
targetObjectAndPosition.Add("沉降监测ViewPort", new Vector3(16f, 113f, -167f));
targetObjectAndPosition.Add("振动加速度ViewPort", new Vector3(16f, 113f, -167f));
targetObjectAndPosition.Add("应变监测ViewPort", new Vector3(16f, 113f, -167f));
targetObjectAndPosition.Add("裂缝监测ViewPort", new Vector3(16f, 113f, -167f));
targetObjectAndPosition.Add("倾角监测ViewPort", new Vector3(16f, 113f, -167f));
targetObjectAndPosition.Add("气象监测ViewPort", new Vector3(16f, 113f, -167f));
targetObjectAndPosition.Add("流量监测ViewPort", new Vector3(16f, 113f, -167f));
}
void Update()
{
if (EventSystem.current != null && EventSystem.current.IsPointerOverGameObject())
{
return; // 直接 return你下面所有相机逻辑都不执行
}
if (Input.GetMouseButtonDown(0))
{
if (waitingSecondClick && Time.time - lastClickTime <= doubleClickInterval)
{
HandleClick();
Debug.Log(123);
waitingSecondClick = false;
}
else
{
waitingSecondClick = true;
lastClickTime = Time.time;
StartCoroutine(ResetClickState());
}
}
}
private void HandleClick()
{
Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out RaycastHit hit, Mathf.Infinity) && hit.collider.CompareTag("Target"))//这里有点小问题应该给被打中的物体加一个标签不然正常物体也会影响core
{
Transform finalObject = hit.transform;//用浮标嫁祸给真实物体浮标用ICON结尾去除这个后缀就得到了真实物体的名字
//这些是之前图片直接在世界空间用spriteRender的现在没用了图片做成UI了也没这个物理检测效果了。
if (finalObject.gameObject.name.EndsWith("ICON"))
{
string realObjName = hit.transform.gameObject.name.Substring(0, finalObject.gameObject.name.Length - 4);
finalObject = GameObject.Find(realObjName).transform;
}
foreach (KeyValuePair<string, Vector3> pair in targetObjectAndPosition)
{
if (finalObject.gameObject.name == pair.Key)
{
Vector3 targetPos = pair.Value;
//float realTransitionDuration = Vector3.Distance(mainCamera.transform.position, targetPos) / 50f;50m每秒的飞行速度
//realTransitionDuration = Mathf.Clamp(realTransitionDuration, 0.8f, 1.5f);
transitionDuration= Mathf.Clamp(Vector3.Distance(mainCamera.transform.position, targetPos) / 50f, 0.5f, 1.5f);
StartCoroutine(MoveCamera(mainCamera, targetPos, transitionDuration, finalObject));
}
}
core = finalObject.position;
}
}
private IEnumerator ResetClickState()
{
yield return new WaitForSeconds(doubleClickInterval);
waitingSecondClick = false;
}
private IEnumerator MoveCamera(Camera cam, Vector3 targetPos, float duration, Transform focusTarget)
{
Vector3 startPos = cam.transform.position;
float elapsed = 0f;
while (elapsed < duration)
{
float t = Mathf.Lerp(0f, 1f, elapsed / duration);
cam.transform.position = Vector3.Lerp(startPos, targetPos, t);
if (focusTarget != null)
cam.transform.LookAt(focusTarget);
elapsed += Time.deltaTime;
waitingSecondClick = false;//这一步是你在每一帧我都让你不等下一次点击,
//防止你再飞的过程中手速快双击的话还能飞到其他地方,
//这样我一直给你设成 false你怎么样都不能再飞第二次
//还有一个作用就是我单击跳转的时候也会持续触发,所以即使 UI 和实物重合,
//我也是 UI 先出发,本身 UI 的优先级就比物理碰撞的优先级要高
flying = true;
yield return null;
}
cam.transform.position = targetPos;
if (focusTarget != null)
cam.transform.LookAt(focusTarget);
if (cam.transform.position.y < 0.01f)
{
Vector3 newPos = cam.transform.position;
// 2. 修改y轴值x、z保持不变
newPos.y = 0.1f;
// 3. 重新赋值给position
cam.transform.position = newPos;//这里埋坑了,如果以后设备真的在地下怎么办,
//有经纬度的高程就是y北溪没有地下的
}
flying = false;
}
public void FlyToIconAndConvertCore(string IconName)//给点击图标使用
{
if (flying)
return;
Transform finalObject = GameObject.Find(IconName.Substring(0, IconName.Length - 4)).transform;
//Unity 的 button 按钮通过 Inspector 没有办法灵活指定参数,
//我在里面把参数写死然后来一一匹配传的参数就是gameobject的名字
foreach (KeyValuePair<string, Vector3> pair in targetObjectAndPosition)
{
if (IconName.Substring(0, IconName.Length - 4) == pair.Key)
{
Vector3 targetPos = pair.Value;
transitionDuration = Mathf.Clamp(Vector3.Distance(mainCamera.transform.position, targetPos) / 50f, 0.5f, 1.5f);
StartCoroutine(MoveCamera(mainCamera, targetPos, transitionDuration, finalObject));
}
}
core = finalObject.position;
}
//给仅显示部分图标使用name是SortingIcons的名字飞行的过程和上面差不多
public void FlyToOverlookAndConvertCore(string name)
{
if (flying)
return;
Transform finalObject = GameObject.Find(name + "ViewPort").transform; //在场景里加对应名的空物体作为伪终点。
foreach (KeyValuePair<string, Vector3> pair in targetObjectAndPosition)
{
if (finalObject.gameObject.name == pair.Key)
{
Vector3 targetPos = pair.Value;
transitionDuration = Mathf.Clamp(Vector3.Distance(mainCamera.transform.position, targetPos) / 50f, 0.5f, 1.5f);
StartCoroutine(MoveCamera(mainCamera, targetPos, transitionDuration, finalObject));
}
}
core = finalObject.position;
}
}