486 lines
16 KiB
C#
486 lines
16 KiB
C#
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<RectTransform> _navPointList = new List<RectTransform>();
|
||
|
||
private Dictionary<int, GameObject> _monsterPointList = new Dictionary<int, GameObject>();
|
||
|
||
// 永久记录点位
|
||
private readonly List<GameObject> _staticPointList = new List<GameObject>();
|
||
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);
|
||
//}
|
||
|
||
/// <summary>
|
||
/// 更新动态点位
|
||
/// </summary>
|
||
public void UpdateMap()
|
||
{
|
||
var mainPlayer = Singleton<ObjManager>.GetInstance().MainPlayer;
|
||
if (mainPlayer != null)
|
||
{
|
||
var mainPlayerMapPos = ScenePosToMapPosVec3(mainPlayer.Position);
|
||
_enemyPointHub.StartSet();
|
||
_friendPointHub.StartSet();
|
||
_otherPointHub.StartSet();
|
||
_teamPointHub.StartSet();
|
||
List<ulong> teams = new List<ulong>();
|
||
foreach (var obj in Singleton<ObjManager>.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<GameManager.gameManager.PlayerDataPool.TeamInfo.teamMember.Length;i++)
|
||
{
|
||
TeamMember member = GameManager.gameManager.PlayerDataPool.TeamInfo.teamMember[i];
|
||
var sceneCopy = TableManager.GetFubenByID(member.SceneClassID, 0);
|
||
if (member.IsValid()
|
||
&& teams.Contains(member.Guid) == false
|
||
&& member.Guid != mainPlayer.GUID
|
||
&& sceneCopy !=null
|
||
&& sceneCopy.GetSceneIdbyIndex(0) == GameManager.gameManager.RunningScene
|
||
&& member.SceneInstID == SceneData.SceneInst)
|
||
{
|
||
var mapPos = ScenePosToMapPosVec3(member.ScenePos.InsertY());
|
||
_teamPointHub.SetPointPosition(mapPos);
|
||
}
|
||
}
|
||
}
|
||
|
||
_enemyPointHub.EndSet();
|
||
_friendPointHub.EndSet();
|
||
_otherPointHub.EndSet();
|
||
_teamPointHub.EndSet();
|
||
}
|
||
}
|
||
|
||
public void UpdateOtherPoint(List<Vector3> Poss,int type)
|
||
{
|
||
if (type == 1)
|
||
{
|
||
_CallMonsterPointHub.StartSet();
|
||
}
|
||
if (type == 2)
|
||
{
|
||
_SameForcePointHub.StartSet();
|
||
}
|
||
for(int i=0;i<Poss.Count;i++)
|
||
{
|
||
var mapPos = Poss[i];
|
||
int serverId = (int)mapPos.y;
|
||
mapPos.y = 0;
|
||
mapPos = ScenePosToMapPosVec3(mapPos);
|
||
if (type == 1)
|
||
{
|
||
_CallMonsterPointHub.SetPointPosition(mapPos, serverId);
|
||
}
|
||
if (type == 2)
|
||
{
|
||
_SameForcePointHub.SetPointPosition(mapPos);
|
||
}
|
||
}
|
||
if (type == 1)
|
||
{
|
||
_CallMonsterPointHub.EndSet();
|
||
}
|
||
if (type == 2)
|
||
{
|
||
_SameForcePointHub.EndSet();
|
||
}
|
||
}
|
||
|
||
public void CloneMonsterPoint(GameObject point,Tab_RoleBaseAttr roleBase)
|
||
{
|
||
if (point == null)
|
||
return;
|
||
if (_monsterPointList.ContainsKey(roleBase.Id))
|
||
return;
|
||
var pointObj = Object.Instantiate(point);
|
||
pointObj.transform.SetParent(point.transform.parent);
|
||
pointObj.transform.localScale = point.transform.localScale;
|
||
var rect = pointObj.GetComponent<RectTransform>();
|
||
if (rect != null)
|
||
rect.anchoredPosition3D = ScenePosToMapPosVec3(new Vector3(roleBase.MapX,0, roleBase.MapZ));
|
||
pointObj.SetActive(true);
|
||
var name = pointObj.GetComponent<Text>();
|
||
if (name != null)
|
||
name.text = string.Format("<color=#ffdf7dff>Lv.{0}</color> <color=#ff3b3bff>{1}</color>", 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<RectTransform>();
|
||
if (rect != null)
|
||
rect.anchoredPosition3D = posCanUse ? pointData.m_pos : ScenePosToMapPosVec3(pointData.m_pos);
|
||
pointObj.SetActive(true);
|
||
var name = pointObj.GetComponentInChildren<Text>();
|
||
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<int> keys = new List<int>(_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<RectTransform> _points = new List<RectTransform>();
|
||
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<Image>();
|
||
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);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 动态创建点记录表
|
||
/// </summary>
|
||
public class MapDynamicPointHub
|
||
{
|
||
private readonly List<RectTransform> _points = new List<RectTransform>();
|
||
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;
|
||
|
||
/// <summary>
|
||
/// 初始化当前玩家路径
|
||
/// </summary>
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 移除当前玩家路径
|
||
/// </summary>
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 重置玩家路径点
|
||
/// </summary>
|
||
public void ResetNavPoint()
|
||
{
|
||
SetPlayerMove();
|
||
if (_playerMove)
|
||
ShowNavPoint();
|
||
else
|
||
ClearNavPoint();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 玩家路径更新
|
||
/// </summary>
|
||
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
|
||
} |