123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616 |
- using SC.XR.Unity;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.IO;
- using UnityEngine;
- public class SafetyAreaManager : SingletonMono<SafetyAreaManager>
- {
- //是否已从配置文件中读取安全区域
- private static bool hasReadFromFile = false;
- public Action OnBeginSetSafeArea;
- public Action OnFinishSetSafeArea;
- public Action OnEnterSafetyArea;
- public Action OnExitSafetyArea;
- public Action<bool> OnDisableSafetyArea;
- public Action<bool> OnDoubleTapShowSafetyArea;
- private Dictionary<SafetyAreaStepEnum, ISafetyAreaStep> areaStepDic;
- private GameObject safetyAreaGameObject;
- private SafetyAreaMono safetyAreaMono;
- private ISafetyAreaStep currentStep;
- [HideInInspector]
- public StationaryAreaMono stationaryAreaMono;
- private GameObject stationaryAreaObject;
- [HideInInspector]
- public PlayAreaMono playAreaMono;
- private GameObject playAreaObject;
- [HideInInspector]
- public bool isDisableSafetyArea = false;
- [HideInInspector]
- public bool isSettingSafetyArea = false;
- [HideInInspector]
- public bool onlySettingGroundHeight = false;
- [HideInInspector]
- public bool doubleTapShowSeeThrough = true;
- private bool showAreaWhenBowHead = true;
- private float originAlphaParam = 0.4f;
- private int originSafetyAreaColorIndex = 0;
- private SafetyAreaInfo currentSafetyAreaInfo = null;
- private bool alreayExitSafetyArea = false;
- public bool DoubleClickShowSeeThrough
- {
- get
- {
- return doubleTapShowSeeThrough;
- }
- set
- {
- doubleTapShowSeeThrough = value;
- OnDoubleTapShowSafetyArea?.Invoke(doubleTapShowSeeThrough);
- }
- }
- public bool IsDisableSafetyArea
- {
- get
- {
- return isDisableSafetyArea;
- }
- set
- {
- isDisableSafetyArea = value;
- OnDisableSafetyArea?.Invoke(isDisableSafetyArea);
- }
- }
- public bool ShowAreaWhenBowHead
- {
- get
- {
- if (!hasReadFromFile)
- {
- LoadSafetyArea();
- }
- return showAreaWhenBowHead;
- }
- set
- {
- showAreaWhenBowHead = value;
- SaveSafetyArea();
- }
- }
- public int OriginSafetyAreaColorIndex
- {
- get
- {
- if (!hasReadFromFile)
- {
- LoadSafetyArea();
- }
- return originSafetyAreaColorIndex;
- }
- set
- {
- originSafetyAreaColorIndex = value;
- SaveSafetyArea();
- }
- }
- public float OriginAlphaParam
- {
- get
- {
- if (!hasReadFromFile)
- {
- LoadSafetyArea();
- }
- return originAlphaParam;
- }
- set
- {
- originAlphaParam = value;
- SaveSafetyArea();
- }
- }
- //public Color SafetyAreaColor
- //{
- // get
- // {
- // return safetyAreaColor[originSafetyAreaColorIndex];
- // }
- //}
- public float AlphaParam
- {
- get
- {
- return Mathf.Lerp(0f, 1f, originAlphaParam);
- }
- }
- //private GameObject savedSafetyArea;
- private void Awake()
- {
- DontDestroyOnLoad(this.gameObject);
- }
- private IEnumerator Start()
- {
- SafetyAreaLanguageManager.Instance.Init();
- //yield return new WaitUntil(() => GSXRManager.Instance.Initialized);
- yield return null;
- if (!hasReadFromFile)
- {
- LoadSafetyArea();
- }
- API_GSXR_Slam.GSXR_Add_SlamPauseCallback(OnLoading);
- }
- private void OnDestroy()
- {
- API_GSXR_Slam.GSXR_Remove_SlamPauseCallback(OnLoading);
- }
- private void Init(object data)
- {
- InitSafetyAreaMono();
- InitStep(safetyAreaMono);
- safetyAreaMono.Init(data);
- }
- private void Release()
- {
- OnFinishSetSafeArea?.Invoke();
- if (safetyAreaMono != null)
- {
- safetyAreaMono.Release();
- GameObject.Destroy(safetyAreaGameObject);
- safetyAreaMono = null;
- areaStepDic = null;
- }
- }
- private void InitStep(SafetyAreaMono safetyAreaMono)
- {
- if (areaStepDic == null)
- {
- areaStepDic = new Dictionary<SafetyAreaStepEnum, ISafetyAreaStep>();
- areaStepDic.Add(SafetyAreaStepEnum.GroundHeight, new GroundHeightStep(safetyAreaMono));
- areaStepDic.Add(SafetyAreaStepEnum.PlayArea, new PlayAreaStep(safetyAreaMono));
- areaStepDic.Add(SafetyAreaStepEnum.StationaryArea, new StationaryAreaStep(safetyAreaMono));
- //areaStepDic.Add(SafetyAreaStepEnum.ConfirmPlayArea, new ConfirmPlayAreaStep());
- }
- }
- private void InitSafetyAreaMono()
- {
- if (safetyAreaMono == null)
- {
- GameObject safetyAreaMonoResource = Resources.Load<GameObject>("SafetyAreaMono");
- safetyAreaGameObject = GameObject.Instantiate(safetyAreaMonoResource);
- safetyAreaMono = safetyAreaGameObject.GetComponent<SafetyAreaMono>();
- }
- //safetyAreaMono.Init();
- }
- //创建原地区域
- public void CreateStationarySafetyArea()
- {
- if (stationaryAreaMono == null)
- {
- stationaryAreaObject = new GameObject(PlayAreaConstant.STATIONARY_NAME);
- stationaryAreaObject.layer = 9;//1 << LayerMask.NameToLayer("SafetyArea");
- float groundHeight = 0f;//GetStep<GroundHeightStep>(SafetyAreaStepEnum.GroundHeight).GetPlaneHeight();
- Mesh cylinderMesh = SafetyAreaVertexHelper.GenerateCylinderMesh(new Vector3(0, groundHeight, 0), groundHeight + PlayAreaConstant.SAFETY_AREA_HEIGHT, groundHeight, PlayAreaConstant.STATIONARY_AREA_RADIUS);
- stationaryAreaMono = stationaryAreaObject.AddComponent<StationaryAreaMono>();
- stationaryAreaMono.Init();
- stationaryAreaMono.SetMesh(cylinderMesh, PlayAreaConstant.STATIONARY_AREA_RADIUS);
- }
- }
- //销毁原地区域
- public void DestroyStationaryArea()
- {
- if (stationaryAreaObject != null)
- {
- GameObject.Destroy(stationaryAreaObject);
- }
- stationaryAreaObject = null;
- stationaryAreaMono = null;
- }
- //创建安全网格
- public void CreatePlayArea(Mesh mesh, Color[] colors, float perimeter, Vector3 worldPosition)
- {
- if (playAreaObject != null)
- {
- GameObject.Destroy(playAreaObject);
- }
- playAreaObject = new GameObject(PlayAreaConstant.PLAY_AREA_NAME);
- playAreaObject.layer = LayerMask.NameToLayer("SafetyArea");
- playAreaObject.transform.position = new Vector3(worldPosition.x, 0f, worldPosition.z);
- playAreaMono = playAreaObject.AddComponent<PlayAreaMono>();
- playAreaMono.Init();
- playAreaMono.SetMesh(mesh, colors, perimeter);
- }
- public void DestroyPlayArea()
- {
- if (playAreaObject != null)
- {
- Debug.LogError("Destroy playAreaObject");
- GameObject.Destroy(playAreaObject);
- }
- playAreaObject = null;
- playAreaMono = null;
- }
- public void StartSetSafetyArea(object data = null)
- {
- if (safetyAreaMono != null)
- {
- Debug.LogError("last set safety area process not complete");
- return;
- }
- //if (savedSafetyArea != null)
- //{
- // savedSafetyArea.SetActive(false);
- //}
- Init(data);
- isSettingSafetyArea = true;
- OnBeginSetSafeArea?.Invoke();
- DestroyExistSafetyArea();
- SafetyAreaCommandBuffer.Instance.AddLoading();
- API_GSXR_Slam.GSXR_ResaveMap("forTest");
- API_GSXR_Slam.GSXR_StartSeeThrough();
- API_GSXR_Slam.GSXR_Add_SlamPauseCallback(OnSlamPause);
- }
- public void StartSetSafetyAreaHeight()
- {
- if (!CheckSafetyAreaExist())
- {
- StartSetSafetyArea();
- return;
- }
- onlySettingGroundHeight = true;
- Init(null);
- OnBeginSetSafeArea?.Invoke();
- API_GSXR_Slam.GSXR_StartSeeThrough();
- API_GSXR_Slam.GSXR_Add_SlamPauseCallback(OnSlamPause);
- }
- //判断安全区域是否存在
- public bool CheckSafetyAreaExist()
- {
- if (!hasReadFromFile)
- {
- LoadSafetyArea();
- }
- GameObject playArea = GameObject.Find(PlayAreaConstant.PLAY_AREA_NAME);
- if (playArea != null)
- {
- return true;
- }
- GameObject stationaryArea = GameObject.Find(PlayAreaConstant.STATIONARY_NAME);
- if (stationaryArea != null)
- {
- return true;
- }
- return false;
- }
- public SafetyAreaTypeEnum GetSafetyAreaType()
- {
- if (!CheckSafetyAreaExist()) return SafetyAreaTypeEnum.None;
- GameObject playArea = GameObject.Find(PlayAreaConstant.PLAY_AREA_NAME);
- if (playArea != null)
- {
- return SafetyAreaTypeEnum.PlayArea;
- }
- GameObject stationaryArea = GameObject.Find(PlayAreaConstant.STATIONARY_NAME);
- if (stationaryArea != null)
- {
- return SafetyAreaTypeEnum.Stationary;
- }
- return SafetyAreaTypeEnum.None;
- }
- //重新设置安全区域高度
- //public void ResetSafetyAreaHeight()
- //{
- // GameObject playArea = GameObject.Find(PlayAreaConstant.PLAY_AREA_NAME);
- // if (playArea != null)
- // {
- // playArea.GetComponent<PlayAreaMono>().ResetPlaneHeight(GetStep<GroundHeightStep>(SafetyAreaStepEnum.GroundHeight).GetPlaneHeight());
- // }
- // GameObject stationaryArea = GameObject.Find(PlayAreaConstant.STATIONARY_NAME);
- // if (stationaryArea != null)
- // {
- // stationaryArea.GetComponent<StationaryAreaMono>().ResetPlaneHeight(GetStep<GroundHeightStep>(SafetyAreaStepEnum.GroundHeight).GetPlaneHeight());
- // }
- //}
- public void DestroyExistSafetyArea()
- {
- GameObject playArea = GameObject.Find(PlayAreaConstant.PLAY_AREA_NAME);
- if (playArea != null)
- {
- playArea.GetComponent<PlayAreaMono>().Release();
- GameObject.Destroy(playArea);
- }
- GameObject stationaryArea = GameObject.Find(PlayAreaConstant.STATIONARY_NAME);
- if (stationaryArea != null)
- {
- stationaryArea.GetComponent<StationaryAreaMono>().Release();
- GameObject.Destroy(stationaryArea);
- }
- }
- public void ExitSafeAreaStep()
- {
- if (currentStep != null)
- {
- currentStep.OnExitStep();
- }
- currentStep = null;
- Release();
- API_GSXR_Slam.GSXR_Remove_SlamPauseCallback(OnSlamPause);
- API_GSXR_Slam.GSXR_StopSeeThrough();
- API_GSXR_Slam.GSXR_SaveMap();
- isSettingSafetyArea = false;
- onlySettingGroundHeight = false;
- stationaryAreaMono = null;
- stationaryAreaObject = null;
- playAreaMono = null;
- playAreaObject = null;
- SaveSafetyArea(true);
- }
- private void LoadSafetyArea()
- {
- hasReadFromFile = true;
- if (!File.Exists(PlayAreaConstant.SAVE_FILE_NAME))
- {
- currentSafetyAreaInfo = new SafetyAreaInfo();
- return;
- }
- string fileStr = File.ReadAllText(PlayAreaConstant.SAVE_FILE_NAME);
- currentSafetyAreaInfo = JsonUtility.FromJson<SafetyAreaInfo>(fileStr);
- showAreaWhenBowHead = currentSafetyAreaInfo.showAreaWhenBowHead;
- originAlphaParam = currentSafetyAreaInfo.originAlphaParam;
- originSafetyAreaColorIndex = currentSafetyAreaInfo.originSafetyAreaColorIndex;
- if (string.IsNullOrEmpty(currentSafetyAreaInfo.safetyAreaName))
- {
- return;
- }
- Mesh edgeMesh = new Mesh();
- edgeMesh.vertices = currentSafetyAreaInfo.vertices.ToArray();
- edgeMesh.uv = currentSafetyAreaInfo.uv.ToArray();
- edgeMesh.triangles = currentSafetyAreaInfo.triangles.ToArray();
- GameObject safetyArea = new GameObject(currentSafetyAreaInfo.safetyAreaName);
- safetyArea.transform.position = currentSafetyAreaInfo.position;
- MeshRenderer meshRenderer = safetyArea.AddComponent<MeshRenderer>();
- MeshFilter meshFilter = safetyArea.AddComponent<MeshFilter>();
- meshFilter.mesh = edgeMesh;
- meshRenderer.sharedMaterial = Resources.Load<Material>("Material/SafetyEdgeMat_Normal");
- SafetyAreaBase safetyAreaBase = null;
- if (currentSafetyAreaInfo.safetyAreaName == PlayAreaConstant.PLAY_AREA_NAME)
- {
- safetyAreaBase = safetyArea.AddComponent<PlayAreaMono>();
- safetyArea.GetComponent<PlayAreaMono>().Init();
- safetyArea.GetComponent<PlayAreaMono>().SetColor(currentSafetyAreaInfo.colors.ToArray());
- }
- else
- {
- safetyAreaBase = safetyArea.AddComponent<StationaryAreaMono>();
- safetyArea.GetComponent<StationaryAreaMono>().Init();
- safetyArea.GetComponent<StationaryAreaMono>().SetRadius(currentSafetyAreaInfo.radius);
- }
- //safetyAreaBase.SetOriginHeight(currentSafetyAreaInfo.originHeight);
- safetyAreaBase.SetPerimeter(currentSafetyAreaInfo.perimeter);
- }
- private void SaveSafetyArea(bool overrideVertexData = false)
- {
- if (overrideVertexData)
- {
- if (CheckSafetyAreaExist())
- {
- GameObject playArea = GameObject.Find(PlayAreaConstant.PLAY_AREA_NAME);
- if (playArea != null)
- {
- currentSafetyAreaInfo.safetyAreaName = PlayAreaConstant.PLAY_AREA_NAME;
- currentSafetyAreaInfo.position = playArea.transform.position;
- currentSafetyAreaInfo.vertices = new List<Vector3>(playArea.GetComponent<MeshFilter>().mesh.vertices);
- currentSafetyAreaInfo.triangles = new List<int>(playArea.GetComponent<MeshFilter>().mesh.triangles);
- currentSafetyAreaInfo.uv = new List<Vector2>(playArea.GetComponent<MeshFilter>().mesh.uv);
- //currentSafetyAreaInfo.originHeight = playArea.GetComponent<SafetyAreaBase>().GetOriginHeight();
- currentSafetyAreaInfo.perimeter = playArea.GetComponent<SafetyAreaBase>().GetPerimter();
- currentSafetyAreaInfo.colors = new List<Color>(playArea.GetComponent<PlayAreaMono>().GetColor());
- }
- GameObject stationaryArea = GameObject.Find(PlayAreaConstant.STATIONARY_NAME);
- if (stationaryArea != null)
- {
- currentSafetyAreaInfo.safetyAreaName = PlayAreaConstant.STATIONARY_NAME;
- currentSafetyAreaInfo.position = stationaryArea.transform.position;
- currentSafetyAreaInfo.vertices = new List<Vector3>(stationaryArea.GetComponent<MeshFilter>().mesh.vertices);
- currentSafetyAreaInfo.triangles = new List<int>(stationaryArea.GetComponent<MeshFilter>().mesh.triangles);
- currentSafetyAreaInfo.uv = new List<Vector2>(stationaryArea.GetComponent<MeshFilter>().mesh.uv);
- //currentSafetyAreaInfo.originHeight = stationaryArea.GetComponent<SafetyAreaBase>().GetOriginHeight();
- currentSafetyAreaInfo.perimeter = stationaryArea.GetComponent<SafetyAreaBase>().GetPerimter();
- currentSafetyAreaInfo.radius = stationaryArea.GetComponent<StationaryAreaMono>().GetRadius();
- }
- }
- else
- {
- currentSafetyAreaInfo.safetyAreaName = string.Empty;
- currentSafetyAreaInfo.position = Vector3.zero;
- currentSafetyAreaInfo.vertices = null;
- currentSafetyAreaInfo.triangles = null;
- currentSafetyAreaInfo.uv = null;
- currentSafetyAreaInfo.originHeight = 0f;
- }
- }
- currentSafetyAreaInfo.showAreaWhenBowHead = ShowAreaWhenBowHead;
- currentSafetyAreaInfo.originAlphaParam = OriginAlphaParam;
- currentSafetyAreaInfo.originSafetyAreaColorIndex = OriginSafetyAreaColorIndex;
- if (!File.Exists(PlayAreaConstant.SAVE_FILE_NAME))
- {
- if (!Directory.Exists(Path.GetDirectoryName(PlayAreaConstant.SAVE_FILE_NAME)))
- {
- Directory.CreateDirectory(Path.GetDirectoryName(PlayAreaConstant.SAVE_FILE_NAME));
- }
- File.Create(PlayAreaConstant.SAVE_FILE_NAME).Dispose();
- }
- File.WriteAllText(PlayAreaConstant.SAVE_FILE_NAME, JsonUtility.ToJson(currentSafetyAreaInfo));
- }
- public void DestroySafetyArea()
- {
- if (CheckSafetyAreaExist())
- {
- DestroyExistSafetyArea();
- }
- SaveSafetyArea();
- }
- public T GetStep<T>(SafetyAreaStepEnum safetyAreaStepEnum) where T : class, ISafetyAreaStep
- {
- if (!areaStepDic.ContainsKey(safetyAreaStepEnum))
- {
- return default(T);
- }
- return areaStepDic[safetyAreaStepEnum] as T;
- }
- public void ChangeStep(SafetyAreaStepEnum safetyAreaStep, object data = null)
- {
- if (currentStep != null)
- {
- currentStep.OnExitStep();
- }
- ISafetyAreaStep nextStep = areaStepDic[safetyAreaStep];
- nextStep.OnEnterStep(data);
- currentStep = nextStep;
- }
- public SafetyAreaStepEnum GetCurrentStepEnum()
- {
- if (currentStep == null) return SafetyAreaStepEnum.Null;
- return currentStep.GetStepEnum();
- }
- public void UserCancelStep()
- {
- if (currentStep != null)
- {
- currentStep.OnUserCancel();
- }
- }
- public void DelayExitSafeAreaStep(float delayTime, Action onExitComplete)
- {
- StartCoroutine(ExitSafeAreaStepCoroutine(delayTime, onExitComplete));
- }
- public void DelayChangeStep(SafetyAreaStepEnum safetyAreaStep, float delayTime)
- {
- StartCoroutine(ChangeStepCoroutine(safetyAreaStep, delayTime));
- }
- public void ExitSafetyAreaInvoke()
- {
- if (!alreayExitSafetyArea)
- {
- alreayExitSafetyArea = true;
- OnExitSafetyArea?.Invoke();
- }
- }
- public void EnterSafetyAreaInvoke()
- {
- if (alreayExitSafetyArea)
- {
- alreayExitSafetyArea = false;
- OnEnterSafetyArea?.Invoke();
- }
- }
- private IEnumerator ChangeStepCoroutine(SafetyAreaStepEnum safetyAreaStep, float delayTime)
- {
- yield return new WaitForSeconds(delayTime);
- ChangeStep(safetyAreaStep);
- }
- private IEnumerator ExitSafeAreaStepCoroutine(float delayTime, Action onExitComplete)
- {
- yield return new WaitForSeconds(delayTime);
- onExitComplete?.Invoke();
- ExitSafeAreaStep();
- }
- public void DelayShow(float delayTime, Action delayMethod)
- {
- StartCoroutine(DelayShowCoroutine(delayTime, delayMethod));
- }
- private IEnumerator DelayShowCoroutine(float delayTime, Action delayMethod)
- {
- yield return new WaitForSeconds(delayTime);
- delayMethod?.Invoke();
- }
- private void OnSlamPause(bool isPause)
- {
- if (!isPause)
- {
- API_GSXR_Slam.GSXR_StartSeeThrough();
- }
- }
- private void OnLoading(bool isPause)
- {
- if (!isPause)
- {
- SafetyAreaCommandBuffer.Instance.AddLoading();
- }
- }
- }
|