fix:风机初始化代码提交

This commit is contained in:
zhangjiajia
2026-05-20 17:05:47 +08:00
parent 8510a3dcda
commit 9579356ed1
3752 changed files with 1351544 additions and 1 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 500eaa2b56c2c074ab576689486fd19f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,41 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Mute : MonoBehaviour
{
Camera cam;
public GameObject Audio;
// Start is called before the first frame update
void Start()
{
cam = Camera.main;
Audio = GameObject.Find("Enviro 3/Audio");
}
// Update is called once per frame
void Update()
{
}
public void GlobalMute()
{
Audio.SetActive(false);
//Audio.SetActive(false);
}
public void UnMute()
{
Audio.SetActive(true);
//Audio.SetActive(true);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 60c571c6b767316438ed3b3d2e06d714
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4986223817693bc41adb331833d466b5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,44 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MouseSuspensionOneSecond : MonoBehaviour
{
Camera cam;
private float hoverTime = 0f;
// Start is called before the first frame update
void Start()
{
cam = Camera.main;
}
// Update is called once per frame
void Update()
{
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(ray,out RaycastHit hit))
{
if (Vector3.Distance(cam.transform.position, hit.transform.position) < 8f && hit.collider.CompareTag("Target") )
{
hoverTime += Time.deltaTime;
if (hoverTime >= 0.6f)
{
//Debug.Log("dianzhong");
UIManager.Instance.DisplayData(hit.collider.gameObject.name);
hoverTime = -999f;
}
}
else
{
hoverTime = 0f;
UIManager.Instance.HideData();
}
}
else
{
hoverTime = 0f;
UIManager.Instance.HideData();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9b93dbca6c3e12849a52f25e7fc88e34
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 928c1a340fd1ab846a4ce724e1dca34a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,96 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static UnityEngine.Rendering.DebugUI.Table;
public class WeatherAndTime : MonoBehaviour
{
public GameObject Rain;
private Coroutine updateTime;
// Start is called before the first frame update
void Start()
{
updateTime = StartCoroutine(setTimeEveryFrame());
}
// Update is called once per frame
void Update()
{
}
public void Sunny()
{
Enviro.EnviroManager.instance.Weather.ChangeWeather("Clear Sky");
Rain.SetActive(false);
}
public void Sprinkle()
{
Enviro.EnviroManager.instance.Weather.ChangeWeather("Rain");
Rain.SetActive(true);
ParticleSystem.EmissionModule emission = Rain.GetComponent<ParticleSystem>().emission;
emission.rateOverTime = 2000f;
}
public void ModerateRain()
{
Enviro.EnviroManager.instance.Weather.ChangeWeather("Rain");
Rain.SetActive(true);
ParticleSystem.EmissionModule emission = Rain.GetComponent<ParticleSystem>().emission;
emission.rateOverTime = 5000f;
}
public void HeavyRain()
{
Enviro.EnviroManager.instance.Weather.ChangeWeather("Rain");
Rain.SetActive(true);
ParticleSystem.EmissionModule emission = Rain.GetComponent<ParticleSystem>().emission;
emission.rateOverTime = 10000f;
}
public void Storm()
{
Enviro.EnviroManager.instance.Weather.ChangeWeather("Storm");
Rain.SetActive(true);
ParticleSystem.EmissionModule emission = Rain.GetComponent<ParticleSystem>().emission;
emission.rateOverTime = 20000f;
}
public void Snow()
{
Enviro.EnviroManager.instance.Weather.ChangeWeather("Snow");
Rain.SetActive(false);
}
public void Cloudy()
{
Enviro.EnviroManager.instance.Weather.ChangeWeather("Cloudy 1");
Rain.SetActive(false);
}
public void SetTime(int hour)
{
StopCoroutine(updateTime);
Enviro.EnviroManager.instance.Time.hours = hour;
}
public void RealTime()
{
if (updateTime != null)
{
StopCoroutine(updateTime);
}
updateTime=StartCoroutine(setTimeEveryFrame());
}
IEnumerator setTimeEveryFrame()
{
while (true)
{
System.DateTime now = System.DateTime.Now;
//string timeStr = now.ToString("yyyy-MM-dd HH:mm:ss");
//Debug.Log(timeStr);
Enviro.EnviroManager.instance.Time.seconds = now.Second;
Enviro.EnviroManager.instance.Time.minutes = now.Minute;
Enviro.EnviroManager.instance.Time.hours = now.Hour;
Enviro.EnviroManager.instance.Time.days = now.Day;
Enviro.EnviroManager.instance.Time.months = now.Month;
Enviro.EnviroManager.instance.Time.years = now.Year;
yield return null;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b02116be5e5c0bc49acb94346cf1d5cf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9bf67224f56146549938b02b5083f217
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,347 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
public class AskForWEBInfomation : MonoBehaviour
{
[Serializable]
public class IdentifierTextBinding
{
public string identifier;
public TMP_Text targetText;
}
[Header("认证")]
[TextArea(2, 4)]
public string authorization = "tenantCode=DEMO&accessToken=225e1a7ffede96cb5adab3aa98775660f4c6a066";
[Header("编辑器测试地址")]
public string editorFullUrl = "https://3d.gzckgc.cn/api.php/Device/deviceDetail";
[Header("设备SN列表")]
public List<string> deviceSnList = new List<string>
{
"ys_2026020420","ys_2026020419","ys_2026020418","ys_2026020417","ys_2026020416","ys_2026020415"
};
[Header("手动拖拽绑定identifier -> TMP_Text")]
public List<IdentifierTextBinding> bindings = new List<IdentifierTextBinding>();
[Header("显示设置")]
public string valueFormat = "0.##";
public bool includeUnit = true;
private Dictionary<string, TMP_Text> textMap = new Dictionary<string, TMP_Text>();
public bool _isRunning = false;//这个东西只是用来防止手动连点
private void Awake()
{
BuildBindingMap();
}
private void BuildBindingMap()
{
textMap.Clear();
foreach (var binding in bindings)
{
if (binding == null) continue;
if (string.IsNullOrWhiteSpace(binding.identifier)) continue;
if (binding.targetText == null) continue;
textMap[binding.identifier] = binding.targetText;
}
}
private void Start()
{
StartCoroutine(LoadAllDevices());
}
//这个是和前端交互的时候按下的按钮
public void ManuallyLoadOneDevice(string SnWithDeviceName)
{
if (_isRunning)
return;
StartCoroutine(LoadOneDeviceManually(SnWithDeviceName));
}
IEnumerator DelayPart()
{
yield return new WaitForSeconds(2.0f); // 等待2秒
// 这里写延迟执行的代码
Debug.Log("2秒后执行");
}
private IEnumerator LoadAllDevices()
{
if (string.IsNullOrWhiteSpace(authorization) || authorization.Contains("替换"))
{
Debug.LogError("authorization 还没填。");
yield break;
}
foreach (string sn in deviceSnList)
{
yield return StartCoroutine(LoadOneDevice(sn));
}
Debug.Log("全部设备文本更新完成");
}
private IEnumerator LoadOneDevice(string deviceSn)
{
string url = GetRequestUrl();
WWWForm form = new WWWForm();
form.AddField("device_sn", deviceSn);
using (UnityWebRequest req = UnityWebRequest.Post(url, form))
{
req.SetRequestHeader("Accept", "application/json, text/plain, */*");
req.SetRequestHeader("Authorization", authorization);
yield return req.SendWebRequest();
if (req.result != UnityWebRequest.Result.Success)
{
Debug.LogError($"请求失败 | SN={deviceSn} | {req.error}");
yield break;
}
string json = req.downloadHandler.text;
DeviceDetailResponse resp = null;
try
{
resp = JsonUtility.FromJson<DeviceDetailResponse>(json);
}
catch (Exception e)
{
Debug.LogError($"JSON解析失败 | SN={deviceSn} | {e.Message}");
yield break;
}
if (resp == null || resp.status == null)
{
Debug.LogError($"响应为空 | SN={deviceSn}");
yield break;
}
if (resp.status.code != 0)
{
Debug.LogError($"业务失败 | SN={deviceSn} | code={resp.status.code} | msg={resp.status.msg}");
yield break;
}
if (resp.result == null || resp.result.data_points == null || resp.result.data_points.timeseries == null)
{
Debug.LogWarning($"没有 timeseries 数据 | SN={deviceSn}");
yield break;
}
foreach (DevicePoint point in resp.result.data_points.timeseries)
{
if (point == null) continue;
if (string.IsNullOrWhiteSpace(point.identifier)) continue;
UpdateText(point.identifier, point.value, point.unitName, point.name);
}
}
}
private IEnumerator LoadOneDeviceManually(string deviceSnWithName)//狗日的unity多参数不能用inspector编辑,重载还不能名字相同,烦。。
{
_isRunning = true;
yield return null;
float transitionDuration = Camera.main.transform.GetComponent<DoubleClickToFocus>().transitionDuration;
yield return new WaitForSeconds(transitionDuration+0.01f); // 等待2秒
// 这里写延迟执行的代码
Debug.Log("2秒后执行");
//为了手动点击传出sn和传感器名字命名ys_2026020427_sb_wuxianqingjiaoji001这样用下划线找sn和名字
//我给这个方法重载了,
//分别是手动点击时和自动跳转
//唯一不同就是最下面判断是不是被点击的设备
int first = deviceSnWithName.IndexOf("_");
int second = deviceSnWithName.IndexOf('_', first + 1);
string deviceSn = deviceSnWithName.Substring(0, second);
string iconName = GameObject.Find("ICONS").transform.Find(deviceSnWithName).transform.Find(deviceSnWithName.Substring(second + 1) + "Text").GetComponent<TextMeshProUGUI>().text;
//传感器的名字。用这个 object 里面的 text。无法用 gameobject. find 直接找到子对象,先找它的父对象,然后用父对象找子对象。
string url = GetRequestUrl();
WWWForm form = new WWWForm();
form.AddField("device_sn", deviceSn);
using (UnityWebRequest req = UnityWebRequest.Post(url, form))
{
req.SetRequestHeader("Accept", "application/json, text/plain, */*");
req.SetRequestHeader("Authorization", authorization);
yield return req.SendWebRequest();
if (req.result != UnityWebRequest.Result.Success)
{
Debug.LogError($"请求失败 | SN={deviceSn} | {req.error}");
yield break;
}
string json = req.downloadHandler.text;
DeviceDetailResponse resp = null;
try
{
resp = JsonUtility.FromJson<DeviceDetailResponse>(json);
}
catch (Exception e)
{
Debug.LogError($"JSON解析失败 | SN={deviceSn} | {e.Message}");
yield break;
}
if (resp == null || resp.status == null)
{
Debug.LogError($"响应为空 | SN={deviceSn}");
yield break;
}
//此部分为手动获取数据和自动获取数据的唯一区别。
SendData sendData = new SendData();
sendData.result = resp.result;
sendData.iconName = iconName;
string CoutJsonData = JsonUtility.ToJson(sendData,true);
Application.ExternalCall("sendDataToVue", CoutJsonData);
//Debug.Log(CoutJsonData);
if (resp.status.code != 0)
{
Debug.LogError($"业务失败 | SN={deviceSn} | code={resp.status.code} | msg={resp.status.msg}");
yield break;
}
if (resp.result == null || resp.result.data_points == null || resp.result.data_points.timeseries == null)
{
Debug.LogWarning($"没有 timeseries 数据 | SN={deviceSn}");
yield break;
}
foreach (DevicePoint point in resp.result.data_points.timeseries)
{
if (point == null) continue;
if (string.IsNullOrWhiteSpace(point.identifier)) continue;
UpdateText(point.identifier, point.value, point.unitName, point.name);
}
}
_isRunning = false;//协程运行完成自动解锁。
Debug.Log("单次查询完成");
}
private void UpdateText(string identifier, string valueStr, string unitName, string itemName)
{
if (!textMap.TryGetValue(identifier, out TMP_Text target) || target == null)
{
Debug.LogWarning($"没有绑定 identifier: {identifier}");
return;
}
string finalText = valueStr;
if (float.TryParse(valueStr, NumberStyles.Any, CultureInfo.InvariantCulture, out float value))
{
finalText = value.ToString(valueFormat, CultureInfo.InvariantCulture);
}
if (includeUnit)//&& !string.IsNullOrWhiteSpace(unitName)
{
finalText += unitName;
finalText = itemName + ": " + finalText;
}
target.text = finalText;
}
private string GetRequestUrl()
{
#if UNITY_WEBGL && !UNITY_EDITOR
return "/api.php/Device/deviceDetail";
#else
return editorFullUrl;
#endif
}
[ContextMenu("重建绑定字典")]
private void RebuildBindings()
{
BuildBindingMap();
Debug.Log("绑定字典已重建");
}
[Serializable]
public class DeviceDetailResponse
{
public ApiStatus status;
public DeviceResult result;
}
[Serializable]
public class ApiStatus
{
public int code;
public string msg;
}
[Serializable]
public class DeviceResult
{
public int device_id;
public string device_name;
public string device_sn;
public string status;
public string online_status;
public string location;
public string address;
public string pic;
public DataPoints data_points;
}
[Serializable]
public class SendData
{
public string iconName;
public DeviceResult result;
}
[Serializable]
public class DataPoints
{
public DevicePoint[] control;
public DevicePoint[] timeseries;
}
[Serializable]
public class DevicePoint
{
public string point_id;
public string name;
public string alias;
public string identifier;
public string unitName;
public string unitIdentifier;
public string accessMode;
public string dataType;
public string value;
public string callback_time;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 18246a8c5681fa3439fde2cea9ba3aea
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,70 @@
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
public class FastSlowAnimationANDZoomIN : MonoBehaviour
{
public Camera cam;
public Camera workerCamera;
//Animator anim;
public float maxHeight = 2f; // 最大上升高度(米)
float scaleRation = 0.5f;//默认缩放系数
public float upTime = 1.5f;// 上升到最高点所需时间(秒)
private Dictionary<Transform, Vector3> childrenStartPos = new Dictionary<Transform, Vector3>();
// Start is called before the first frame update
void Start()
{
cam = Camera.main;
// workerCamera = GameObject.Find("WorkerCamera").GetComponent<Camera>();zhe行代码为什么会引起 bug目前还不清楚
foreach (Transform child in transform)
{
childrenStartPos[child] = child.position;
}
}
// Update is called once per frame
void Update()
{
if (cam.gameObject.activeInHierarchy == true)
{
//自由视角下的动画逻辑
foreach (Transform child in transform)//每个孩子就是一个世界空间的大画布
{
//通过遍历每个子物体,每个物体的大小是独立计算的,不能取最小值
float dist = Vector3.Distance(child.position, cam.transform.position);
float scale = scaleRation * dist / 30f;
scale = Mathf.Clamp(scale, 0.0333f, 10f);
maxHeight = 0.05f + (dist - 1f) * 0.9f / 49f;
maxHeight = Mathf.Clamp(maxHeight, 0.05f, 2f);
float yOffset = Mathf.PingPong(Time.time * (maxHeight / upTime), maxHeight);
child.position = childrenStartPos[child] + new Vector3(0, yOffset, 0);
child.localScale = Vector3.one * scale;
child.LookAt(child.position + cam.transform.forward);//看相机
//transform.LookAt(transform.position + target.forward);
}
}
else
{
//切换到工人视角下所放和浮动在这里
foreach (Transform child in transform)//每个孩子就是一个世界空间的大画布
{
float yOffset = Mathf.PingPong(Time.time * (0.3f / upTime), 0.3f);
child.position = childrenStartPos[child] + new Vector3(0, yOffset, 0);
child.localScale = Vector3.one * 0.3f;
child.LookAt(child.position + workerCamera.transform.forward);//看相机
//transform.LookAt(transform.position + target.forward);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b9b0e3f3c35a5b841829631672af3cd0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7ecb74b5777741e41a17f224352daba9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,76 @@
using Enviro;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static UnityEngine.Rendering.DebugUI.Table;
public class LightManager : MonoBehaviour
{
public enum SwitchCondition { turnON,turnOFF};
SwitchCondition currentCondition;
SwitchCondition lightCondition;
private List<Light> streetLightingAndAutomativeLighting;
// Start is called before the first frame update
void Start()
{
var streetLightings=GameObject.FindGameObjectsWithTag("StreetLighting");
var automativeLightings = GameObject.FindGameObjectsWithTag("AutomativeLighting");
streetLightingAndAutomativeLighting = new List<Light>();
for (int i = 0; i < streetLightings.Length; i++)
{
streetLightingAndAutomativeLighting.Add(streetLightings[i].GetComponent<Light>());
}
for (int i = 0; i < automativeLightings.Length; i++)
{
streetLightingAndAutomativeLighting.Add(automativeLightings[i].GetComponent<Light>());
}
UpdateLight();
}
// Update is called once per frame
void Update()
{
//System.DateTime now = System.DateTime.Now;
int hour = Enviro.EnviroManager.instance.Time.hours;
if (hour >= 6 && hour <= 18)
{
currentCondition = SwitchCondition.turnOFF;
}
else
{
currentCondition = SwitchCondition.turnON;
}
if (currentCondition != lightCondition)
{
UpdateLight();
}
}
void UpdateLight()
{
int hour = Enviro.EnviroManager.instance.Time.hours;
//System.DateTime now = System.DateTime.Now;
if (hour >= 6 && hour <= 18)//°×Ìì
{
lightCondition = SwitchCondition.turnOFF;
foreach (var light in streetLightingAndAutomativeLighting)
{
light.enabled = false;
}
}
else//ÍíÉÏ
{
lightCondition = SwitchCondition.turnON;
foreach (var light in streetLightingAndAutomativeLighting)
{
light.enabled = true;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 826a15849d68a714f8520ec9a1584c39
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ff3b04630a566da47910993dfba8e638
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,192 @@
using UnityEngine;
using UnityEngine.EventSystems;
public class ControlMoving : MonoBehaviour
{
public float moveSpeed = 50f; // 右键平移速度
public float zoomSpeed = 10f; // 滚轮缩放速度
public DoubleClickToFocus doubleClickToFocusScript; // 引用焦点脚本,提供 core
public float rotationSensitivity = 0.2f; // 左键拖拽旋转灵敏度
private Camera cam;
private bool isRotating = false;
private Vector2 lastMousePos;
void Start()
{
cam = Camera.main;
Vector3 core = doubleClickToFocusScript.core;
if (doubleClickToFocusScript == null)
Debug.LogError("请在 Inspector 中把挂有 ClickToFocus 的物体拖给 inScript");
}
void Update()
{
//if (EventSystem.current != null && EventSystem.current.IsPointerOverGameObject())
//{
// return; // 直接 return你下面所有相机逻辑都不执行
//}
//if (SliderDragDetector.isSliderDragging)
// return;
//if (doubleClickToFocusScript == null) return;
Vector3 core = doubleClickToFocusScript.core;
// —— 右键平移 ——
if (Input.GetMouseButton(1))
{
moveSpeed = Vector3.Distance(core, transform.position) / 2f;//这里涉及到像素和实际空间米的关系转换
float mx = Input.GetAxis("Mouse X");
float my = Input.GetAxis("Mouse Y");
Vector3 desiredPosition = cam.transform.position + (-cam.transform.right * mx + -cam.transform.up * my) * moveSpeed * Time.deltaTime;
// 判断是否与障碍物发生碰撞
if (!WillCollideWithObstacle(desiredPosition))
{
cam.transform.position = desiredPosition;
}
}
// —— 滚轮缩放 ——
float scroll = Input.GetAxis("Mouse ScrollWheel");
if (Mathf.Abs(scroll) > 0.001f)
{
Vector3 desiredPosition = cam.transform.position + cam.transform.forward * scroll * zoomSpeed;
// 判断是否与障碍物发生碰撞
if (!WillCollideWithObstacle(desiredPosition))
{
cam.transform.position = desiredPosition;
}
}
// —— 左键开始/结束旋转 ——
if (Input.GetMouseButtonDown(0))
{
isRotating = true;
lastMousePos = Input.mousePosition;
}
if (Input.GetMouseButtonUp(0))
{
isRotating = false;
}
// —— 左键拖拽RotateAround 实现 + 俯仰限制 ——
if (isRotating && Input.GetMouseButton(0))
{
Vector2 curr = Input.mousePosition;
Vector2 delta = (curr - lastMousePos) * rotationSensitivity;
lastMousePos = curr;
// 1. 水平绕世界 Y 轴旋转
//Vector3 desiredPosition = cam.transform.position;
//cam.transform.RotateAround(core, Vector3.up, delta.x);
Vector3 localPosHorizonal = cam.transform.position - core;
Quaternion rotationHorizonal = Quaternion.AngleAxis(delta.x, Vector3.up);
Vector3 newLocalPosHorizonal = rotationHorizonal * localPosHorizonal;//四元数*向量,旋转轴永远经过向量的起点
Vector3 newPosHorizonal = core + newLocalPosHorizonal;
// 检查旋转后是否发生碰撞
if (!WillCollideWithObstacle(newPosHorizonal))
{
// 如果没有碰撞,执行旋转
cam.transform.RotateAround(core, Vector3.up, delta.x);
}
else
{
// 如果碰撞了,就不动
}
// 2. 俯仰旋转
//Vector3 dir = (cam.transform.position - core).normalized;
//Vector3 flat = new Vector3(dir.x, 0f, dir.z).normalized;
//相机看的方向是正 z 方向。也是 forward 的方向。
float selfFlatX = cam.transform.forward.x;
float selfFlatZ = cam.transform.forward.z;
Vector3 selfFlat = new Vector3(selfFlatX, 0f, selfFlatZ).normalized;//把相机看的方向。在世界空间留下水平X Z。垂直量(Y)去掉。
//第一个参数和第二个参数绕着第三个参数(绕着 right 旋转),取值在-180~180
//cam.transform.right永远是垂直着你所看到的方向的所以它垂直着你的这个selfFlat和cam.transform.forward
//这么做是为了得到你的相机,抬头或者是低头度数是多少
//既然是从平面开始,终点是上或下,原则上应该遵循顺时针为正,逆时针为负。
float selfPitch = Vector3.SignedAngle(selfFlat, cam.transform.forward, cam.transform.right);//俯视为正仰视为负cam.transform.right这玩意是旋转轴
if (selfPitch <= 80f && selfPitch >= -80f)
{
float pitchDelta = delta.y * -1f;
Vector3 localPosVertical = cam.transform.position - core;
Quaternion rotationVertical = Quaternion.AngleAxis(pitchDelta, cam.transform.right);//构造出cam.transform.right绕着旋转pitchDelta的旋转值
Vector3 newPosVertical = core + rotationVertical * localPosVertical;//rotationVertical * localPosVertical这个量是旋转中心指向新位置的向量。
//某个物体的 rotation 等于一个四元数这是一种用法还有就是用四元素来相乘qA * qB = 先旋转 qB再旋转 qA
//我这里是用四元素乘一个向量是把这个向量按照四元素的内容来旋转可以想象把cam.transform.right平移到旋转中心他肯定很永远和地面平行并且和localPosVertical垂直。
//给localPosVertical这个向量按照rotationVertical旋转
// 判断是否与障碍物发生碰撞
//整体思路是先手动判断RotateAround的落脚点是否碰撞然后再使用
if (!WillCollideWithObstacle(newPosVertical))
{
cam.transform.RotateAround(core, cam.transform.right, pitchDelta);
}
}
else if (selfPitch > 80f)
{
float pitchDelta = delta.y * -1f;
if (pitchDelta < 0f)
{
cam.transform.RotateAround(core, cam.transform.right, pitchDelta);
}
}
else if (selfPitch < -80f)
{
float pitchDelta = delta.y * -1f;
if (pitchDelta > 0f)
{
cam.transform.RotateAround(core, cam.transform.right, pitchDelta);
}
}
}
}
// 碰撞检测方法
bool WillCollideWithObstacle(Vector3 targetPosition)
{
// 计算从当前位置到目标位置的方向和距离
Vector3 moveDir = targetPosition - cam.transform.position;
float moveDist = moveDir.magnitude;
// 使用 SphereCast 检查即将到达的位置是否会与障碍物发生碰撞
RaycastHit hit;
if (Physics.SphereCast(cam.transform.position, 0.08f, moveDir, out hit, moveDist, LayerMask.GetMask("Default"), QueryTriggerInteraction.Ignore) )
{
// 如果检测到碰撞,返回 true
Debug.Log("collider");
return true;
}
else if ( Mathf.Pow(targetPosition.x+36f, 2f)+ Mathf.Pow(targetPosition.z+15f , 2f)<250000f && targetPosition.y<300f)
{
// 如果在范围内,返回 false
return false;
}
else
Debug.Log("outRange");
return true;//这个true是为了有返回值实际上走不到这一步
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b23207c5903af2f4b98b735175e8852d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,368 @@
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;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 305f95b3ceedd6043babd042de2ea318
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0f9f32f70dec08a488a75d5ad2d3601b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,53 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BaseMgr<T>:MonoBehaviour where T : MonoBehaviour
{
private static T instance;
public static T Instance
{
//get
//{
// if (instance == null)
// instance = new T();
// return instance;
//}
get
{
//if (instance == null)
//{
// GameObject obj = new GameObject();
// obj.name = typeof(T).ToString();
// instance = obj.AddComponent<T>();
// DontDestroyOnLoad(obj);
//}
return instance;
}
}
protected virtual void Awake()
{
instance = this as T;
}
//public static T GetInstance()
//{
// if (instance == null)
// instance = new T();
// return instance;
//}
}
//public class SelfUIManager : MonoBehaviour
//{
// //public ima
// public static GameObject pickUPHint;
// private void Awake()
// {
// if (pickUPHint == null)
// {
// pickUPHint = GameObject.Find("PickUp");
// }
// }
//}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 604158ae0ee59df4f8a4db8b61b992ca
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: db8f02e226eb91748ac6a3469878a8a4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,14 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
public class SkipUnitySplash : MonoBehaviour
{
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSplashScreen)]
static void OnBeforeSplash()
{
// 打包后运行时,直接停掉启动画面
SplashScreen.Stop(SplashScreen.StopBehavior.StopImmediate);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 80f25d5d367c9274e842cf52a8e3861b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 410b270eca23bfe4aadcc4d64d3f0d1d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class ConnectToRealSluicesHeight : MonoBehaviour
{
[Serializable]
public class SluicesSliderBinding
{
public GameObject sluice;
public GameObject slider;
}
public List<SluicesSliderBinding> bindings = new List<SluicesSliderBinding>();
private Dictionary<GameObject, Vector3> sluiceInitialLocalPosition = new Dictionary<GameObject, Vector3>();
void Start()
{
foreach (var binding in bindings)
{
sluiceInitialLocalPosition[binding.sluice] = binding.sluice.transform.localPosition;
}
}
void Update()
{
foreach (var binding in bindings)
{
Slider sliderComp = binding.slider.GetComponent<Slider>();
Vector3 initLocalPos = sluiceInitialLocalPosition[binding.sluice];
binding.sluice.transform.localPosition = new Vector3(
initLocalPos.x,
initLocalPos.y + sliderComp.value,
initLocalPos.z
);
binding.slider.transform.Find("Text (TMP)").GetComponent<TextMeshProUGUI>().text =
binding.slider.name.Substring(6) + "#" + ": " + sliderComp.value.ToString("F1");
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 435a1377c29de3e48a8aff544627f80f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,31 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ModifySluiceHeightManually : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
//setHeight("sluice1", 1.5f);
//setHeight("sluice2,1.5");
//setHeight("sluice1,1.5");
//Debug.Log("aaaa");
}
// Update is called once per frame
void Update()
{
}
//public void setHeight(string sluiceName,float height)
//{
// transform.Find("Sliders/" + sluiceName).GetComponent<Slider>().value = height;
//}
public void setHeight(string sluiceNameAndHeight)
{
string[] parts = sluiceNameAndHeight.Split(',');
transform.Find("Sliders/" + parts[0]).GetComponent<Slider>().value = float.Parse(parts[1]);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 82f187734168bad498845ae9a9967cc6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,63 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class OneKeyOperation : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void AllOpen()
{
foreach(Transform child in transform.Find("Sliders").transform)
{
StartCoroutine(SmoothIncreaseToTwo(0.3f, child));
}
}
public void AllClose()
{
foreach (Transform child in transform.Find("Sliders").transform)
{
StartCoroutine(SmoothDecreaseToZero(0.3f, child));
}
}
IEnumerator SmoothDecreaseToZero(float duration,Transform child )
{
float startValue = child.GetComponent<Slider>().value;
float time = 0f;
while (time < duration)
{
time += Time.deltaTime;
startValue = Mathf.Lerp(startValue, 0f, time / duration);
child.GetComponent<Slider>().value = startValue;
yield return null;
}
child.GetComponent<Slider>().value = 0f;
}
IEnumerator SmoothIncreaseToTwo(float duration, Transform child)
{
float startValue = child.GetComponent<Slider>().value;
float time = 0f;
while (time < duration)
{
time += Time.deltaTime;
startValue = Mathf.Lerp(startValue, 2f, time / duration);
child.GetComponent<Slider>().value = startValue;
yield return null;
}
child.GetComponent<Slider>().value = 2f;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8ab7398f0cf55e44982d5db77cffb184
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0c4e033165d6b0b438d356d601068c21
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,142 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DisplayChosenIcons : MonoBehaviour
{
List<string> IconKinds = new List<string>
{
"振动加速度", "沉降监测", "气象监测",
"倾角监测", "应变监测"
};
// 缓存:每个标签 -> 该标签下的所有物体
private Dictionary<string, List<GameObject>> cachedObjects;
private List<Button> allButtons = new List<Button>();
public Camera cam;
// 飞行锁定时间,固定 1.5 秒
public float flyDuration = 1.5f;
private bool flying = false;
void Start()
{
if (cam == null)
cam = Camera.main;
cachedObjects = new Dictionary<string, List<GameObject>>();
// 为每个标签创建一个空列表,并缓存场景物体
foreach (string tag in IconKinds)
{
cachedObjects[tag] = new List<GameObject>();
GameObject[] found = GameObject.FindGameObjectsWithTag(tag);
cachedObjects[tag].AddRange(found);
}
// 绑定按钮点击
foreach (Transform child in transform)
{
Button btn = child.GetComponent<Button>();
if (btn != null)
{
allButtons.Add(btn);
string btnName = child.gameObject.name;
btn.onClick.AddListener(() => OnClickEvent(btnName));
}
}
}
void OnClickEvent(string selectedName)
{
if (cam.gameObject.activeInHierarchy == false)
{
return;
}
// 飞行过程中,所有点击无效
if (flying)
{
return;
}
flying = true;
SetButtonsInteractable(false);
// 1. 立即切换图标显示
ApplyDisplay(selectedName);
// 2. 开始飞行
if (cam != null)
{
DoubleClickToFocus focus = cam.GetComponent<DoubleClickToFocus>();
if (focus != null)
{
focus.FlyToOverlookAndConvertCore(selectedName);
}
}
// 3. 1.5 秒后解锁
StartCoroutine(UnlockAfterDelay());
}
IEnumerator UnlockAfterDelay()
{
yield return null;//这里很恶心没有办法确定这个响应函数和DoubleClickToFocus里的update谁先执行
//只能等下一帧里面刷新了飞行时间再说
float transitionDuration = cam.transform.GetComponent<DoubleClickToFocus>().transitionDuration;
yield return new WaitForSeconds(transitionDuration+0.01f);
flying = false;
SetButtonsInteractable(true);
}
void ApplyDisplay(string selectedName)
{
if (selectedName == "全部")
{
foreach (var kvp in cachedObjects)
{
foreach (GameObject obj in kvp.Value)
{
if (obj != null)
obj.SetActive(true);
}
}
}
else
{
// 先全部隐藏
foreach (var kvp in cachedObjects)
{
foreach (GameObject obj in kvp.Value)
{
if (obj != null)
obj.SetActive(false);
}
}
// 再显示当前类别
if (cachedObjects.ContainsKey(selectedName))
{
foreach (GameObject obj in cachedObjects[selectedName])
{
if (obj != null)
obj.SetActive(true);
}
}
}
}
void SetButtonsInteractable(bool enable)
{
foreach (Button btn in allButtons)
{
if (btn != null)
btn.interactable = enable;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 51f6b204c89295e4fb54a7998c71be15
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 124100b5f0b252a419ba900d91ff1d3f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,65 @@
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
//public enum UILayer { HUD,Main,Popup}
public class UIManager : BaseMgr<UIManager>
{
//这里面要维护很多数据,
//基本上所有的覆盖全屏 UI 的对象都要覆盖,
//涉及到 UI 外面的也会有一些全部使用 public
//目前他控制的应该只是某个UI的显示与否就是Setactive其他的逻辑不要写
//find找不到禁用对象解决的办法就是不要把任何对象设置禁用哪怕费点事禁用全部组件就行
//这样除了在update里面不要写find之外哪里都能找到这个gameobject了
//调试归调试,但是还是要给前端调用接口,还是要分散到当事对象上面
//比如启用工人视角这个函数就应该放在工人这个gameobject上面
public GameObject mainCamera;
public GameObject worker;
public GameObject PopUpCanvas;
public Transform ICONS;
protected override void Awake()
{
base.Awake();
}
public void ConvertToWorkerView()
{
mainCamera.SetActive(false);
worker.SetActive(true);
for (int i = 0; i < ICONS.childCount; i++)
{
ICONS.GetChild(i).transform.localScale = Vector3.one * 0.5f;//工人视角下重置大小
}
}
public void ConvertToFreeView()
{
mainCamera.SetActive(true);
worker.SetActive(false);
}
public void DisplayData(string targetName)
{
if (PopUpCanvas.transform.Find(targetName) != null)
{
PopUpCanvas.transform.Find(targetName).gameObject.SetActive(true);
}
}
public void HideData()
{
for(int i = 0; i < PopUpCanvas.transform.childCount; i++)
{
PopUpCanvas.transform.GetChild(i).gameObject.SetActive(false);
}
}
public void CloseSluicesHeight()
{
PopUpCanvas.transform.Find("Sluices").gameObject.SetActive(false);
}
public void OpenSluicesHeight()
{
PopUpCanvas.transform.Find("Sluices").gameObject.SetActive(true);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8153d9aea4752894d8436f1c525dafee
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: edf26518729fa024ca108689392dd1c3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,22 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LookAtWorkerCam : MonoBehaviour
{
public Transform WorldIcons;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
for (int i = 0; i < WorldIcons.childCount; i++)
{
WorldIcons.GetChild(i).transform.LookAt(WorldIcons.GetChild(i).transform.position + transform.forward);//¿´Ïà»ú
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9f9a89b00b4a76742a3ae50fd7160e5f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 64a10dae871f32c4e8d9a163a4b99dff
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,147 @@
using Cinemachine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
//using static UnityEditor.Searcher.SearcherWindow.Alignment;
public class ControlMovingAndAnimation : MonoBehaviour
{
public Camera workerCamera;
public GameObject bear;
//Animation part
private Animator anim;
private CharacterController chara;
private NavMeshAgent agent;
//control moving part
float Gravity = -9.8f;
float yVelocity = 0f;
private float MoveSpeed = 4f;
// cinamachine part
public CinemachineFreeLook freeLook;
public Transform head;
private Vector3 lastPosition;
//hit part
// private Vector3 lastPos;
//public Transform hitPoint;
// public float radius = 0.3f;
// private HashSet<Collider> hitTargets = new HashSet<Collider>();
// public bool isAttacking = false;
void Start()
{
// lastPosition = transform.position;
anim = GetComponent<Animator>();
// agent = GetComponent<NavMeshAgent>();
chara = GetComponent<CharacterController>();
//lastPos = hitPoint.position;
}
// Update is called once per frame
void Update()
{
//这些是点哪走哪
//Vector3 currentPosition = transform.position;
//if (currentPosition != lastPosition)
//{
// anim.SetBool("IsWalking", true);
//}
//else
//{
// anim.SetBool("IsWalking", false);
//}
//lastPosition = currentPosition;
//if (Input.GetMouseButtonDown(0))
//{
// Ray r = workerCamera.ScreenPointToRay(Input.mousePosition);
// if (Physics.Raycast(r, out RaycastHit hit))
// {
// agent.SetDestination(hit.point);
// }
//}
//这些是键盘逻辑
FreeFalling();
PlayAnimations();
Move();
}
private void FreeFalling()
{
if (chara.isGrounded && yVelocity < 0f)
yVelocity = -2f;
else
yVelocity += Gravity * Time.deltaTime;
chara.Move(new Vector3(0f, yVelocity, 0f) * Time.deltaTime);
}
private void PlayAnimations()
{
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.S))
{
anim.SetBool("IsWalking", true);
}
else
{
anim.SetBool("IsWalking", false);
}
if (Input.GetKey(KeyCode.LeftShift))
{
MoveSpeed = 8f;
anim.SetBool("IsRunning", true);
}
else
{
MoveSpeed = 4f;
anim.SetBool("IsRunning", false);
}
if (Input.GetKeyDown(KeyCode.Space) && chara.isGrounded)
{
anim.SetTrigger("Jump");
yVelocity = Mathf.Sqrt(20f);//向上初速度为根号10米每秒大概跳0.5米
}
//if (Input.GetMouseButtonDown(0))
//{
// anim.SetTrigger("Fight");
// // StartAttacking();
//}
}
private void Move()
{
Vector3 cameraWorldPos = freeLook.transform.position;//虚拟相机的位置
Vector3 cameraToPlayerHeadVector = (head.position - cameraWorldPos).normalized;//相机指向角色的头,这个代表指向方向向量
Vector3 horizontalDirection = new Vector3(cameraToPlayerHeadVector.x, 0, cameraToPlayerHeadVector.z).normalized;//指向向量去除y方向再归一化
Vector3 cameraRight = Vector3.Cross(Vector3.up, horizontalDirection).normalized;//垂直于相机指向,右手边
float DeltaHorizontal = Input.GetAxis("Horizontal");
float DeltaVertical = Input.GetAxis("Vertical");//两个方向位移检测 -1到1
Vector3 forwardMove = horizontalDirection * DeltaVertical;//视线指向方向乘上你按键的量,决定前进还是后退 W必然前进s必然朝你走
//Vector3 rightMove = cameraRight * DeltaHorizontal;
//Vector3 move = forwardMove + rightMove;
//Vector3 realMove = move.normalized * MoveSpeed * Time.deltaTime;
Vector3 realMove = forwardMove * MoveSpeed * Time.deltaTime;
chara.Move(realMove);
if (forwardMove.sqrMagnitude > 0f)
{
Quaternion targetRotation = Quaternion.LookRotation(forwardMove);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 5f);
}
}
//public void StartAttacking()
//{
// isAttacking = true;
// hitTargets.Clear();
//}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 58bf345e57e03a24fa0fd3bd4905190d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: