JJBB/Assets/Project/Script/GUI/Map/MapInterface.cs
2024-08-23 15:49:34 +08:00

486 lines
16 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}