using System.Collections;
|
using System.Collections.Generic;
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
using System;
|
using UnityEngine.EventSystems;
|
|
namespace Snxxz.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] Image m_HeroHead;
|
[SerializeField] LocalMapEventPointInstroduce m_EventPointInstroduce;
|
[SerializeField] Transform m_SelecteEventPointSign;
|
|
LocalMap mapMatrix;
|
|
Vector3 heroPrePosition = new Vector3(-999, -8888, 0);
|
private List<GameObject> pathNodeBehaviours = new List<GameObject>(); //寻路点池
|
List<LocalMapTag> tagBehaviours = new List<LocalMapTag>();
|
|
MapModel model { get { return ModelCenter.Instance.GetModel<MapModel>(); } }
|
|
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_HeroHead.gameObject.SetActive(true);
|
var job = PlayerDatas.Instance.baseData.Job;
|
this.m_HeroHead.SetSprite(GeneralDefine.GetJobHeadPortrait(job, 0));
|
}
|
else
|
{
|
this.m_HeroHead.gameObject.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_HeroHead.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();
|
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.gameObject.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.gameObject.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.gameObject.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<Vector3>();
|
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.gameObject.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_HeroHead.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<Vector3> NodeLerp(Vector3[] _originalNodes)
|
{
|
if (_originalNodes == null || _originalNodes.Length < 2)
|
{
|
return null;
|
}
|
|
var nodes = new List<Vector3>();
|
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<GameObject>(prefab);
|
pathNodeBehaviours.Add(instance);
|
instance.transform.SetParentEx(m_ContainerPathNode, Vector3.zero, Quaternion.identity, Vector3.one);
|
}
|
}
|
}
|
|
private void FoucsEventPoint(int _eventPoint)
|
{
|
var config = MapEventPointConfig.Get(_eventPoint);
|
if (config != null)
|
{
|
var npcConfig = NPCConfig.Get(config.NPCID);
|
if (npcConfig.NPCType == 0)
|
{
|
m_EventPointInstroduce.gameObject.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.gameObject.SetActive(true);
|
m_EventPointInstroduce.Display(model.selectedMapEventPoint, m_SelecteEventPointSign);
|
}
|
else
|
{
|
m_EventPointInstroduce.gameObject.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);
|
}
|
|
}
|
}
|
|
}
|
|