using LitJson; using SC.XR.Unity; using System; using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; using UnityEngine.UI; /* * 半自动交付/自动交付 * 景点、触发范围、水晶点应保持顺序对应 * 当前场景下景点名称不应重复 * 同一景点下素材名称不应重复 * ListShowObjs/ListColliderBoxs/ListCrystals半自动时在场景中推拽,全自动时全部由代码生成 * * 新增锚点列表 * 锚点识别图Vuforia XML和DAT文件 * 各个锚点的位置信息 * * 每次打开都下载vuforia文件 * 自动加载生成ImageTarget * */ public class GameManager : MonoSingleton { public Text text; public GameObject Map; /// /// 景点ID与对应的素材组合 /// [SerializeField, Tooltip("景点对应的物体及景点下的素材")] private Dictionary ObjectValues = new Dictionary(); public List ColliderObjectValues = new List(); [Header("Spoit")] [Tooltip("景点对应的显示物体")] public List ListShowObjs; [Tooltip("景点对应的显示物体,本地添加物体")] public List ListLocalShowObjs; public bool isShowLoacalShowObjs = false; [Tooltip("景点对应的物体触发范围")] public List ListColliderBoxs; private List ListColiderBoxs_Mesh; [Tooltip("景点对应的水晶点")] public List ListCrystals; [Tooltip("景点对应的显示物体父物体")] public Transform ObjsParent; [Tooltip("触发器父物体")] public Transform CollidersParent; [Tooltip("水晶点父物体")] public Transform CrystalsParent; [Tooltip("锚点父物体")] public Transform AnchorsParent; public GameObject ColliderItem; public GameObject CrystalItem; [Space(20)] [Tooltip("是否显示路径")] public bool IsShowLuJIng = true; [Tooltip("是否为编辑模式")] public bool IsEditor = true; [Tooltip("是否是全自动显示景点")] public bool IsAuto = true; [SerializeField, Tooltip("路径控制器")] private RouteCtr RouteCtr; [SerializeField, Tooltip("素材编辑器")] private EditorPanel m_EditorPanel; [SerializeField, Tooltip("计算人物在地图上的位置")] [Header("MinMap")] private CalMap m_CalMap; [SerializeField, Tooltip("小地图信息")] private MinMap m_MinMap; [Header("Setting")] [SerializeField, Tooltip("设置面板")] private SettingPanel m_SettingPanel; [SerializeField, Tooltip("编辑器面板")] private Transform m_EditorCanvas; [SerializeField, Tooltip("设置按钮")] private Transform m_SetBtn; [Header("地图比例")] public Transform PointA; public Transform PointB; public Transform PointC; public Transform PointD; public bool isStart; // 场景四个点已经确定 public Vector2 WebMapSize; public Vector2 MapSize; public Vector2 MinMapSize = new Vector2(320, 135); public string MapPicUrl; public GameObject ernieBot; [Header("展厅")] public GameObject MRZhanTing; public bool isPlayMRZhanTing; public IrobotMove m_IroBot; [Header("Player")] public PlayerTrigger Player; [Header("Head")] public Transform m_head; [Header("虚拟导游")] public List Irobots; /// /// 是否在触发区域内 /// private bool m_IsTriggerExiting; /// /// 是否在触发区域内 /// public bool IsTriggerExiting { get { return m_IsTriggerExiting; } set { m_IsTriggerExiting = value; } } /// /// 是否可以开始编辑素材 /// private bool m_IsStartEditor; /// /// 是否可以开始编辑素材 /// public bool IsStartEditor { get { return m_IsStartEditor; } set { m_IsStartEditor = value; } } /// /// 素材加载完成,素材prefab生成完成,开始进入运行状态 /// public bool m_IsRuning; /// /// 素材加载完成,素材prefab生成完成,开始进入运行状态 /// public bool IsRuning { get { return m_IsRuning; } set { m_IsRuning = value; } } /// /// 当前触发物体的下标 /// private int m_SpoitIndex; /// /// 当前触发物体的下标 /// public int SpoitIndex { get { return m_SpoitIndex; } set { m_SpoitIndex = value; } } /// /// 当前场景数据 /// public SceneValue m_SceneValue; /// /// 当前场景数据 /// public SceneValue SceneValue { get { return m_SceneValue; } set { m_SceneValue = value; } } /// /// 当前场景中的景点信息 /// private List m_SpoitValues; /// /// 当前场景中的景点信息 /// public List SpoitValues { get { return m_SpoitValues; } set { m_SpoitValues = value; } } /// /// 景点详情数据 /// private Dictionary m_SpoitsValueDetail; /// /// 景点详情数据 /// public Dictionary SpoitsValueDetail { get { return m_SpoitsValueDetail; } set { m_SpoitsValueDetail = value; } } public UIAnchorsPanel m_UIAnchorsPanel; private Dictionary m_AnchorValue; public Dictionary AnchorValue { get { return m_AnchorValue; } set { m_AnchorValue = value; } } private Dictionary m_AnchorChild; public Dictionary AnchorChild { get { return m_AnchorChild; } set { m_AnchorChild = value; } } private void Awake() { // Debug.unityLogger.logEnabled = false; } private void Start() { // PlayerPrefs.DeleteAll(); isStart = false; m_SpoitsValueDetail = new Dictionary(); m_AnchorValue = new Dictionary(); m_AnchorChild = new Dictionary(); SceneValue = null; m_IsStartEditor = false; m_IsRuning = false; m_SetBtn.gameObject.SetActive(false); //CalMapSize(); SpoitIndex = -1; SpoitValues = new List(); if (m_EditorPanel == null) { m_EditorPanel = GameObject.FindObjectOfType(); } if (!IsAuto) { //GetObjectValue(); //CreateSpoitValue(); } else { ListShowObjs = new List(); ListColliderBoxs = new List(); ListColiderBoxs_Mesh = new List(); ListCrystals = new List(); // ListLocalShowObjs = new List(); } m_MinMap.gameObject.SetActive(false); Map.SetActive(false); } private void LateUpdate() { if (OpenXRCamera.Instance.head != null && m_IsRuning) { m_SetBtn.transform.localEulerAngles = new Vector3(0, OpenXRCamera.Instance.head.localEulerAngles.y, 0); //m_SetBtn.transform.position = API_GSXR_Slam.GSXR_Get_Head().localPosition + Player.transform.forward * 1.3f+ new Vector3(0, 1f, 0); //m_SetBtn.transform.localPosition = API_GSXR_Slam.GSXR_Get_Head().localPosition + Player.transform.forward * 1.3f + new Vector3(0, 1f, 0); m_SetBtn.transform.position = OpenXRCamera.Instance.head.position + Player.transform.forward * 1.3f + new Vector3(-0.2f, 1f, 0); } } public void Init() { } private void InitCrystals() { for (int i = 0; i < ListCrystals.Count; i++) { ListCrystals[i].gameObject.SetActive(true); } } private void InitBoxColliders() { for (int i = 0; i < ListColliderBoxs.Count; i++) { ListColliderBoxs[i].gameObject.SetActive(true); } } public void IntoScene() { Map.SetActive(true); //GameObject.Instantiate(Resources.Load("ARCamera")); //ImageTargetManager.Instance.LoadVuforiaDat(); //API_GSXR_Slam.GSXR_Get_Head().localPosition = new Vector3(23.57f, 2.5f, 16.74f); //API_GSXR_Slam.GSXR_Get_Head().localEulerAngles = new Vector3(0, -35.9f, 0); StartCoroutine(StartScene(isPlayMRZhanTing)); HttpSocket.Instance.SendIpToElectric(); } IEnumerator StartScene( bool isPlayMRZhanTing) { yield return new WaitForSeconds(0.5f); if(isPlayMRZhanTing) { //if (!string.IsNullOrWhiteSpace(DataManager.Instance.CurrentScene.sandTable)) //{ MRZhanTing.gameObject.SetActive(true); MRZhanTing.transform.position = API_GSXR_Slam.GSXR_Get_Head().position + API_GSXR_Slam.GSXR_Get_Head().forward + new Vector3(0, -0.7f, 0); MRZhanTing.transform.localEulerAngles = new Vector3(0, API_GSXR_Slam.GSXR_Get_Head().eulerAngles.y, 0); yield return new WaitForSeconds(18f); MRZhanTing.gameObject.SetActive(false); //} } m_SettingPanel.gameObject.SetActive(true); m_EditorPanel.Init(); m_SettingPanel.Init(); if (RouteCtr.CurrentPoints.Count > 0) { Player.MovePoints = RouteCtr.CurrentPoints; //判断选择那个虚拟导游 //int id = ChooseIroBot(); //if (id < 3) //{ //m_IroBot = Irobots[id - 1]; m_IroBot.gameObject.SetActive(true); m_IroBot.Points = RouteCtr.CurrentPoints; yield return new WaitForSeconds(5f); //} } IsRuning = true; m_SetBtn.gameObject.SetActive(true); InitCrystals(); InitBoxColliders(); ernieBot.SetActive(true); } private int ChooseIroBot() { int id = 3; var navlines = DataManager.Instance.CurrentScene.navLines; if (navlines.Count > 0) { id = navlines[0].guideMod; } return id; } /// /// 若为半自动显示素材,需要获取景点物体来为ObjectValues赋值 /// private void GetObjectValue() { //for (int i = 0; i < ListShowObjs.Count; i++) //{ // var spoit = ListShowObjs[i]; // List values = new List(); // ObjectValue objectValue = new ObjectValue(i, -1, spoit.name, spoit.gameObject, spoit.localPosition, spoit.localEulerAngles, spoit.localScale); // var editors = spoit.GetComponentsInChildren(); // for (int j = 1; j < editors.Length; j++) // { // var obj = editors[j]; // ObjectValue value = new ObjectValue(j, i, obj.name, obj.gameObject, obj.transform.localPosition, obj.transform.localEulerAngles, obj.transform.localScale); // objectValue.ChildrenObj.Add(value); // } // values.Add(objectValue); // ObjectValues.Add(i, values); //} } /// /// 半自动时创建景点信息 /// //private void CreateSpoitValue() //{ // if (SpoitValues == null) // { // SpoitValues = new List(); // } // SpoitValues.Clear(); // foreach (int id in ObjectValues.Keys) // { // var item = ObjectValues[id]; // SpoitValue spoit = new SpoitValue(); // spoit.id = item[0].ID; // spoit.name = item[0].matName; // for (int i = 0; i < item.Count; i++) // { // var objs = item[i]; // MaterialObl materialObl = new MaterialObl(); // materialObl.id = objs.ID; // materialObl.name = objs.matName; // materialObl.type = 0; // OjectTransform ojectTransform = new OjectTransform(objs.Object.transform.localPosition, objs.Object.transform.localEulerAngles, objs.Object.transform.localScale); // for (int m = 0; m < objs.ChildrenObj.Count; m++) // { // var obj = objs.ChildrenObj[i]; // MaterialObjValue mat = new MaterialObjValue(); // mat.name = obj.matName; // mat.type = 0; // mat.objectTransform = new OjectTransform(obj.Object.transform.localPosition, obj.Object.transform.localEulerAngles, obj.Object.transform.localScale); // materialObl.materialList.Add(mat); // } // spoit.material.Add(materialObl); // SpoitValues.Add(spoit); // } // } //} #region 设置功能 public void OnEditorBtnValueChanged(bool ison) { m_EditorCanvas.gameObject.SetActive(ison); m_IsStartEditor = ison; for (int i = 0; i < ListColiderBoxs_Mesh.Count; i++) { ListColiderBoxs_Mesh[i].enabled = ison; } if (ison) { GetPosRotScale(); // 获取所有物体位置旋转缩放 m_EditorCanvas.position = API_GSXR_Slam.GSXR_Get_Head().position + Player.transform.forward + new Vector3(0, 0.5f, 0); m_EditorCanvas.eulerAngles = new Vector3(0, API_GSXR_Slam.GSXR_Get_Head().eulerAngles.y, 0); } else { SetPosRotScale();// 设置所有物体位置旋转缩放 m_EditorCanvas.position = API_GSXR_Slam.GSXR_Get_Head().position + new Vector3(0, 100, 0); if (SpoitIndex >= 0 && !IsTriggerExiting) { ListShowObjs[SpoitIndex].gameObject.SetActive(false); if (isShowLoacalShowObjs) ListLocalShowObjs[SpoitIndex].gameObject.SetActive(false); ListCrystals[SpoitIndex].gameObject.SetActive(true); m_EditorPanel.ClosePanel(); SpoitIndex = -1; } } } public void OnSettingBtnValueChanged(bool ison) { m_SettingPanel.gameObject.SetActive(ison); if (ison) { Debug.Log(API_GSXR_Slam.GSXR_Get_Head().forward); m_SettingPanel.transform.position = API_GSXR_Slam.GSXR_Get_Head().position + Player.transform.forward; m_SettingPanel.transform.eulerAngles = new Vector3(0, API_GSXR_Slam.GSXR_Get_Head().eulerAngles.y, 0); } } public void OnAnchorBtnValueChanged(bool ison) { foreach (var item in m_AnchorValue) { item.Value.enabled = ison; } //foreach (var item in m_AnchorChild) //{ // item.Value.SetActive(ison); //} if(ison) { m_UIAnchorsPanel.transform.position = API_GSXR_Slam.GSXR_Get_Head().position + Player.transform.forward + new Vector3(0, 0.5f, 0); m_UIAnchorsPanel.transform.eulerAngles = new Vector3(0, API_GSXR_Slam.GSXR_Get_Head().eulerAngles.y, 0); } else { m_UIAnchorsPanel.transform.position = API_GSXR_Slam.GSXR_Get_Head().position + new Vector3(0, 100, 0); } } public void GetPosRotScale() { PosRotScale.PosRotScalePatchList.Clear(); for (int i = 0; i < GameManager.Instance.ObjsParent.childCount; i++) { if (i != 0) { for (int j = 0; j < GameManager.Instance.ObjsParent.GetChild(i).childCount; j++) { for (int k = 0; k < GameManager.Instance.ObjsParent.GetChild(i).GetChild(j).childCount; k++) { PosRotScalePatch PosRotScalePatch = new PosRotScalePatch(); PosRotScalePatch.PosPatch = GameManager.Instance.ObjsParent.GetChild(i).GetChild(j).GetChild(k).localPosition; PosRotScalePatch.RotPatch = GameManager.Instance.ObjsParent.GetChild(i).GetChild(j).GetChild(k).localEulerAngles; PosRotScalePatch.ScalePatch = GameManager.Instance.ObjsParent.GetChild(i).GetChild(j).GetChild(k).localScale; PosRotScale.PosRotScalePatchList.Add(PosRotScalePatch); } } } } } public void SetPosRotScale() { if (PosRotScale.PosRotScalePatchList.Count != 0) { int temp = 0; for (int i = 0; i < GameManager.Instance.ObjsParent.childCount; i++) { if (i != 0) { for (int j = 0; j < GameManager.Instance.ObjsParent.GetChild(i).childCount; j++) { for (int k = 0; k < GameManager.Instance.ObjsParent.GetChild(i).GetChild(j).childCount; k++) { GameManager.Instance.ObjsParent.GetChild(i).GetChild(j).GetChild(k).localPosition = PosRotScale.PosRotScalePatchList[temp].PosPatch; GameManager.Instance.ObjsParent.GetChild(i).GetChild(j).GetChild(k).localEulerAngles = PosRotScale.PosRotScalePatchList[temp].RotPatch; GameManager.Instance.ObjsParent.GetChild(i).GetChild(j).GetChild(k).localScale = PosRotScale.PosRotScalePatchList[temp].ScalePatch; temp++; } } } } } } #endregion #region 获取景点信息--素材编辑模式下 /// /// 获取当前景点对应的物体信息 /// /// /// public ObjectValue GetSpoitObjs(int spoitID) { if (ObjectValues.ContainsKey(spoitID)) { return ObjectValues[spoitID]; } else { return null; } } /// /// 初始化数据 /// 素材编辑模式下 /// /// public void InitSpoitObjs() { m_EditorPanel.InitObjTransForm(); } /// /// 保存数据 /// 素材编辑模式下 /// /// public void SaveSpoitObjs() { m_EditorPanel.SaveObjTransForm(); } public void SaveAnchorObjs( string name) { foreach (var item in AnchorValue) // 保存所有锚点 { item.Key.objectTransform.SavePos(item.Value.transform.localPosition, item.Value.transform.localEulerAngles, item.Value.transform.localScale); } // 锚点发送后台 m_UIAnchorsPanel.SaveAnchors(name); } #endregion #region 创建水晶点、触发器范围、显示物体 public void CreateScene(SceneValue scene) { SceneValue = scene; if (m_MinMap.Map.sprite == null) { GetMinMap(scene ); } else { StartCreateScene(scene); } } private void StartCreateScene(SceneValue scene) { if (scene.navLines != null && scene.navLines.Count > 0) SetRouteValue(scene.navLines); else Debug.LogError(" 当前场景未设置路径"); if (scene.listSpoit != null && scene.listSpoit.Count > 0) SetSpoitValue(scene.listSpoit); else Debug.LogError(" 当前场景未创建景点"); if (scene.listPicture != null && scene.listPicture.Count > 0) SetAnchor(scene.listPicture); else Debug.LogError(" 当前场景未创建锚点"); //设置小地图景点 // m_CalMap.SettingMapPoint(ListCrystals); UIManager.Instance.ShowUI(UINameConfig.LoadingPanel, typeof(LoadingPanel), (int)ELoadState.download); DownloadManager.Instance.UpdataData(); } /// /// 获取小地图 /// public void GetMinMap( SceneValue scene ) { DownloadData data1 = new DownloadData(); string filename = Path.GetFileName(MapPicUrl); data1.name = filename; data1.type = 1; data1.downloadPath = MapPicUrl; //data1.updateTime = (int)SceneValue.updateTime; data1.localSavePath = DownloadManager.Instance.LocaDataPath + "/map/" + filename; if(scene.width>0 &&scene.length>0) { Debug.Log(scene.width + " " + scene.length); isStart = true; PointB.position = Vector3.zero; PointB.eulerAngles = Vector3.zero; PointA.position = PointB.position + new Vector3(0, 0, scene.width); PointA.eulerAngles = Vector3.zero; PointC.position = PointB.position + new Vector3(scene.length, 0, 0); PointC.eulerAngles = Vector3.zero; PointD.position = PointB.position + new Vector3(scene.length, 0, scene.width); PointD.eulerAngles = Vector3.zero; m_CalMap.SettingMapPoint(ListCrystals); } DownloadManager.Instance.GetMapImage(data1, m_MinMap.Map, (b, tex) => { if (b) { Sprite sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f, 0.5f)); m_MinMap.Map.sprite = sprite; //m_MinMap.Map.SetNativeSize(); float width = tex.width; float height = tex.height; if(width>height) { width = width / height; height = 1; } else { height = height / width; width = 1; } MinMapSize = new Vector2(width * 150, height * 150); CalMapSize(); m_MinMap.Map.GetComponent().sizeDelta = new Vector2( width*150,height*150 ); //获取网页端 WebMapSize = new Vector2((float)tex.width, (float)tex.height); if (SceneValue != null) { StartCreateScene(SceneValue); } } }); } /// /// 设置景点素材信息 /// /// public void SetSpoitValue(List spoits) { SpoitValue spoitValue; for (int i = 0; i < spoits.Count-1; i++) { spoitValue = null; for (int j = 0; j < spoits.Count-1-i; j++) { if(spoits[j].id>spoits[j+1].id) { spoitValue = spoits[j]; spoits[j] = spoits[j+1]; spoits[j+1] = spoitValue; } } } SpoitValues.Clear(); for (int i = 0; i < spoits.Count; i++) { var spoit = spoits[i]; SpoitValue spoit1 = spoit; CreateCrystalAndTrigger(spoit); CreateMaterial(spoit, out spoit1); spoits[i] = spoit1; } for (int i = 0; i < ListColiderBoxs_Mesh.Count; i++) { ListColiderBoxs_Mesh[i].enabled = false; } SpoitValues.AddRange(spoits); SceneValue.listSpoit = SpoitValues; DataManager.Instance.Spoits = SpoitValues; } /// /// 创建水晶点和触发器 /// private void CreateCrystalAndTrigger(SpoitValue spoit) { var spoitPos = Vector3.zero; if (spoit.SpoitTransform.Count > 0) { Debug.LogFormat("{0}{1}", spoit.name, "景点存在"); SpoitPos trans = spoit.SpoitTransform[0]; spoitPos = new Vector3((float)trans.pointRelativeX / WebMapSize.x * MapSize.x, -1f, -(float)trans.pointRelativeY / WebMapSize.y * MapSize.y); //创建水晶点 var obj = Instantiate(CrystalItem, CrystalsParent); obj.name = spoit.name; obj.transform.localPosition = spoitPos; ListCrystals.Add(obj.transform); var spoitobj = CreateSpoit(spoit, spoitPos); ListShowObjs.Add(spoitobj.transform); ObjectValue spoitvalue = new ObjectValue(spoit.id, -1, spoitobj.name, spoitobj); ObjectValues.Add(spoit.id, spoitvalue); ////创建触发器 //if (SpoitsValueDetail.ContainsKey(spoit.id)) //{ // var spoitdetail = SpoitsValueDetail[spoit.id]; // var range = spoitdetail.triggerRange; // if (range.areaRelativeH == 0 && range.areaRelativeW == 0 && range.areaRelativeX == 0 && range.areaRelativeY == 0) // { // } // else // { // trans = range; // } //} //var tiggerpos = new Vector3((float)trans.areaRelativeX / WebMapSize.x * MapSize.x, -0.5f, -(float)trans.areaRelativeY / WebMapSize.y * MapSize.y); var tiggerpos = new Vector3((float)(trans.areaRelativeX + trans.areaRelativeW / 2) / WebMapSize.x * MapSize.x, -0.5f, -(float)(trans.areaRelativeY + trans.areaRelativeH / 2) / WebMapSize.y * MapSize.y); var tiggerRange = new Vector3((float)trans.areaRelativeW / WebMapSize.x * MapSize.x, 0.1f, (float)trans.areaRelativeH / WebMapSize.y * MapSize.y); var triggerobj = Instantiate(ColliderItem, CollidersParent); triggerobj.name = spoit.name; triggerobj.transform.localPosition = tiggerpos; triggerobj.transform.localScale = tiggerRange; //triggerobj.AddComponent().IsClickEditor = true; ObjectValue boxvalue = new ObjectValue(spoit.id, -1, triggerobj.name, triggerobj); ColliderObjectValues.Add(boxvalue); ListColliderBoxs.Add(triggerobj.transform); ListColiderBoxs_Mesh.Add(triggerobj.GetComponent()); } else { Debug.LogFormat("{0}{1}", spoit.name, "景点不存在"); } } private GameObject CreateSpoit(SpoitValue spoit, Vector3 spoitPos) { //生成景点父物体 GameObject spoitObj = new GameObject(spoit.name); spoitObj.transform.SetParent(ObjsParent.transform); spoitObj.AddComponent().IsClickEditor = false; //为景点位置信息赋值 if (spoit.spoitTf.startPos == Vector3.zero && spoit.spoitTf.nowPos == Vector3.zero) { spoitObj.transform.localPosition = new Vector3(spoitPos.x, 0.5f, spoitPos.z); spoitObj.transform.localRotation = Quaternion.identity; spoitObj.transform.localScale = new Vector3(1, 1, 1); spoit.spoitTf.SetStartValue(spoitObj.transform.localPosition, spoitObj.transform.localEulerAngles, spoitObj.transform.localScale); } else { spoitObj.transform.localPosition = spoit.spoitTf.nowPos; spoitObj.transform.localEulerAngles = spoit.spoitTf.nowRot; spoitObj.transform.localScale = spoit.spoitTf.nowScale; } return spoitObj; } /// /// 创建整体素材 /// 一个景点下应只有一个父物体,其他素材都在父物体下 /// private void CreateMaterial(SpoitValue spoit, out SpoitValue newspoit) { var spoitValues = ObjectValues[spoit.id]; var spoitObj = spoitValues.Object; //生成素材组合 for (int i = 0; i < spoit.material.Count; i++) { //素材整体 MaterialObl material = spoit.material[i]; Debug.Log(spoit.material[i].name); //素材组物体 GameObject matObj = new GameObject(material.name); matObj.transform.SetParent(spoitValues.Object.transform); if (!material.select) { matObj.transform.localPosition = Vector3.zero; matObj.transform.localEulerAngles = Vector3.zero; matObj.transform.localScale = new Vector3(1, 1, 1); material.objectTransform.SetStartValue(matObj.transform.localPosition, matObj.transform.localEulerAngles, matObj.transform.localScale); } else { matObj.transform.localPosition = material.objectTransform.nowPos; matObj.transform.localEulerAngles = material.objectTransform.nowRot; matObj.transform.localScale = material.objectTransform.nowScale; } //素材组合对应ObjectValue的 ObjectValue spoitValue = new ObjectValue(i, spoit.id, material.name, matObj); //素材组合下的单个素材ObjectValue List objsvalue = null; MaterialObl newmaterial = material; //生成素材组合的ObjectValue,是对应景点的 switch (material.type) { case (int)MaterialType.None: break; case (int)MaterialType.Image: case (int)MaterialType.Video: case (int)MaterialType.Model: case (int)MaterialType.Text: case (int)MaterialType.LocaImage: objsvalue = CreateSuCaiObj(material, matObj, out newmaterial); break; case (int)MaterialType.Image_Video_Text: objsvalue = CreateImage_Video_Text(material, matObj, out newmaterial); break; case (int)MaterialType.Model_Text: objsvalue = CreateModel_Text(material, matObj, out newmaterial); break; default: break; } spoit.material[i] = newmaterial; spoitValue.ChildrenObj.AddRange(objsvalue); spoitValues.ChildrenObj.Add(spoitValue); } newspoit = spoit; if (ObjectValues.ContainsKey(spoit.id)) { ObjectValues[spoit.id] = spoitValues; } else { ObjectValues.Add(spoit.id, spoitValues); } spoitObj.gameObject.SetActive(false); } /// /// 编辑面板添加素材 /// /// public void AddMaterial(MaterialObl material) { if (SpoitIndex < 0) { return; } MaterialObl newmaterial = new MaterialObl(); newmaterial = material; var spoit = SpoitValues[SpoitIndex]; var spoitValues = ObjectValues[spoit.id]; var spoitObj = spoitValues.Object; //素材组物体 GameObject matObj = new GameObject(newmaterial.name + "-" + spoit.material.Count.ToString()); newmaterial.name = matObj.name; matObj.transform.SetParent(spoitValues.Object.transform); if (!material.select) { matObj.transform.localPosition = Vector3.zero; matObj.transform.localEulerAngles = Vector3.zero; matObj.transform.localScale = new Vector3(1, 1, 1); newmaterial.objectTransform.SetStartValue(matObj.transform.localPosition, matObj.transform.localEulerAngles, matObj.transform.localScale); } else { matObj.transform.localPosition = newmaterial.objectTransform.nowPos; matObj.transform.localEulerAngles = newmaterial.objectTransform.nowRot; matObj.transform.localScale = newmaterial.objectTransform.nowScale; } //素材组合对应ObjectValue的 ObjectValue spoitValue = new ObjectValue(spoit.material.Count, spoit.id, newmaterial.name, matObj); //素材组合下的单个素材ObjectValue List objsvalue = null; //生成素材组合的ObjectValue,是对应景点的 switch (material.type) { case (int)MaterialType.None: break; case (int)MaterialType.Image: case (int)MaterialType.Video: case (int)MaterialType.Model: case (int)MaterialType.Text: case (int)MaterialType.LocaImage: objsvalue = CreateSuCaiObj(newmaterial, matObj, out newmaterial); break; case (int)MaterialType.Image_Video_Text: objsvalue = CreateImage_Video_Text(newmaterial, matObj, out newmaterial); break; case (int)MaterialType.Model_Text: objsvalue = CreateModel_Text(newmaterial, matObj, out newmaterial); break; default: break; } newmaterial.select = true; spoit.material.Add(newmaterial); spoitValue.ChildrenObj.AddRange(objsvalue); spoitValues.ChildrenObj.Add(spoitValue); if (ObjectValues.ContainsKey(spoit.id)) { ObjectValues[spoit.id] = spoitValues; } else { ObjectValues.Add(spoit.id, spoitValues); } SpoitValues[SpoitIndex] = spoit; //更新编辑面板Ui UpdateEditorUI(); } /// /// 创建 1图片 2视频 3模型 4文字 /// /// 素材类型 /// 素材数据 /// 景点 /// private List CreateSuCaiObj(MaterialObl material, GameObject spoit, out MaterialObl newmaterial) { List objects = new List(); List objs = material.materialList; newmaterial = material; //for (int i = 0; i < objs.Count; i++) //{ // Debug.Log(objs[i].localSavePath); //} for (int i = 0; i < objs.Count; i++) { var mat = objs[i]; GameObject go = null; switch (int.Parse(mat.type)) { case (int)MaterialType.None: break; case (int)MaterialType.Image: var pImage = ResMgr.Instance.Load("Template/Prefab/Image"); go = Instantiate(pImage, spoit.transform); var imageitem = go.AddComponent(); go.SetActive(true); imageitem.SetData(mat, material.updateTime); break; case (int)MaterialType.Video: var pVideo = ResMgr.Instance.Load("Template/Prefab/Video"); go = Instantiate(pVideo, spoit.transform); var videoitem = go.AddComponent(); go.SetActive(true); videoitem.SetData(mat, material.updateTime); break; case (int)MaterialType.Model: var pModel = ResMgr.Instance.Load("Template/Prefab/Model"); go = Instantiate(pModel, spoit.transform); var modelitem = go.AddComponent(); go.SetActive(true); modelitem.SetData(mat, material.updateTime); Debug.Log(modelitem.Data.localSavePath); break; case (int)MaterialType.Text: var pText = ResMgr.Instance.Load("Template/Prefab/Text"); go = Instantiate(pText, spoit.transform); var textitem = go.AddComponent(); go.SetActive(true); textitem.SetData(mat, material.updateTime); break; case (int)MaterialType.LocaImage: var pLocaImage = ResMgr.Instance.Load("Template/Prefab/Image"); go = Instantiate(pLocaImage, spoit.transform); var locaImageitem = go.AddComponent(); go.SetActive(true); locaImageitem.SetLocaImageData(mat); break; default: break; } if (go != null) { go.name = string.IsNullOrWhiteSpace(mat.name) ? spoit.name + "-" + i.ToString() : mat.name; mat.name = go.name; go.AddComponent().Type = (MaterialType)(int.Parse(mat.type)); if (material.select) { go.transform.localPosition = mat.ObjectTransform.nowPos; go.transform.localEulerAngles = mat.ObjectTransform.nowRot; go.transform.localScale = mat.ObjectTransform.nowScale; } else { go.transform.localEulerAngles = Vector3.zero; go.transform.localScale = new Vector3(1, 1, 1); if (int.Parse(mat.type) != (int)MaterialType.Text) { go.transform.localPosition = Vector3.zero; } else { //Set text position if (mat.textPosition == "top") { go.transform.localPosition = new Vector3(0, 0.3f, 0); } else if (mat.textPosition == "bottom") { go.transform.localPosition = new Vector3(0, -0.3f, 0); } } mat.ObjectTransform.SetStartValue(go.transform.localPosition, go.transform.localEulerAngles, go.transform.localScale); } ObjectValue objectValue = new ObjectValue(i, material.id, mat.name, go); objects.Add(objectValue); } newmaterial.materialList[i] = mat; } return objects; } /// /// 创建 6模型+文字 /// /// /// /// private List CreateModel_Text(MaterialObl material, GameObject spoit, out MaterialObl newmaterial) { List objects = new List(); List objs = material.materialList; newmaterial = material; for (int i = 0; i < objs.Count; i++) { var mat = objs[i]; GameObject go = null; switch (int.Parse(mat.type)) { case (int)MaterialType.None: break; case (int)MaterialType.Model: var pModel = ResMgr.Instance.Load("Template/Prefab/Model"); go = Instantiate(pModel, spoit.transform); var modelitem = go.AddComponent(); go.SetActive(true); modelitem.SetData(mat, material.updateTime); break; case (int)MaterialType.Text: var pText = ResMgr.Instance.Load("Template/Prefab/Text"); go = Instantiate(pText, spoit.transform); var textitem = go.AddComponent(); go.SetActive(true); textitem.SetData(mat, material.updateTime); break; default: break; } if (go != null) { go.name = string.IsNullOrWhiteSpace(mat.name) ? spoit.name + "-" + i.ToString() : mat.name; go.AddComponent().Type = (MaterialType)(int.Parse(mat.type)); if (material.select) { go.transform.localPosition = mat.ObjectTransform.nowPos; go.transform.localEulerAngles = mat.ObjectTransform.nowRot; go.transform.localScale = mat.ObjectTransform.nowScale; } else { go.transform.localEulerAngles = Vector3.zero; go.transform.localScale = new Vector3(1, 1, 1); if (int.Parse(mat.type) != (int)MaterialType.Text) { go.transform.localPosition = Vector3.zero; } else { //Set text position if (mat.textPosition == "top") { go.transform.localPosition = new Vector3(0, 0.3f, 0); } else if (mat.textPosition == "bottom") { go.transform.localPosition = new Vector3(0, -0.3f, 0); } else if (mat.textPosition == "left") { go.transform.localPosition = new Vector3(-0.3f, 0, 0); } else if (mat.textPosition == "right") { go.transform.localPosition = new Vector3(0.3f, 0f, 0); } } mat.ObjectTransform.SetStartValue(go.transform.localPosition, go.transform.localEulerAngles, go.transform.localScale); } ObjectValue objectValue = CreateMatObjectValue(i, material.id, go, mat); objects.Add(objectValue); } newmaterial.materialList[i] = mat; } return objects; } /// /// 创建 5图片+文字/视频+文字 /// private List CreateImage_Video_Text(MaterialObl material, GameObject spoit, out MaterialObl newmaterial) { newmaterial = material; List objects = new List(); switch (material.typesetting) { case "1": objects = SRTitleLayout.CalLayout(material, spoit, out newmaterial); break; case "2": objects = SRSectorLayout.CalLayout(material, spoit, out newmaterial); break; case "3": objects = DRTitleLayout.CalLayout(material, spoit, out newmaterial); break; case "4": objects = DRFanLayout.CalLayout(material, spoit, out newmaterial); break; case "5": objects = SRTitleLayout.CalLayout(material, spoit, out newmaterial); break; case "自定义": break; default: break; } return objects; } /// /// 创建物体ObjectValue,并赋值位置信息 /// /// /// /// /// /// private ObjectValue CreateMatObjectValue(int id, int parentid, GameObject go, MaterialObjValue mat) { go.name = string.IsNullOrWhiteSpace(mat.name) ? go.name : mat.name; go.AddComponent().Type = (MaterialType)(int.Parse(mat.type)); //为物体位置信息赋值 if (mat.ObjectTransform != null) { go.transform.localPosition = mat.ObjectTransform.nowPos; go.transform.localEulerAngles = mat.ObjectTransform.nowRot; go.transform.localScale = mat.ObjectTransform.nowScale; } else { go.transform.localPosition = Vector3.zero; go.transform.localEulerAngles = Vector3.zero; go.transform.localScale = new Vector3(1, 1, 1); } ObjectValue objectValue = new ObjectValue(id, parentid, mat.name, go, go.transform.localPosition, go.transform.localEulerAngles, go.transform.localScale); return objectValue; } #endregion #region 路径 /// /// 设置路线数据 /// /// public void SetRouteValue(List navLines) { if (navLines == null || navLines.Count <= 0) { Debug.Log("当前景点未绘制路线"); return; } RouteCtr.SetRouteValue(navLines); } #endregion #region 锚点 /// /// 设置场景锚点 /// /// public void SetAnchor(List listAnchor) { if (listAnchor == null) return; Anchor anchor; for (int i = 0; i < listAnchor.Count - 1; i++) { for (int j = 0; j < listAnchor.Count - 1 - i; j++) { if (listAnchor[j].id > listAnchor[j + 1].id) { anchor = listAnchor[j]; listAnchor[j] = listAnchor[j + 1]; listAnchor[j + 1] = anchor; } } } for (int i = 0; i < listAnchor.Count; i++) { // 创建锚点 GameManager.Instance.AnchorValue.Add(listAnchor[i], CreateAnchor(listAnchor[i])); GameManager.Instance.AnchorChild.Add(listAnchor[i], AnchorValue[listAnchor[i]].transform.GetChild(0).gameObject); } m_UIAnchorsPanel.SetAnchor(AnchorValue); } private MeshRenderer CreateAnchor(Anchor anchor) { // 创建锚点 给锚点赋值 GameObject anchorObj = GameObject.Instantiate(Resources.Load("Template/Prefab/Anchor"),AnchorsParent); anchorObj.name = "Anchor" + anchor.id; /* VuforiaAnchor vuforiaAnchor = anchorObj.GetComponent(); vuforiaAnchor.player = GameManager.Instance.m_head.transform; if (VuforiaManager.Instance.list_Anchor == null) VuforiaManager.Instance.list_Anchor = new List(); VuforiaManager.Instance.list_Anchor.Add(vuforiaAnchor);*/ var anchorPos = Vector3.zero; Debug.Log(anchor.picturePosition.pointRelativeX+" "+ WebMapSize.x); anchorPos = new Vector3((float)anchor.picturePosition.pointRelativeX / WebMapSize.x * MapSize.x, -1f, -(float)anchor.picturePosition.pointRelativeY / WebMapSize.y * MapSize.y); anchorObj.transform.localPosition = anchorPos; anchorObj.transform.GetChild(0).gameObject.SetActive(false); var mesh = anchorObj.GetComponent(); mesh.enabled = false; //if(anchor.objectTransform!=null) //{ // anchorObj.transform.localPosition = anchor.objectTransform.nowPos; // anchorObj.transform.localEulerAngles = anchor.objectTransform.nowRot; //} if(anchor.objectTransform!=null && anchor.objectTransform.nowScale!=Vector3.zero) { anchorObj.transform.localEulerAngles = anchor.objectTransform.nowRot; anchorObj.transform.localPosition = anchor.objectTransform.nowPos; } return mesh; } #endregion #region 触发器判定 /// /// 当人物进入触发器范围 /// public void OnColliderTriggerEnter(Collider other) { IsTriggerExiting = true; for (int i = 0; i < ListColliderBoxs.Count; i++) { if (other.name == ListColliderBoxs[i].name) { ListShowObjs[i].gameObject.SetActive(true); Debug.Log(i); if (isShowLoacalShowObjs) ListLocalShowObjs[i].gameObject.SetActive(true); // 进入景点通知后台 HttpSocket.Instance.SendIpToPointTrigger(" ",other.name, CallBack); if (SpoitIndex == i) { return; } //进入新区域前关闭当前显示 if (SpoitIndex >= 0 && IsStartEditor) { ListShowObjs[SpoitIndex].gameObject.SetActive(false); if (isShowLoacalShowObjs) ListLocalShowObjs[SpoitIndex].gameObject.SetActive(false); ListCrystals[SpoitIndex].gameObject.SetActive(true); m_EditorPanel.ClosePanel(); } //进入新的出发区域 SpoitIndex = i; ListCrystals[SpoitIndex].gameObject.SetActive(false); m_EditorPanel.SetSpoit(SpoitValues[i]); return; } } } /// /// 当人物退出触发器范围 /// public void OnColliderTriggerExit(Collider other) { IsTriggerExiting = false; if (IsStartEditor) { return; } else { ListShowObjs[SpoitIndex].gameObject.SetActive(false); if (isShowLoacalShowObjs) ListLocalShowObjs[SpoitIndex].gameObject.SetActive(false); ListCrystals[SpoitIndex].gameObject.SetActive(true); m_EditorPanel.ClosePanel(); SpoitIndex = -1; } } /// /// 更新景点信息 /// public void UpdateSpoitValue() { var spoit = SpoitValues[SpoitIndex]; var objvalues = ObjectValues[spoit.id]; spoit.spoitTf.SavePos(objvalues.nowPos, objvalues.nowRot, objvalues.nowScale); //X\Y\W\H var collidervalue = ColliderObjectValues[SpoitIndex]; var collider = collidervalue.Object; var pos = collidervalue.nowPos; var w = collidervalue.nowScale.x; var h = collidervalue.nowScale.z; var webpos = new Vector3(Math.Abs(pos.x) / MapSize.x * WebMapSize.x, 0, Math.Abs(pos.z) / MapSize.y * WebMapSize.y); var webw = w / MapSize.x * WebMapSize.x; var webh = h / MapSize.y * WebMapSize.y; spoit.SpoitTransform[0].areaRelativeX = webpos.x; spoit.SpoitTransform[0].areaRelativeY = webpos.z; spoit.SpoitTransform[0].areaRelativeW = webw; spoit.SpoitTransform[0].areaRelativeH = webh; spoit.spoitTf.SavePos(objvalues.nowPos, objvalues.nowRot, objvalues.nowScale); if (objvalues.Object == null) { RemoveSpoitObjectValue(spoit.id); spoit.material = new List(); } else { var mats = spoit.material; var objvalue = objvalues.ChildrenObj; for (int j = 0; j < mats.Count; j++) { var matobj = mats[j]; var obis = objvalue[j]; matobj.objectTransform.SavePos(obis.nowPos, obis.nowRot, obis.nowScale); for (int m = 0; m < matobj.materialList.Count; m++) { var childrenobj = obis.ChildrenObj[m]; var mat = matobj.materialList[m]; if (childrenobj.Object == null) { obis.ChildrenObj.RemoveAt(m); matobj.materialList.RemoveAt(m); break; } mat.ObjectTransform.SavePos(childrenobj.nowPos, childrenobj.nowRot, childrenobj.nowScale); } matobj.select = true; if (obis.ChildrenObj.Count <= 0) { mats.RemoveAt(j); objvalue.RemoveAt(j); Destroy(obis.Object); break; } } } SpoitValues[SpoitIndex] = spoit; } public void UpdateEditorUI() { m_EditorPanel.SetSpoit(SpoitValues[SpoitIndex]); } #endregion public ObjectValue GetCurrentColliderValue() { return ColliderObjectValues[SpoitIndex]; } public void SaveSpoitObjectValue(ObjectValue value) { if (ObjectValues.ContainsKey(SpoitValues[SpoitIndex].id)) { ObjectValues[SpoitValues[SpoitIndex].id] = value; } } public void RemoveSpoitObjectValue(int id) { if (ObjectValues.ContainsKey(id)) { ObjectValues.Remove(id); } } public void SaveCurrentColliderValue(ObjectValue value) { if (ColliderObjectValues.Contains(value)) { ColliderObjectValues[SpoitIndex] = value; } } //计算场景中点云地图比例 public void CalMapSize() { //场景地图比例 var disX = Vector3.Distance(PointA.localPosition, PointD.localPosition); var disZ = Vector3.Distance(PointA.localPosition, PointB.localPosition); MapSize = new Vector2(disX, disZ); //Debug.LogFormat("{0}:{1}", "AB", Vector3.Distance(PointA.localPosition, PointB.localPosition)); //Debug.LogFormat("{0}:{1}", "CD", Vector3.Distance(PointC.localPosition, PointD.localPosition)); //Debug.LogFormat("{0}:{1}", "AD", Vector3.Distance(PointA.localPosition, PointD.localPosition)); //Debug.LogFormat("{0}:{1}", "BC", Vector3.Distance(PointB.localPosition, PointC.localPosition)); } public void CallBack(string message) { } } [Serializable] public class ObjectValue { /// /// 景点ID /// [SerializeField] public int ID; /// /// 当前物体名称 /// [SerializeField] public string matName; /// /// 父物体ID /// -1表示当期物体为景点 /// [SerializeField] public int parentID; /// /// 对应的物体 /// [SerializeField] public GameObject Object; /// /// 子物体 /// [SerializeField] public List ChildrenObj; public Vector3 startPos { get; set; } public Vector3 startRot { get; set; } public Vector3 startScale { get; set; } public Vector3 nowPos { get; set; } public Vector3 nowRot { get; set; } public Vector3 nowScale { get; set; } public ObjectValue() { ChildrenObj = new List(); parentID = -1; } /// /// /// /// 景点对应的index /// 景点ID /// /// /// /// /// public ObjectValue(int id, int parentid, string name, GameObject @object, Vector3 pos, Vector3 Rot, Vector3 Scale) { ID = id; parentID = parentid; matName = name; Object = @object; ChildrenObj = new List(); startPos = pos; nowPos = pos; startRot = Rot; nowRot = Rot; startScale = Scale; nowScale = Scale; } public ObjectValue(int id, int parentid, string name, GameObject @object) { ID = id; parentID = parentid; matName = name; Object = @object; ChildrenObj = new List(); startPos = @object.transform.localPosition; nowPos = startPos; startRot = @object.transform.localEulerAngles; nowRot = startRot; startScale = @object.transform.localScale; nowScale = startScale; } /// /// 初始化时当前位置和初始位置 /// 此方法只在组合素材时使用 /// public void InitTransform() { if (Object != null) { startPos = Object.transform.localPosition; nowPos = Object.transform.localPosition; startRot = Object.transform.localEulerAngles; nowRot = Object.transform.localEulerAngles; startScale = Object.transform.localScale; nowScale = Object.transform.localScale; } } /// /// 编辑物体坐标时初始化坐标 /// public void InitObjTransform() { Object.transform.localPosition = startPos; Object.transform.localEulerAngles = startRot; Object.transform.localScale = startScale; nowPos = startPos; nowRot = startRot; nowScale = startScale; } /// /// 编辑物体坐标时保存坐标信息 /// public void SaveObjTransfoem() { if (Object != null) { nowPos = Object.transform.localPosition; nowRot = Object.transform.localEulerAngles; nowScale = Object.transform.localScale; } } }