using System.Collections; using System.Collections.Generic; using Unity.Collections; using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems; using UnityEngine.UI; namespace Seengene.XDKUnityPluginCloud { public class CloudDemoController : MonoBehaviour { #region Properties [Header("Base Settings")] /// /// XDK会话对象 /// private XDKCloudSession m_XDKCloudSession = null; [SerializeField] private Transform m_ARHead = null; /// /// 场景参照根对象 /// [SerializeField] private Transform m_SceneRoot = null; /// /// 是否开始算法重定位 /// [SerializeField] private Toggle m_ToggleRelocationOn = null; [Header("Debug Setttings")] /// /// 输入日志开关 /// [SerializeField] private Toggle m_ToggleLogOn = null; /// /// 保存图片到本地开关 /// [SerializeField] private Toggle m_ToggleSaveImages = null; /// /// 模拟首次定位成功 /// [SerializeField] private Button m_BtnSimulatFirstRelocSuccess = null; /// /// 提示信息 /// [SerializeField] private Text m_InfoSceneRoot = null; [SerializeField] private Text m_InfoUpdateFrameNative = null; [SerializeField] private Text m_InfoGetSpatialMappingNative = null; /// /// 定位时间间隔 /// private float m_Interval; /// /// 上一次定位时间 /// private float m_LastTime; /// /// 预览图 /// [SerializeField] private RawImage m_PreviewImage = null; private bool ifShowKeyPoints = true; [SerializeField] private GameObject keyPointPrefab = null; List keyPointsList = new List(); [Header("Smooth Move Settings")] [SerializeField] SmoothMoveType m_SmoothMoveType = SmoothMoveType.Linear; [SerializeField] float m_SmoothMoveTime = 1.0f; Vector3 m_StartPosition = Vector3.zero; Quaternion m_StartRotation = Quaternion.identity; Vector3 m_TargetPosition = Vector3.zero; Quaternion m_TargetRotation = Quaternion.identity; [Header("Unity Events")] /// /// 首次重定位成功事件 /// [SerializeField] private UnityEvent m_OnFirstRelocationSuccessEvent = new UnityEvent(); /// /// Debug模式切换事件 /// [SerializeField] private UnityEventBool m_OnDebugModeChangeEvent = new UnityEventBool(); #endregion #region Unity Methods private void Awake() { m_XDKCloudSession = GetComponent(); m_LastTime = Time.realtimeSinceStartup; if (XDKConfigs.IfSaveImages) { m_ToggleSaveImages.isOn = true; } else { m_ToggleSaveImages.isOn = false; } m_ToggleSaveImages.onValueChanged.AddListener(OnSaveImagesLogChanged); if (XDKConfigs.IfLogOn) { m_ToggleLogOn.isOn = true; } else { m_ToggleLogOn.isOn = false; } m_ToggleLogOn.onValueChanged.AddListener(OnLogOnToggleChanged); if (XDKConfigs.IfRelocationOn) { m_ToggleRelocationOn.isOn = true; } else { m_ToggleRelocationOn.isOn = false; } m_ToggleRelocationOn.onValueChanged.AddListener(OnToggleRelocationOnChanged); if (m_XDKCloudSession != null) m_XDKCloudSession.OnUpdateDebugInfoEvent += OnOnUpdateDebugInfo; if (m_BtnSimulatFirstRelocSuccess != null) { m_BtnSimulatFirstRelocSuccess.onClick.AddListener(() => { m_XDKCloudSession.SimulateFirstRelocatSuccess(); }); } } private void OnEnable() { if (m_XDKCloudSession != null) { m_XDKCloudSession.SpatialMappedEvent += OnSpatialMapped; m_XDKCloudSession.OnFirstRelocationSuccessEvent += OnFirstRelocationSuccess; m_XDKCloudSession.UpdatePreviewImageEvent += OnPreviewImageEvent; if (ifShowKeyPoints) m_XDKCloudSession.UpdateKeyPointsEvent += OnUpdateKeyPoints; } XDKConfigs.OnDebugModeChange += OnDebugModeChangeEvent; } private void OnDisable() { if (m_XDKCloudSession != null) { m_XDKCloudSession.SpatialMappedEvent -= OnSpatialMapped; m_XDKCloudSession.OnFirstRelocationSuccessEvent -= OnFirstRelocationSuccess; m_XDKCloudSession.UpdatePreviewImageEvent -= OnPreviewImageEvent; if (ifShowKeyPoints) m_XDKCloudSession.UpdateKeyPointsEvent -= OnUpdateKeyPoints; } XDKConfigs.OnDebugModeChange -= OnDebugModeChangeEvent; } private void Update() { if (XDKConfigs.IfDebugOn && m_ARHead != null) { m_InfoSceneRoot.text = string.Format("\nPos:{0},Rot:{1},Scale:{2}\n\nPos:{3},Rot:{4}\n {5}", m_SceneRoot.position.ToString("f2"), m_SceneRoot.eulerAngles.ToString("f2"), m_SceneRoot.localScale.ToString("f2"), m_ARHead.position.ToString("f2"), m_ARHead.eulerAngles.ToString("f2"), m_Interval.ToString("f2") ); } } #endregion #region Private Methods private void OnSpatialMapped(Vector3 position, Quaternion rotation, Vector3 scale, int relocSuccessCounter) { m_Interval = Time.realtimeSinceStartup - m_LastTime; m_LastTime = Time.realtimeSinceStartup; if (m_SceneRoot != null) { if (relocSuccessCounter == 1) { m_SceneRoot.localScale = scale; m_SceneRoot.localPosition = position; m_SceneRoot.localRotation = rotation; } else { m_SceneRoot.localScale = scale; StopCoroutine("CorMoveToTarget"); m_TargetPosition = position; m_TargetRotation = rotation; StartCoroutine("CorMoveToTarget"); } } } IEnumerator CorMoveToTarget() { m_StartPosition = m_SceneRoot.position; m_StartRotation = m_SceneRoot.rotation; float factor = 0; while (factor != 1) { factor += Time.deltaTime / m_SmoothMoveTime; factor = Mathf.Clamp01(factor); if (m_SmoothMoveType == SmoothMoveType.Linear) { m_SceneRoot.position = Vector3.Lerp(m_StartPosition, m_TargetPosition, factor); m_SceneRoot.rotation = Quaternion.Lerp(m_StartRotation, m_TargetRotation, factor); } else { m_SceneRoot.position = Vector3.Lerp(m_SceneRoot.position, m_TargetPosition, factor); m_SceneRoot.rotation = Quaternion.Lerp(m_SceneRoot.rotation, m_TargetRotation, factor); } yield return new WaitForEndOfFrame(); } } private void OnUpdateKeyPoints(List points) { keyPointsList.ForEach((go) => { DestroyImmediate(go); }); keyPointsList.Clear(); for (int i = 0; i < points.Count; i++) { GameObject go = Instantiate(keyPointPrefab, m_SceneRoot); go.transform.localPosition = new Vector3(points[i].x, -points[i].y, points[i].z); keyPointsList.Add(go); } } private void OnPreviewImageEvent(Texture texture) { m_PreviewImage.texture = texture; m_PreviewImage.rectTransform.sizeDelta = new Vector2(texture.width, texture.height); } private void OnFirstRelocationSuccess() { Debug.Log("首次重定位成功!"); if (m_OnFirstRelocationSuccessEvent != null) m_OnFirstRelocationSuccessEvent.Invoke(); } private void OnOnUpdateDebugInfo(string debugInfo, DebugInfoType type) { switch (type) { case DebugInfoType.UpdateFrameNative: m_InfoUpdateFrameNative.text = debugInfo; break; case DebugInfoType.GetSpatialMappingNative: m_InfoGetSpatialMappingNative.text = debugInfo; break; default: break; } } private void OnSaveImagesLogChanged(bool value) { XDKConfigs.IfSaveImages = value; m_PreviewImage.gameObject.SetActive(value); } private void OnLogOnToggleChanged(bool value) { XDKConfigs.IfLogOn = value; } private void OnToggleRelocationOnChanged(bool value) { XDKConfigs.IfRelocationOn = value; if (XDKConfigs.IfLogOn) { string strDebug; if (XDKConfigs.IfRelocationOn) { strDebug = "开启重定位功能!"; } else { strDebug = "关闭重定位功能!"; } Debug.Log(strDebug); } } private void OnDebugModeChangeEvent() { Debug.LogFormat("OnDebugModeChangeEvent: {0}", XDKConfigs.IfDebugOn); if (m_OnDebugModeChangeEvent != null) m_OnDebugModeChangeEvent.Invoke(XDKConfigs.IfDebugOn); if (XDKConfigs.IfDebugOn == false) { ///清空关键点 if (keyPointsList != null) { keyPointsList.ForEach((go) => { DestroyImmediate(go); }); keyPointsList.Clear(); } } } #endregion } }