Files
JJBB/Assets/Project/Script/GUI/Base/UICameraTexture.cs
2024-08-23 15:49:34 +08:00

597 lines
20 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.Collections;
using Games.Events;
using Games.GlobeDefine;
using Games.LogicObj;
using GCGame.Table;
using Module.Log;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using Object = UnityEngine.Object;
public class UICameraTexture : UIBase, IDragHandler
{
public delegate void InitModelPathCallBack();
//加载MountModel坐骑表不在CharModel中
public delegate void InitOverCallBack();
private static int _callTimes;
private int _openRawImageFrame = int.MaxValue;
public GameObject _CameraPrefab;
public bool isPerspective;
public FakeShowObj _FakeObj { get; private set; }
public RawImage _RawImage;
public float cameraSize = 1;
public event UnityAction<GameObject> onModelUpdate;
public bool isPreview;
private Camera _cameraInstance;
private bool _hideFakeShow;
private bool _currentHideFakeShow;
private void InitImage()
{
if (_FakeObj == null)
{
var cameraGo = Instantiate(_CameraPrefab);
cameraGo.transform.SetParent(null);
cameraGo.transform.position = new Vector3(1000 + 100 * _callTimes, -1000, 0);
++_callTimes;
// 避开旋转造成模型光照方向不正常,部分模型需要维持在各场景世界方向不变
// cameraGo.transform.rotation = Camera.main.transform.rotation;
cameraGo.transform.localRotation = Quaternion.identity;
cameraGo.transform.localScale = Vector3.one;
var objTransform = cameraGo.transform.Find("GameObject");
_cameraInstance = cameraGo.GetComponent<Camera>();
if (objTransform != null && _cameraInstance != null)
{
_cameraInstance.orthographic = !isPerspective;
_FakeObj = new FakeShowObj(objTransform.gameObject, _cameraInstance, cameraSize, _RawImage);
_FakeObj.FakeObj.onModelUpdate += OnFakeShowModelUpdate;
}
else
LogModule.ErrorLog("FakeObj无法正常初始化于物体" + transform.GetHierarchyName());
_RawImage.material = CommonUtility.LoadSharedMaterial("UiRenderTexture");
OnEnable();
}
else
{
DisAbleFake();
}
// 注以下部分在ShowingModel加载时再次调用CreateNewFake会导致多次构造FakeObj。暂时先修改有其他影响再看如何处理。
//if (_FakeObj == null || _FakeObj.ShowingModel == null)
// _FakeObj = CreateNewFake();
}
public void SetBlack()
{
if(_FakeObj!=null && _FakeObj.FakeObj!=null)
{
_FakeObj.FakeObj.ChangeToBlack();
}
}
public void RemoveBlack()
{
if (_FakeObj != null && _FakeObj.FakeObj != null)
{
_FakeObj.FakeObj.RemoveBlack();
}
}
private void OnFakeShowModelUpdate(GameObject modelGameObject)
{
_hideFakeShow = false;
_currentHideFakeShow = false;
if (modelGameObject != null)
modelGameObject.SetActive(!_currentHideFakeShow);
SetOpenFrame();
if (onModelUpdate != null)
onModelUpdate(modelGameObject);
}
private void Update()
{
// 跳过第一帧激活 - 动画机会有一帧的刷新时间,没有找到避开的办法
if (Time.frameCount > _openRawImageFrame && _FakeObj != null && !_FakeObj.IsInAnimTransistion())
{
_openRawImageFrame = int.MaxValue;
_RawImage.color = Color.white;
}
}
private void OnEnable()
{
// 注使用_FakeObj作为OnEnable标签_FakeObj构造完成或者重新激活时执行一次OnEnable。
if (_FakeObj != null)
{
_FakeObj.Enable();
_RawImage.texture = _FakeObj.renderTexture;
}
if (!isPreview)
_RawImage.color = new Color(0f, 0f, 0f, 0f);
}
private void OnDisable()
{
if (!GameManager.applicationQuit)
{
if (_FakeObj != null)
{
_FakeObj.Disable();
_RawImage.texture = null;
_RawImage.color = Color.white;
}
_openRawImageFrame = int.MaxValue;
}
}
public void SetOpenFrame()
{
_openRawImageFrame = Time.frameCount + 1;
}
private void OnDestroy()
{
if (!GameManager.applicationQuit)
DestroyObj();
}
public void DestroyObj()
{
if (_FakeObj != null)
{
_FakeObj.Destroy();
_FakeObj = null;
}
}
// public void ShowRawImage()
// {
// if (enabled && gameObject.activeInHierarchy)
// StartCoroutine(ShowRawImageNextFrame());
// else
// _RawImage.enabled = true;
// }
// private IEnumerator ShowRawImageNextFrame()
// {
// yield return null;
// _RawImage.enabled = true;
// }
private Obj_FakeShow InitFakeShowObj()
{
var result = _FakeObj == null ? null : _FakeObj.FakeObj;
return result;
}
public void DisAbleFake()
{
_hideFakeShow = true;
}
public void EnAbleFake()
{
_hideFakeShow = false;
}
private void LateUpdate()
{
if (_hideFakeShow != _currentHideFakeShow)
{
_currentHideFakeShow = _hideFakeShow;
if (_FakeObj != null && _FakeObj.ShowingModel != null)
_FakeObj.ShowingModel.SetActive(_currentHideFakeShow);
}
}
private void InitFakeShow(Obj_FakeShow fakeShow, Obj_FakeShow_Init_Data initData)
{
if (initData.m_Hash == null)
initData.m_Hash = new Hashtable();
//initData.m_Hash["ShowRawImage"] = (InitOverCallBack) ShowRawImage;
fakeShow.Init(initData);
}
private void CreateModel(Obj_FakeShow fakeShow, Obj_FakeShow_Init_Data initData, string modelPath, bool isBody,
string bodyPos, string bodyRot, string halfPos, string halfRot, Hashtable table = null)
{
if (table == null)
table = new Hashtable();
table["_FakeObj"] = _FakeObj;
//table["ShowRawImage"] = (InitOverCallBack) ShowRawImage;
if (isBody)
{
table["Pos"] = StrToVector3(bodyPos);
table["Rot"] = StrToVector3(bodyRot);
}
else
{
table["Pos"] = StrToVector3(halfPos);
table["Rot"] = StrToVector3(halfRot);
}
if (initData != null)
{
initData.m_Hash = table;
fakeShow.Init(initData);
}
else
{
fakeShow.CreateModel(-1, modelPath, table);
}
}
/// <summary>
/// 清空当前使用的模型文件
/// </summary>
public void RemoveModel()
{
if (_FakeObj != null && _FakeObj.FakeObj != null)
_FakeObj.FakeObj.RemoveModels();
}
// isBody = true 全身像; fase 半身像
public bool InitModelPath(string resPath, Tab_CharModel modelTab, string bundle = LoadAssetBundle.BUNDLE_PATH_MODEL,
bool isBody = false, InitModelPathCallBack callBack = null,
bool isSettedOrthSize = false, int profession = -1)
{
InitImage();
var fakeShow = InitFakeShowObj();
if (fakeShow != null)
{
if (string.IsNullOrEmpty(resPath) && modelTab != null && modelTab.Id == fakeShow.ModelID)
{
SetOpenFrame();
EnAbleFake();
return false;
}
if (fakeShow.ModelNode != null && modelTab == null && string.IsNullOrEmpty(resPath) == false &&
resPath == fakeShow.ModelNode.targetModel)
{
SetOpenFrame();
EnAbleFake();
return false;
}
var initData = new Obj_FakeShow_Init_Data
{
m_nProfession = -1,
m_ModelVisualID = -1,
m_WeaponDataID = -1,
m_WeaponEffectGem = -1,
m_WingAuraId = -1,
m_EffectAuraId = -1,
m_AdvanceWingId = -1,
BundlePath = bundle,
FakeModelPath = resPath
};
if (modelTab != null)
initData.m_ModelVisualID = modelTab.Id;
if (profession != -1)
initData.m_nProfession = profession;
if (callBack != null)
{
if (initData.m_Hash == null)
initData.m_Hash = new Hashtable();
initData.m_Hash.Add("InitModelPathCallBack", callBack);
}
if (isSettedOrthSize)
{
if (initData.m_Hash == null)
initData.m_Hash = new Hashtable();
initData.m_Hash.Add("isSettedOrthSize", callBack);
}
if (modelTab == null)
InitFakeShow(fakeShow, initData);
else
CreateModel(fakeShow, initData, "", isBody, modelTab.BodyPos, modelTab.BodyRot, modelTab.HalfPos,
modelTab.HalfRot, initData.m_Hash);
}
return true;
}
/// <summary>
/// CharModelId如果是人物时装需要转换成对应的CharModelId
/// 通过:Globaldata.GetCharModel(职业, 时装ID)获取
/// </summary>
/// <param name="profession"></param>
/// <param name="charModeld"></param>
/// <param name="weaponID"></param>
/// <param name="WingID"></param>
/// <param name="weaponEffectID"></param>
/// <param name="modelEffectID"></param>
/// <param name="advanceWingId"></param>
/// <param name="charModel"></param>
/// <param name="isBody"></param>
public void InitModel(int profession, int charModeld, int weaponID = -1, int WingID = -1, int weaponEffectID = -1,
int modelEffectID = -1, int advanceWingId = -1, Tab_CharModel charModel = null, bool isBody = true)
{
InitImage();
var fakeShow = InitFakeShowObj();
if (fakeShow == null) return;
var initData = new Obj_FakeShow_Init_Data
{
m_nProfession = profession,
m_ModelVisualID = charModeld,
m_WeaponDataID = weaponID,
m_WeaponEffectGem = weaponEffectID,
m_WingAuraId = WingID,
m_EffectAuraId = modelEffectID,
m_AdvanceWingId = advanceWingId
};
if (fakeShow.ModelNode.model != null && initData.IsVisualMatch(fakeShow))
{
fakeShow.ModelNode.model.transform.localRotation = Quaternion.identity;
}
else
{
if (charModel == null)
charModel = TableManager.GetCharModelByID(initData.m_ModelVisualID, 0);
if (charModel == null)
InitFakeShow(fakeShow, initData);
else
CreateModel(fakeShow, initData, string.Empty, isBody, charModel.BodyPos, charModel.BodyRot,
charModel.HalfPos,
charModel.HalfRot);
}
}
public void InitPlayerModel(Obj_Character Shower_Character, bool isBody = true, InitOverCallBack callBack = null)
{
if (Shower_Character == null)
return;
InitImage();
var fakeShow = InitFakeShowObj();
if (fakeShow == null)
return;
if (fakeShow.ModelNode.model != null &&
fakeShow.IsVisualMatch(Shower_Character))
{
_FakeObj.ShowingModel.transform.localRotation = Quaternion.identity;
SetOpenFrame();
EnAbleFake();
}
else
{
//没有时装显示默认模型
var tabItemVisual = TableManager.GetItemVisualByID(Shower_Character.ModelVisualID, 0);
if (tabItemVisual == null)
{
tabItemVisual = TableManager.GetItemVisualByID(GlobeVar.DEFAULT_VISUAL_ID, 0);
if (tabItemVisual == null) return;
}
var nCharmodelId = fakeShow.GetCharModelID(tabItemVisual, Shower_Character.Profession);
var charModel = TableManager.GetCharModelByID(nCharmodelId, 0);
if (charModel == null) return;
var initData = new Obj_FakeShow_Init_Data
{
m_nProfession = Shower_Character.Profession,
m_ModelVisualID = nCharmodelId,
m_WeaponDataID = Shower_Character.WeaponDataID,
m_WeaponEffectGem = Shower_Character.WeaponEffectGem,
m_WingAuraId = Shower_Character.WingModelAuraid,
m_EffectAuraId = Shower_Character.EffectAuraId,
m_AdvanceWingId = Shower_Character.IsShowWing ? Shower_Character.AdvanceWingId : -1
};
if (callBack != null)
{
if (initData.m_Hash == null)
initData.m_Hash = new Hashtable();
initData.m_Hash.Add("InitOverCallBack", callBack);
}
CreateModel(fakeShow, initData, "", isBody, charModel.BodyPos, charModel.BodyRot, charModel.HalfPos,
charModel.HalfRot, initData.m_Hash);
}
}
public void InitMountModelPath(Tab_CharMount mountTab, InitOverCallBack callBack = null)
{
if (mountTab == null)
return;
InitImage();
var fakeShow = InitFakeShowObj();
if (fakeShow != null)
{
Hashtable hash = null;
if (callBack != null)
hash = new Hashtable {{"InitOverCallBack", callBack}};
CreateModel(fakeShow, null, mountTab.MountModel, true, mountTab.BodyPos, mountTab.BodyRot, "", "", hash);
}
}
public void InitWingModelPath(Tab_AdvanceBase advanceBase, Tab_WeaponModel wingData = null,
InitOverCallBack callBack = null)
{
InitImage();
if (wingData == null)
{
var auraConfig = TableManager.GetAuraConfigByID(advanceBase.ModelId, 0);
if (auraConfig == null)
return;
switch (GameManager.gameManager.PlayerDataPool.MainPlayerBaseAttr.Profession)
{
case (int) CharacterDefine.PROFESSION.TIANJI:
{
wingData = TableManager.GetWeaponModelByID(auraConfig.TianJiWingModelId, 0);
break;
}
case (int) CharacterDefine.PROFESSION.SHUSHAN:
{
wingData = TableManager.GetWeaponModelByID(auraConfig.ShuShanWingModelId, 0);
break;
}
case (int) CharacterDefine.PROFESSION.LIUSHAN:
{
wingData = TableManager.GetWeaponModelByID(auraConfig.LiuShanWingModelId, 0);
break;
}
case (int) CharacterDefine.PROFESSION.XUANNV:
{
wingData = TableManager.GetWeaponModelByID(auraConfig.XuanNvWingModelId, 0);
break;
}
}
}
if (wingData == null)
return;
var fakeShow = InitFakeShowObj();
// 注:"isWing"这个标签唯一作用是强制配置ResPath到默认加载路径实际底层会自动回落到默认路径
// "isWing"标签已经在底层移除
//hash.Add("isWing", true);
if (fakeShow != null)
{
var hash = new Hashtable();
if (callBack != null)
hash.Add("InitOverCallBack", callBack);
fakeShow.RealoadWingModel();
CreateModel(fakeShow, null, wingData.ResPathR, true, wingData.BodyPos, wingData.BodyRot, "", "", hash);
}
}
private static Vector3 StrToVector3(string strValue)
{
var splitStrs = strValue.Split(';');
if (splitStrs.Length != 3)
{
LogModule.ErrorLog("StrToVector3 error:" + strValue);
return Vector3.zero;
}
return new Vector3(float.Parse(splitStrs[0]), float.Parse(splitStrs[1]), float.Parse(splitStrs[2]));
}
#region
public class FakeShowObj
{
public FakeShowObj(GameObject rootObj, Camera camera, float cameraSize, RawImage rawImage)
{
FakeObj = rootObj.EnsureComponent<Obj_FakeShow>();
renderCamera = camera;
renderCamera.orthographicSize = cameraSize <= 0f ? 1f : cameraSize;
renderCamera.cullingMask = renderCamera.gameObject.layer.ToFlag();
renderCamera.enabled = false;
_rawImage = rawImage;
DontDestroyOnLoad(renderCamera.gameObject);
}
public Obj_FakeShow FakeObj { get; private set; }
public Camera renderCamera { get; private set; }
public RenderTexture renderTexture { get; private set; }
private readonly RawImage _rawImage;
public GameObject ShowingModel
{
get
{
return FakeObj != null && FakeObj.ModelNode.model != null ? FakeObj.ModelNode.model.gameObject : null;
}
}
public void Enable()
{
if (renderTexture == null)
{
var size = GetTextureSize();
if (size != Vector2.zero)
renderTexture = RenderTexturePool.Instance.GetRenderTexture(size);
}
if (renderTexture != null)
{
renderCamera.targetTexture = renderTexture;
EventDispatcher.Instance.Remove(Games.Events.EventId.PostUiCameraRender, OnUiCameraRender);
EventDispatcher.Instance.Add(Games.Events.EventId.PostUiCameraRender, OnUiCameraRender);
//renderCamera.enabled = true;
}
}
public void Disable()
{
if (renderTexture != null)
{
RenderTexturePool.Instance.ReleaseRenderTexture(renderTexture);
renderTexture = null;
}
if (renderCamera != null)
{
renderCamera.enabled = false;
EventDispatcher.Instance.Remove(Games.Events.EventId.PostUiCameraRender, OnUiCameraRender);
//renderCamera.targetTexture = null;
}
FakeObj.RemoveModels();
}
private void OnUiCameraRender(object args)
{
renderCamera.Render();
}
public bool IsInAnimTransistion()
{
return FakeObj != null && FakeObj.IsInAnimTransistion();
}
public void Destroy()
{
Disable();
if (FakeObj != null)
{
FakeObj.DestroyObj();
Object.Destroy(FakeObj.gameObject);
FakeObj = null;
}
if (renderCamera != null)
{
Object.Destroy(renderCamera.gameObject);
renderCamera = null;
}
}
private Vector2 GetTextureSize()
{
var result = Vector2.zero;
if (_rawImage != null)
{
var imageSize = _rawImage.rectTransform.rect.size;
if (imageSize.x > 0f && imageSize.y > 0f)
{
// 贴图尺寸校正到单边不超过512
//var ratio = Mathf.Min(512f / imageSize.x, 512f / imageSize.y, 1f);
result = imageSize;// * ratio;
}
}
return result;
}
}
#endregion
#region opt
public bool _CanDrag = true; //有些模型需要不能转动
public void OnDrag(PointerEventData eventData)
{
if (_CanDrag)
if (_FakeObj != null && _FakeObj.FakeObj != null)
{
var eular = _FakeObj.FakeObj.transform.localRotation.eulerAngles;
eular.y -= eventData.delta.x;
_FakeObj.FakeObj.transform.localRotation = Quaternion.Euler(eular);
}
}
#endregion
}