Files
JJBB/Assets/Project/Script/GUI/Map/MapInterface.cs

486 lines
16 KiB
C#
Raw Normal View History

2024-08-23 15:49:34 +08:00
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
}