using System; using System.Collections.Generic; using System.IO; using Games.GlobeDefine; using Games.LogicObj; using GCGame; using GCGame.Table; using UnityEngine; using UnityEngine.UI; using Object = UnityEngine.Object; public class MapInterface { private const float _mapTrackDistance = 10f; private const float _navPathDistInterval = 3f; private const float _navPathTimeInterval = 0.5f; // 寻路点位记录 private readonly List _navPointList = new List(); private Dictionary _monsterPointList = new Dictionary(); // 永久记录点位 private readonly List _staticPointList = new List(); private MapDynamicPointHub _enemyPointHub; // 动态记录点位 private MapDynamicPointHub _friendPointHub; //private Vector3 _lastNavTarget; private RectTransform _mapRect; private GameObject _navPoint; //private float _navPointStartTime; private MapDynamicPointHub _otherPointHub; private MapDynamicPointHub _teamPointHub; private MapDynamicHeadHub _CallMonsterPointHub; private MapDynamicPointHub _SameForcePointHub; public void InitOtherPoint(GameObject pointCall, GameObject pointSame) { if (_CallMonsterPointHub == null) _CallMonsterPointHub = new MapDynamicHeadHub(pointCall); if (_SameForcePointHub == null) _SameForcePointHub = new MapDynamicPointHub(pointSame); } public void Init(RectTransform mapRoot, GameObject pointFriend, GameObject pointEnemy, GameObject pointOther, GameObject pointTeam) { if (_friendPointHub == null && pointFriend != null) _friendPointHub = new MapDynamicPointHub(pointFriend); if (_enemyPointHub == null && pointEnemy != null) _enemyPointHub = new MapDynamicPointHub(pointEnemy); if (_otherPointHub == null && pointOther != null) _otherPointHub = new MapDynamicPointHub(pointOther); if (_teamPointHub == null && pointTeam != null) _teamPointHub = new MapDynamicPointHub(pointTeam); _mapRect = mapRoot; } public void InitNavPointPrefab(GameObject navPoint) { _navPoint = navPoint; } public void SetMapImage(string imagePath, RawImage image) { var name = Path.GetFileNameWithoutExtension(imagePath); if (!string.IsNullOrEmpty(name)) name = name.ToLower(); LoadAssetBundle.Instance.SetRawTexture(image, name, imagePath); } //屏幕位置转换成场景位置 public Vector3? ScreenPosToScenePos(Vector3 pos) { if (SceneMapFix.Instance() == null || _mapRect == null) { return null; } var outVec = Utils.PositionToRectLocal(_mapRect, pos); var x = outVec.x / _mapRect.sizeDelta.x; var y = outVec.y / _mapRect.sizeDelta.y; outVec.x = x; outVec.y = y; return SceneMapFix.Instance().MapPosToScenePos(outVec); } // 注:之前接口中ScenePosToMapPos不会将_mapRect传到函数中;因此定义一个新的函数来处理 public Vector3 ScenePosToMapPosVec3(Vector3 pos) { return SceneMapFix.Instance() == null ? Vector3.zero : SceneMapFix.Instance().ScenePosToMapPosVec3(pos, _mapRect); } //public Vector3 ScenePosToMapPosVec2(Vector2 pos) //{ // return SceneMapFix.Instance() == null ? Vector3.zero : SceneMapFix.Instance().ScenePosToMapPosVec2(pos, _mapRect); //} /// /// 更新动态点位 /// public void UpdateMap() { var mainPlayer = Singleton.GetInstance().MainPlayer; if (mainPlayer != null) { var mainPlayerMapPos = ScenePosToMapPosVec3(mainPlayer.Position); _enemyPointHub.StartSet(); _friendPointHub.StartSet(); _otherPointHub.StartSet(); _teamPointHub.StartSet(); List teams = new List(); foreach (var obj in Singleton.GetInstance().ObjPools.Values) if (obj.ObjType == GameDefine_Globe.OBJ_TYPE.OBJ_CHARACTER || obj.ObjType == GameDefine_Globe.OBJ_TYPE.OBJ_OTHER_PLAYER) { var otherPlayer = obj as Obj_OtherPlayer; if (otherPlayer != null) { var mapPos = ScenePosToMapPosVec3(otherPlayer.Position); if (GameManager.gameManager.PlayerDataPool.IsHaveTeam() && GameManager.gameManager.PlayerDataPool.IsTeamMem(otherPlayer.GUID)) { _teamPointHub.SetPointPosition(mapPos); teams.Add(otherPlayer.GUID); continue; } if ((mapPos - mainPlayerMapPos).sqrMagnitude < _mapTrackDistance.ToSquare()) { var reputation = Reputation.GetObjReputionType(otherPlayer); switch (reputation) { case CharacterDefine.REPUTATION_TYPE.REPUTATION_FRIEND: _friendPointHub.SetPointPosition(mapPos); break; case CharacterDefine.REPUTATION_TYPE.REPUTATION_HOSTILE: _enemyPointHub.SetPointPosition(mapPos); break; default: _otherPointHub.SetPointPosition(mapPos); break; } } } } if(GameManager.gameManager.PlayerDataPool.IsHaveTeam()) { for(int i=0;i Poss,int type) { if (type == 1) { _CallMonsterPointHub.StartSet(); } if (type == 2) { _SameForcePointHub.StartSet(); } for(int i=0;i(); if (rect != null) rect.anchoredPosition3D = ScenePosToMapPosVec3(new Vector3(roleBase.MapX,0, roleBase.MapZ)); pointObj.SetActive(true); var name = pointObj.GetComponent(); if (name != null) name.text = string.Format("Lv.{0} {1}", roleBase.Level, roleBase.Name); _monsterPointList[roleBase.Id] = pointObj; } public void ClonePoint(PointInfoData pointData, bool posCanUse = false) { if (pointData != null && pointData.m_cloneObj != null) { var pointObj = Object.Instantiate(pointData.m_cloneObj); pointObj.transform.SetParent(pointData.m_cloneObj.transform.parent); pointObj.transform.localScale = pointData.m_cloneObj.transform.localScale; var rect = pointObj.GetComponent(); if (rect != null) rect.anchoredPosition3D = posCanUse ? pointData.m_pos : ScenePosToMapPosVec3(pointData.m_pos); pointObj.SetActive(true); var name = pointObj.GetComponentInChildren(); if (name != null && !string.IsNullOrEmpty(pointData.m_name)) name.text = pointData.m_name; _staticPointList.Add(pointObj); } } public void ClearStaticPoint() { for (var i = 0; i < _staticPointList.Count; i++) Object.Destroy(_staticPointList[i]); _staticPointList.Clear(); List keys = new List(_monsterPointList.Keys); for (var i = 0; i < keys.Count; i++) Object.Destroy(_monsterPointList[keys[i]]); _monsterPointList.Clear(); } public class PointInfoData { public GameObject m_cloneObj; public string m_name = string.Empty; public Vector3 m_pos = Vector3.zero; } public class MapDynamicHeadHub { private readonly List _points = new List(); private readonly GameObject _prefab; private int _lastIndex; public MapDynamicHeadHub(GameObject prefab) { _prefab = prefab; prefab.gameObject.SetActive(false); } public void StartSet() { _lastIndex = 0; } public void SetPointPosition(Vector2 position,int RoleBaseID) { RectTransform point; Tab_RoleBaseAttr roleBase = TableManager.GetRoleBaseAttrByID(RoleBaseID, 0); if (roleBase == null) return; Tab_CharModel charModel = TableManager.GetCharModelByID(roleBase.CharModelID, 0); if (charModel == null) { return; } if (_lastIndex < _points.Count) { point = _points[_lastIndex]; } else { var pointObj = Object.Instantiate(_prefab); point = (RectTransform)pointObj.transform; point.SetParent(_prefab.transform.parent, false); _points.Add(point); } Image head = point.GetComponent(); if(head!=null) { LoadAssetBundle.Instance.SetImageSprite(head, charModel.HeadPic); } point.anchoredPosition = position; point.gameObject.SetActive(true); _lastIndex++; } public void EndSet() { for (var i = _lastIndex; i < _points.Count; i++) _points[i].gameObject.SetActive(false); } } /// /// 动态创建点记录表 /// public class MapDynamicPointHub { private readonly List _points = new List(); private readonly GameObject _prefab; private int _lastIndex; public MapDynamicPointHub(GameObject prefab) { _prefab = prefab; prefab.gameObject.SetActive(false); } public void StartSet() { _lastIndex = 0; } public RectTransform SetPointPosition(Vector2 position) { RectTransform point; if (_lastIndex < _points.Count) { point = _points[_lastIndex]; } else { var pointObj = Object.Instantiate(_prefab); point = (RectTransform) pointObj.transform; point.SetParent(_prefab.transform.parent, false); _points.Add(point); } point.anchoredPosition = position; point.gameObject.SetActive(true); _lastIndex++; return point; } public void EndSet() { for (var i = _lastIndex; i < _points.Count; i++) _points[i].gameObject.SetActive(false); } } #region 玩家当前路径显示 // 防止寻路机实际路线偏离航道,每两秒执行一次重置 private bool _playerMove; private float _lastNavPointTime; /// /// 初始化当前玩家路径 /// private void ShowNavPoint() { _lastNavPointTime = Time.time; var path = ObjManager.Instance.MainPlayer.NavAgent.path; var pointId = 0; var cornerId = 1; var distance = 0f; while (cornerId < path.corners.Length) { //var start = path.corners[cornerId - 1]; //var end = path.corners[cornerId]; var start = path.corners[path.corners.Length - cornerId]; var end = path.corners[path.corners.Length - cornerId - 1]; var length = Vector3.Distance(start, end); while (distance < length) { // 最后一个点把长度保留到下一段路径 var point = Vector3.Lerp(start, end, distance / length); RectTransform pointTransform; if (pointId < _navPointList.Count) { pointTransform = _navPointList[pointId]; } else { var itemObj = Object.Instantiate(_navPoint); pointTransform = (RectTransform) itemObj.transform; pointTransform.SetParent(_navPoint.transform.parent, false); _navPointList.Add(pointTransform); } pointId++; pointTransform.gameObject.SetActive(true); pointTransform.anchoredPosition = ScenePosToMapPosVec3(point); distance = distance + _navPathDistInterval; } distance -= length; cornerId++; } for (var i = pointId; i < _navPointList.Count; i++) _navPointList[i].gameObject.SetActive(false); //_lastNavTarget = path.corners[path.corners.Length - 1]; //_navPointStartTime = Time.time; } /// /// 移除当前玩家路径 /// private void ClearNavPoint() { for (var i = 0; i < _navPointList.Count; i++) _navPointList[i].gameObject.SetActive(false); } private void SetPlayerMove() { _playerMove = false; var mainPlayer = ObjManager.Instance.MainPlayer; if (mainPlayer != null && !mainPlayer.isAutoCombat && mainPlayer.IsMoveToPos() && mainPlayer.NavAgent != null && mainPlayer.NavAgent.hasPath && mainPlayer.NavAgent.path.corners.Length > 1) _playerMove = true; } /// /// 重置玩家路径点 /// public void ResetNavPoint() { SetPlayerMove(); if (_playerMove) ShowNavPoint(); else ClearNavPoint(); } /// /// 玩家路径更新 /// public void UpdateNavPoint() { var lastMove = _playerMove; SetPlayerMove(); if (lastMove != _playerMove) { if (_playerMove) ShowNavPoint(); else ClearNavPoint(); } else if (_playerMove) { if (Time.time > _lastNavPointTime + _navPathTimeInterval) ShowNavPoint(); } } #endregion }