342 lines
13 KiB
C#
342 lines
13 KiB
C#
|
using System;
|
|||
|
using Games.Events;
|
|||
|
using Module.Log;
|
|||
|
using System.Collections.Generic;
|
|||
|
using GCGame.Table;
|
|||
|
using UnityEngine;
|
|||
|
using UnityEngine.Events;
|
|||
|
|
|||
|
namespace Games.LogicObj
|
|||
|
{
|
|||
|
// 近世界层UI,该层UI可以认为是每一帧都需要重新拼合
|
|||
|
public class WorldUIRoot : MonoBehaviour
|
|||
|
{
|
|||
|
// 暂时不构造从UiManager向下初始化的结构,不析构的管理器直接用Instance自己管理
|
|||
|
public static WorldUIRoot Instance { get; private set; }
|
|||
|
//public const float maxScale = 1f;
|
|||
|
//public const float minScale = 0.2f;
|
|||
|
//// 像素宽度到世界宽度转化数值
|
|||
|
//public float PixelToWorld { get; private set; }
|
|||
|
|
|||
|
private List<WorldUIItem> _uiItemList;
|
|||
|
private UiItemPool<WorldUIItem, WorldUiLoadData, WorldUiLoadTask> _uiItemPool;
|
|||
|
// Destroy之后不回收任何物品
|
|||
|
private bool _isDestroyed;
|
|||
|
private Canvas _canvas;
|
|||
|
|
|||
|
#region Head UI
|
|||
|
public static bool ShowHeadUi
|
|||
|
{
|
|||
|
get { return PlayerPreferenceData.SystemNameBoard; }
|
|||
|
}
|
|||
|
|
|||
|
private RectTransform _headUiRoot;
|
|||
|
private RectTransform _damageUiRoot;
|
|||
|
|
|||
|
public void ShowOrHideHeadRoot(bool IsShow)
|
|||
|
{
|
|||
|
if (_headUiRoot)
|
|||
|
_headUiRoot.gameObject.SetActive(IsShow);
|
|||
|
}
|
|||
|
|
|||
|
public void ResetShowHeadUi()
|
|||
|
{
|
|||
|
for (var i = 0; i < _uiItemList.Count; i++)
|
|||
|
{
|
|||
|
var headUi = _uiItemList[i] as Obj_HeadUI;
|
|||
|
if (headUi)
|
|||
|
headUi.ResetShow();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 请求一个HeadUi物体
|
|||
|
/// </summary>
|
|||
|
public void LoadHeadUi(ObjParent objParent)
|
|||
|
{
|
|||
|
var loadData = new WorldUiLoadData(objParent, _headUiRoot, OnHeadUiLoadTaskComplete);
|
|||
|
_uiItemPool.PullItem(loadData, objParent.HeadUiPath);
|
|||
|
}
|
|||
|
|
|||
|
public void StopLoadHeadUi(ObjParent objParent)
|
|||
|
{
|
|||
|
// 无视这个警告 - 常规指针检测方式
|
|||
|
#pragma warning disable 252,253
|
|||
|
_uiItemPool.RemoveLoadTask(a => a.data == objParent);
|
|||
|
#pragma warning restore 252,253
|
|||
|
}
|
|||
|
|
|||
|
private void OnHeadUiLoadTaskComplete(WorldUIItem worldUiItem, WorldUiLoadData loadData)
|
|||
|
{
|
|||
|
if (worldUiItem == null)
|
|||
|
return;
|
|||
|
// Obj在加载中被析构的稀有情况
|
|||
|
if (loadData.data == null)
|
|||
|
_uiItemPool.PushItem(worldUiItem.uiPathData, worldUiItem);
|
|||
|
else
|
|||
|
{
|
|||
|
var error = false;
|
|||
|
try
|
|||
|
{
|
|||
|
((ObjParent)loadData.data).BindHeadUi(worldUiItem);
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
LogModule.ErrorLog(e.ToString());
|
|||
|
error = true;
|
|||
|
}
|
|||
|
if (error)
|
|||
|
worldUiItem.BackToPool();
|
|||
|
else
|
|||
|
_uiItemList.Add(worldUiItem);
|
|||
|
}
|
|||
|
}
|
|||
|
#endregion
|
|||
|
#region Damage Board
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 显示伤害信息
|
|||
|
/// </summary>
|
|||
|
/// <param name="nType">伤害类型</param>
|
|||
|
/// <param name="strValue">字符串</param>
|
|||
|
/// <param name="pos">世界位置</param>
|
|||
|
/// <param name="isProfessionSkill">是否职业技能</param>
|
|||
|
public void ShowDamageBoard(int nType, string strValue, Vector3 pos, bool isProfessionSkill = true)
|
|||
|
{
|
|||
|
if (!PlayerPreferenceData.SystemDamageBoardEnable)
|
|||
|
return;
|
|||
|
var data = DamageBoardManager.damageBoardManager.TryAddDamageBoard(nType);
|
|||
|
if (data != null)
|
|||
|
{
|
|||
|
bool hightLayer = (
|
|||
|
(nType == (int)Games.GlobeDefine.GameDefine_Globe.DAMAGEBOARD_TYPE.PLAYER_EXP_UP)
|
|||
|
|| (nType == (int)Games.GlobeDefine.GameDefine_Globe.DAMAGEBOARD_TYPE.YINPIAO_UP)
|
|||
|
|| (nType == (int)Games.GlobeDefine.GameDefine_Globe.DAMAGEBOARD_TYPE.YINLING_UP)
|
|||
|
|| (nType == (int)Games.GlobeDefine.GameDefine_Globe.DAMAGEBOARD_TYPE.YUANBAO_UP)
|
|||
|
|| (nType == (int)Games.GlobeDefine.GameDefine_Globe.DAMAGEBOARD_TYPE.LINGYU_UP)
|
|||
|
);
|
|||
|
RectTransform _damageExpUiRoot = (UIManager.Instance() != null ? UIManager.Instance().DamageHightRoot : null);
|
|||
|
RectTransform root = (hightLayer && _damageExpUiRoot != null ? _damageExpUiRoot : _damageUiRoot);
|
|||
|
var taskStarter = new WorldUiLoadData(new DamageBoardData(data, strValue, pos, isProfessionSkill), root, OnDamageBoardLoadTaskComplete);
|
|||
|
_uiItemPool.PullItem(taskStarter, DamageBoard.PathData);
|
|||
|
}
|
|||
|
}
|
|||
|
private void OnDamageBoardLoadTaskComplete(WorldUIItem damageUiItem, WorldUiLoadData loadData)
|
|||
|
{
|
|||
|
var data = (DamageBoardData) loadData.data;
|
|||
|
var damageBoard = (DamageBoard) damageUiItem;
|
|||
|
damageBoard.ActiveDamageBoard(data.data, data.strValue, data.worldPos, data.isProfessionSkill);
|
|||
|
_uiItemList.Add(damageBoard);
|
|||
|
}
|
|||
|
// 注:这个指令应该同所有角色析构是同一帧,因此可以析构HeadUi
|
|||
|
public void ClearDamageBoard()
|
|||
|
{
|
|||
|
if (!_isDestroyed)
|
|||
|
{
|
|||
|
for (var i = 0; i < _uiItemList.Count; i++)
|
|||
|
{
|
|||
|
var uiItem = _uiItemList[i];
|
|||
|
if (uiItem.itemType == WorldUiItemType.DamageBoard)
|
|||
|
Recovery(uiItem.uiPathData, uiItem);
|
|||
|
}
|
|||
|
DamageBoardManager.damageBoardManager.ClearNumber();
|
|||
|
}
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region AnchoredText
|
|||
|
|
|||
|
public void ShowCountdownOnCharacter(int objId, int countdown)
|
|||
|
{
|
|||
|
var textData = new AnchoredTextData(objId, Time.unscaledTime + (float)countdown);
|
|||
|
var taskStarter = new WorldUiLoadData(textData, _damageUiRoot, OnCountDownLoadTaskComplete);
|
|||
|
_uiItemPool.PullItem(taskStarter, AnchoredText.PathData);
|
|||
|
}
|
|||
|
|
|||
|
private void OnCountDownLoadTaskComplete(WorldUIItem damageUiItem, WorldUiLoadData loadData)
|
|||
|
{
|
|||
|
var data = (AnchoredTextData) loadData.data;
|
|||
|
var anchoredText = (AnchoredText) damageUiItem;
|
|||
|
anchoredText.SetInitData(data);
|
|||
|
_uiItemList.Add(anchoredText);
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
private void Awake()
|
|||
|
{
|
|||
|
Instance = this;
|
|||
|
_canvas = GetComponent<Canvas>();
|
|||
|
_uiItemList = new List<WorldUIItem>();
|
|||
|
_uiItemPool = new UiItemPool<WorldUIItem, WorldUiLoadData, WorldUiLoadTask>((RectTransform)transform.Find("PoolRoot"));
|
|||
|
_headUiRoot = (RectTransform)transform.Find("NameBoardRoot");
|
|||
|
_damageUiRoot = (RectTransform) transform.Find("DamageBoardRoot");
|
|||
|
}
|
|||
|
|
|||
|
private void Start()
|
|||
|
{
|
|||
|
EventDispatcher.Instance.Add(Events.EventId.PostMainCameraMove, PostMainCameraMove);
|
|||
|
EventDispatcher.Instance.Add(Events.EventId.UiCameraCopy, OnUiCameraCopy);
|
|||
|
// 等TableManager一帧
|
|||
|
// PixelToWorld = 1f; float.Parse(TableManager.GetSystemParamByID(6, 0).StringValue);
|
|||
|
}
|
|||
|
|
|||
|
private void OnDestroy()
|
|||
|
{
|
|||
|
if (Instance == this)
|
|||
|
Instance = null;
|
|||
|
_isDestroyed = true;
|
|||
|
EventDispatcher.Instance.Remove(Events.EventId.PostMainCameraMove, PostMainCameraMove);
|
|||
|
EventDispatcher.Instance.Remove(Events.EventId.UiCameraCopy, OnUiCameraCopy);
|
|||
|
}
|
|||
|
|
|||
|
private int _hideCamera;
|
|||
|
private void OnUiCameraCopy(object args)
|
|||
|
{
|
|||
|
var start = (bool)args;
|
|||
|
_hideCamera = _hideCamera.ReplaceFlag(0.ToFlag(), start);
|
|||
|
ResetHideCamera();
|
|||
|
}
|
|||
|
|
|||
|
//private void OnSceneMovie(object args)
|
|||
|
//{
|
|||
|
// var start = (bool)args;
|
|||
|
// _hideCamera = _hideCamera.ReplaceFlag(1.ToFlag(), start);
|
|||
|
// ResetHideCamera();
|
|||
|
//}
|
|||
|
|
|||
|
private void ResetHideCamera()
|
|||
|
{
|
|||
|
_canvas.enabled = _hideCamera <= 0;
|
|||
|
}
|
|||
|
|
|||
|
private void PostMainCameraMove(object args)
|
|||
|
{
|
|||
|
// 注:可能有设置位置时,要求被回收的情况
|
|||
|
for (var i = _uiItemList.Count - 1; i >= 0; i--)
|
|||
|
{
|
|||
|
// 加固,防止固化流程被其他模块破坏
|
|||
|
try
|
|||
|
{
|
|||
|
var activeItem = _uiItemList[i];
|
|||
|
if (activeItem.CheckPositionValid() && activeItem.CheckDuration())
|
|||
|
{
|
|||
|
// 屏蔽缩放功能直到修复
|
|||
|
//if (activeItem.scaleByWorldPos)
|
|||
|
// uiPos = GetUiPositionAndScale(activeItem.worldPosition, activeItem.pixelWidth, out scale);
|
|||
|
//else
|
|||
|
//{
|
|||
|
var uiPos = UIManager.Instance().WorldToUiPoint(activeItem.worldPosition);
|
|||
|
const float scale = 1f;
|
|||
|
//}
|
|||
|
activeItem.SetPositionAndScale(uiPos, scale);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// 伤害面板回收需要清除使用计数
|
|||
|
if (activeItem.itemType == WorldUiItemType.DamageBoard && DamageBoardManager.damageBoardManager != null)
|
|||
|
{
|
|||
|
var damageBoard = (DamageBoard) activeItem;
|
|||
|
DamageBoardManager.damageBoardManager.RemoveDamageBoard(damageBoard.data.DamageBoardTypeID);
|
|||
|
}
|
|||
|
activeItem.BackToPool();
|
|||
|
}
|
|||
|
}
|
|||
|
catch (System.Exception e)
|
|||
|
{
|
|||
|
LogModule.ErrorLog(_uiItemList[i] == null
|
|||
|
? "World Ui Root 中发现为空的物体!"
|
|||
|
: string.Format("{0}发生故障!", _uiItemList[i].transform.GetHierarchyName()));
|
|||
|
LogModule.ErrorLog(e.ToString());
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 世界坐标转到UI坐标体系下的位置和缩放
|
|||
|
/// </summary>
|
|||
|
/// <param name="worldPos">世界坐标位置</param>
|
|||
|
/// <param name="pixelWidth">组件预期像素宽度</param>
|
|||
|
/// <param name="scale">Ui空间的缩放数值</param>
|
|||
|
//public Vector3 GetUiPositionAndScale(Vector3 worldPos, float pixelWidth, out float scale)
|
|||
|
//{
|
|||
|
// var sceneCamera = UIManager.Instance().GetWorldCamera();
|
|||
|
// var worldWidth = pixelWidth * PixelToWorld;
|
|||
|
// // 默认世界摄像机是投影摄像机
|
|||
|
// // 实际是摄像机的forward,叉乘之后才是right
|
|||
|
// var right = worldPos - sceneCamera.transform.position;
|
|||
|
// right = Vector3.Cross(Vector3.up, right);
|
|||
|
// if (right == Vector3.zero)
|
|||
|
// right = sceneCamera.transform.right;
|
|||
|
// right = right.normalized;
|
|||
|
// var pos0 = worldPos - right * 0.5f * worldWidth;
|
|||
|
// var pos1 = worldPos + right * 0.5f * worldWidth;
|
|||
|
// // 像素位置
|
|||
|
// pos0 = UIManager.Instance().WorldToUiPoint(pos0);
|
|||
|
// pos1 = UIManager.Instance().WorldToUiPoint(pos1);
|
|||
|
// scale = Mathf.Clamp((pos1.x - pos0.x) / pixelWidth, minScale, maxScale);
|
|||
|
// return (pos0 + pos1) * 0.5f;
|
|||
|
//}
|
|||
|
|
|||
|
public void SetShow(bool isShow)
|
|||
|
{
|
|||
|
_canvas.enabled = isShow;
|
|||
|
}
|
|||
|
|
|||
|
public void Recovery(UIPathData pathData, WorldUIItem item)
|
|||
|
{
|
|||
|
if (!_isDestroyed)
|
|||
|
{
|
|||
|
_uiItemList.Remove(item);
|
|||
|
_uiItemPool.PushItem(pathData, item);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public class WorldUiLoadData : BaseLoadData<WorldUIItem, WorldUiLoadData>
|
|||
|
{
|
|||
|
public object data;
|
|||
|
public WorldUiLoadData(object pData, Transform root, UnityAction<WorldUIItem, WorldUiLoadData> callback) : base(root, callback)
|
|||
|
{
|
|||
|
data = pData;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public class WorldUiLoadTask : BaseLoadTask<WorldUIItem, WorldUiLoadData, WorldUiLoadTask>
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
public class DamageBoardData
|
|||
|
{
|
|||
|
public Tab_DamageBoardType data;
|
|||
|
public string strValue;
|
|||
|
public Vector3 worldPos;
|
|||
|
public bool isProfessionSkill;
|
|||
|
|
|||
|
public DamageBoardData(Tab_DamageBoardType data, string strValue, Vector3 worldPos, bool isProfessionSkill)
|
|||
|
{
|
|||
|
this.data = data;
|
|||
|
this.strValue = strValue;
|
|||
|
this.worldPos = worldPos;
|
|||
|
this.isProfessionSkill = isProfessionSkill;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public class AnchoredTextData
|
|||
|
{
|
|||
|
public int objId;
|
|||
|
public float endTime;
|
|||
|
|
|||
|
public AnchoredTextData(int objId, float endTime)
|
|||
|
{
|
|||
|
this.objId = objId;
|
|||
|
this.endTime = endTime;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public enum WorldUiItemType
|
|||
|
{
|
|||
|
HeadInfo, // 头顶面板
|
|||
|
DamageBoard, // 伤害面板
|
|||
|
AnchorText, // 倒计时面板
|
|||
|
}
|
|||
|
}
|
|||
|
}
|