using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using System; using UnityEngine.EventSystems; namespace vnxbqy.UI { public class LocalMapFindPath : MonoBehaviour, IPointerClickHandler { const float NODE_SPACEOUT = 3f; [SerializeField] float m_StandardSize = 50f; [SerializeField] BoundedDrag m_BoundDrag; [SerializeField] RectTransform m_LocalMapRect; [SerializeField] Image m_MapImage; [SerializeField] Transform m_ContainerPathNode; [SerializeField] AvatarCell m_AvatarCell; [SerializeField] RectTransform m_AvatarRect; [SerializeField] LocalMapEventPointInstroduce m_EventPointInstroduce; [SerializeField] Transform m_SelecteEventPointSign; LocalMap mapMatrix; Vector3 heroPrePosition = new Vector3(-999, -8888, 0); private List pathNodeBehaviours = new List(); //寻路点池 List tagBehaviours = new List(); MapModel model { get { return ModelCenter.Instance.GetModel(); } } int dataMapId = 0; int lineId = 0; public void Init(int dataMapId, int lineId) { this.dataMapId = dataMapId; this.lineId = lineId; if (this.dataMapId != this.mapMatrix.mapId) { this.PathPointClear(); } if (this.dataMapId == MapUtility.GetDataMapId()) { this.m_AvatarRect.SetActive(true); this.m_AvatarCell.InitUI(AvatarHelper.GetMyAvatarModel()); } else { this.m_AvatarRect.SetActive(false); } var mapResConfig = MapResourcesConfig.GetConfig(this.dataMapId, this.lineId); var mapWidth = mapResConfig.MapScale.x; var mapHeight = mapResConfig.MapScale.y; m_StandardSize = mapResConfig.MapShowScale; var uiMapWidth = mapWidth * m_StandardSize; var uiMapHeight = mapHeight * m_StandardSize; m_LocalMapRect.sizeDelta = new Vector2(uiMapWidth, uiMapHeight); m_MapImage.SetSprite(mapResConfig.BigMap); m_MapImage.SetNativeSize(); var offsetX = Mathf.Clamp((uiMapWidth - m_BoundDrag.rectTransform.rect.width) * 0.5f, 0, float.MaxValue); var offsetY = Mathf.Clamp((uiMapHeight - m_BoundDrag.rectTransform.rect.height) * 0.5f, 0, float.MaxValue); m_BoundDrag.moveArea = new BoundedDrag.MoveArea(-offsetX, offsetX, offsetY, -offsetY); this.mapMatrix = new LocalMap(this.dataMapId, mapWidth, mapHeight, uiMapWidth, uiMapHeight); DrawWayPoints(); DrawFunctionNpcs(); DrawJumpPoints(); DrawEventPoints(); m_AvatarRect.transform.SetAsLastSibling(); FoucsEventPoint(model.selectedMapEventPoint); m_BoundDrag.onBeginDrag.RemoveAllListeners(); m_BoundDrag.onBeginDrag.AddListener(OnBeginDrag); model.selectMapEventPointEvent += FoucsEventPoint; if (MapUtility.GetDataMapId() == this.dataMapId) { var hero = PlayerDatas.Instance.hero; if (hero != null) { if (hero.PathFindStatus == GActor.E_PathFindStatus.Moving) { this.OnHeroStartMove(); } else { this.OnHeroStopMove(); } hero.OnPathFinding += this.OnHeroStartMove; hero.OnPathFindStop += this.OnHeroStopMove; } } } public void UnInit() { var hero = PlayerDatas.Instance.hero; if (hero != null) { hero.OnPathFinding -= OnHeroStartMove; hero.OnPathFindStop -= OnHeroStopMove; } model.selectMapEventPointEvent -= FoucsEventPoint; m_BoundDrag.onBeginDrag.RemoveAllListeners(); for (int i = 0; i < tagBehaviours.Count; i++) { LocalMapTagPool.Recycle(tagBehaviours[i]); } tagBehaviours.Clear(); } void HeroMoveTo(Vector3 _position) { if (dataMapId != PlayerDatas.Instance.baseData.MapID) { return; } if (PlayerDatas.Instance.hero == null) { return; } var position = GetGroundPosition(_position); PlayerDatas.Instance.hero.Behaviour.StopHandupAI(); PlayerDatas.Instance.hero.IdleImmediate(); MapTransferUtility.Instance.MoveToLocalMapPosition(new Vector2(position.x, position.z)); // PlayerDatas.Instance.hero.MoveToPosition(position); } public void OnPointerClick(PointerEventData eventData) { #if UNITY_EDITOR if (RectTransformUtility.RectangleContainsScreenPoint(m_LocalMapRect, Input.mousePosition, CameraManager.uiCamera)) { HeroMoveTo(ScreenToWorldPosition(Input.mousePosition)); } #else if (RectTransformUtility.RectangleContainsScreenPoint(m_LocalMapRect, Input.mousePosition,CameraManager.uiCamera)) { HeroMoveTo( ScreenToWorldPosition(Input.touches[0].position)); } #endif if (RectTransformUtility.RectangleContainsScreenPoint((RectTransform)this.transform, Input.mousePosition, CameraManager.uiCamera) && !RectTransformUtility.RectangleContainsScreenPoint(m_EventPointInstroduce.containerDetails, Input.mousePosition, CameraManager.uiCamera)) { model.selectedMapEventPoint = -1; } } private void LateUpdate() { if (dataMapId == MapUtility.GetDataMapId()) { UpdateHeroPosition(); } } Vector3 ScreenToWorldPosition(Vector3 _sp) { var originalPoint = CameraManager.uiCamera.WorldToViewportPoint(UIUtility.GetMinWorldPosition(m_LocalMapRect)); var spToViewPoint = CameraManager.uiCamera.ScreenToViewportPoint(_sp); var delta = spToViewPoint - originalPoint; var adjustScale = (Screen.width / (float)Screen.height) / (Constants.DESIGN_RESOLUTION.x / Constants.DESIGN_RESOLUTION.y); var adjustX = delta.x * Constants.DESIGN_RESOLUTION.x * (adjustScale > 1f ? adjustScale : 1f) / m_LocalMapRect.rect.width; var adjustY = delta.y * Constants.DESIGN_RESOLUTION.y / (adjustScale < 1f ? adjustScale : 1f) / m_LocalMapRect.rect.height; var adjustedViewPoint = new Vector2(adjustX, adjustY); return new Vector3(mapMatrix.worldMapWidth * adjustedViewPoint.x, 0, mapMatrix.worldMapHeight * adjustedViewPoint.y); } private void GeneratePathNodes(Vector3 targetPos) { var pathVertexArray = GetWorldPathNodes(targetPos); if (pathVertexArray == null) { return; } PathPointClear(); var nodes = NodeLerp(pathVertexArray); if (nodes == null) { return; } InstantiateNodeBehaviours(nodes.Count); for (int i = 0; i < nodes.Count; i++) { var position = mapMatrix.WorldToLocalPosition(nodes[i]); pathNodeBehaviours[i].transform.localPosition = position; pathNodeBehaviours[i].SetActive(true); } } private void DrawEventPoints() { var eventPoints = model.GetMapEventPoints(dataMapId, lineId); for (int i = 0; i < eventPoints.Count; i++) { var eventPoint = eventPoints[i]; DrawEventPoint(eventPoint); } } private void DrawEventPoint(int _eventPoint) { var eventPointConfig = MapEventPointConfig.Get(_eventPoint); if (eventPointConfig.ShowInMipMap == 0) { return; } var npcType = LocalMapTag.TagType.Boss; var npcConfig = NPCConfig.Get(eventPointConfig.NPCID); if (eventPointConfig.IsShowInfo == 1) { if (npcConfig.NPCType == (int)E_NpcType.Func) { npcType = LocalMapTag.TagType.Function; } else if (npcConfig.NPCType == (int)E_NpcType.Fight) { switch ((E_MonsterType)npcConfig.IsBoss) { case E_MonsterType.Normal: npcType = LocalMapTag.TagType.Monster; break; default: npcType = LocalMapTag.TagType.Elite; break; } } } else { npcType = LocalMapTag.TagType.Boss; } var monsterRefreshConfig = MonsterRefreshPointConfig.Get(npcConfig.NPCID); var npcPos = new Vector3(monsterRefreshConfig.Position.x * 0.5f, 0, monsterRefreshConfig.Position.y * 0.5f); var behaviour = LocalMapTagPool.Require(npcType); tagBehaviours.Add(behaviour); behaviour.Display(npcType == LocalMapTag.TagType.Boss ? eventPointConfig.NPCID : npcConfig.NPCID, (TextColType)eventPointConfig.Colour); var pathPointPos = mapMatrix.WorldToLocalPosition(npcPos); behaviour.transform.SetParentEx(m_LocalMapRect, pathPointPos, Quaternion.identity, Vector3.one); behaviour.SetActive(true); } private void DrawWayPoints() { var waypoints = maptransportConfig.GetValues(); foreach (var waypoint in waypoints) { if (waypoint.OriginalMapID == MapUtility.GetMapId(this.dataMapId, this.lineId)) { DrawWayPoint(waypoint.TransportID); } } } private void DrawWayPoint(int _wayPoint) { var config = maptransportConfig.Get(_wayPoint.ToString()); var behaviour = LocalMapTagPool.Require(LocalMapTag.TagType.WayPoint); tagBehaviours.Add(behaviour); var position = new Vector3(config.OriginalPosX * 0.5f, 0, config.OriginalPosY * 0.5f); var pathPointPos = mapMatrix.WorldToLocalPosition(position); behaviour.transform.SetParentEx(m_LocalMapRect, pathPointPos, Quaternion.identity, Vector3.one); behaviour.SetActive(true); } private void DrawFunctionNpcs() { var npcRefreshIds = model.GetMapNPCRefreshIds(dataMapId); if (npcRefreshIds != null) { foreach (var item in npcRefreshIds) { var config = mapnpcConfig.Get(item); var npcConfig = NPCConfig.Get(config.NPCID); if (npcConfig.Show != 0) { DrawFunctionNpc(item); } } } } private void DrawFunctionNpc(string _refreshId) { var mapNpcConfig = mapnpcConfig.Get(_refreshId); var behaviour = LocalMapTagPool.Require(LocalMapTag.TagType.Function); tagBehaviours.Add(behaviour); var originalPosition = GAStaticDefine.GetClientPostionFromHex(mapNpcConfig.HexPosNPCRefreshAreaChaseArea); var position = new Vector3(originalPosition.x, 0, originalPosition.y); var pathPointPos = mapMatrix.WorldToLocalPosition(position); behaviour.transform.SetParentEx(m_LocalMapRect, pathPointPos, Quaternion.identity, Vector3.one); behaviour.SetActive(true); behaviour.Display(mapNpcConfig.NPCID, TextColType.White); } private void DrawJumpPoints() { var mapData = H2Engine.MapData.LoadFormFile(MapUtility.GetMapId(dataMapId, lineId)); if (mapData == null) { return; } var transfers = mapData.transfers; var jumpPoints = new List(); foreach (var transfer in transfers) { foreach (var transferPoint in transfer.transferPoints) { jumpPoints.Add(transferPoint.position); } } foreach (var jumpPoint in jumpPoints) { DrawJumpPoint(jumpPoint); } } private void DrawJumpPoint(Vector3 position) { var behaviour = LocalMapTagPool.Require(LocalMapTag.TagType.JumpPoint); tagBehaviours.Add(behaviour); var pathPointPos = mapMatrix.WorldToLocalPosition(position); behaviour.transform.SetParentEx(m_LocalMapRect, pathPointPos, Quaternion.identity, Vector3.one); behaviour.SetActive(true); behaviour.Display(position); } private void UpdateHeroPosition() { if (dataMapId == PlayerDatas.Instance.baseData.MapID) { var heroPos = mapMatrix.WorldToLocalPosition(PlayerDatas.Instance.hero.Pos); if (Vector3.Distance(heroPrePosition, heroPos) > 0.01f) { m_AvatarRect.transform.localPosition = heroPos; } } } private void PathPointClear() { for (int i = pathNodeBehaviours.Count - 1; i >= 0; i--) { pathNodeBehaviours[i].SetActive(false); } } private Vector3[] GetWorldPathNodes(Vector3 targetPos) { return PlayerDatas.Instance.hero.GetCorners(); } List NodeLerp(Vector3[] _originalNodes) { if (_originalNodes == null || _originalNodes.Length < 2) { return null; } var nodes = new List(); nodes.Add(_originalNodes[0]); var acclength = 0f; for (int i = 0; i < _originalNodes.Length - 1; i++) { var node1 = _originalNodes[i]; var node2 = _originalNodes[i + 1]; var direction = Vector3.Normalize(node2 - node1); var distance = Vector3.Distance(node1, node2); while (acclength < distance) { nodes.Add(node1 + direction * acclength); acclength += NODE_SPACEOUT; } acclength = acclength - distance; } if (Vector3.Distance(nodes[nodes.Count - 1], _originalNodes[_originalNodes.Length - 1]) > NODE_SPACEOUT * 0.5f) { nodes.Add(_originalNodes[_originalNodes.Length - 1]); } return nodes; } void InstantiateNodeBehaviours(int _count) { var now = pathNodeBehaviours.Count; var dif = _count - now; if (dif > 0) { var prefab = UILoader.LoadPrefab("LocalMap_PathNode"); for (int i = 0; i < dif; i++) { var instance = Instantiate(prefab); pathNodeBehaviours.Add(instance); instance.transform.SetParentEx(m_ContainerPathNode, Vector3.zero, Quaternion.identity, Vector3.one); } } } private void FoucsEventPoint(int _eventPoint) { if(MapLevelModel.Instance.GetSelectIndex() != 0) { m_EventPointInstroduce.SetActive(false); return; } var config = MapEventPointConfig.Get(_eventPoint); if (config != null) { var npcConfig = NPCConfig.Get(config.NPCID); if (npcConfig.NPCType == 0) { m_EventPointInstroduce.SetActive(false); return; } } if (model.selectedMapEventPoint != -1 && config.ShowInMipMap == 1) { var monsterRefreshConfig = MonsterRefreshPointConfig.Get(config.NPCID); var position = new Vector3(monsterRefreshConfig.Position.x * 0.5f, 0, monsterRefreshConfig.Position.y * 0.5f); var localPosition = mapMatrix.WorldToLocalPosition(position); m_BoundDrag.destPosition = -1 * localPosition; if (localPosition.y >= 0f) { m_SelecteEventPointSign.localPosition = localPosition.SetY(localPosition.y - 15); } else { m_SelecteEventPointSign.localPosition = localPosition.SetY(localPosition.y + 15); } m_EventPointInstroduce.SetActive(true); m_EventPointInstroduce.Display(model.selectedMapEventPoint, m_SelecteEventPointSign); } else { m_EventPointInstroduce.SetActive(false); } } private Vector3 GetGroundPosition(Vector3 _xzPosition) { RaycastHit hit; var ray = new Ray(_xzPosition.SetY(50f), Vector3.down); if (Physics.Raycast(ray, out hit, 100f, LayerUtility.WalkbleMask)) { return hit.point; } else { return _xzPosition; } } private void OnHeroStartMove() { if (PlayerDatas.Instance.hero == null) { return; } GeneratePathNodes(PlayerDatas.Instance.hero.DestPos); } private void OnHeroStopMove() { if (PlayerDatas.Instance.hero == null) { return; } PathPointClear(); } private void OnBeginDrag() { model.selectedMapEventPoint = -1; } public struct LocalMap { public int mapId; public float worldMapWidth; public float worldMapHeight; public float localMapWidth; public float localMapHeight; public LocalMap(int mapId, float mWidth, float mHeigth, float mSpriteWidth, float mSpriteHeight) { this.mapId = mapId; worldMapWidth = mWidth; worldMapHeight = mHeigth; localMapWidth = mSpriteWidth; localMapHeight = mSpriteHeight; } public Vector3 WorldToLocalPosition(Vector3 _worldPosition) { var x = ((_worldPosition.x - worldMapWidth * 0.5f) / worldMapWidth) * localMapWidth; var y = ((_worldPosition.z - worldMapHeight * 0.5f) / worldMapHeight) * localMapHeight; return new Vector3(x, y, 0); } } } }