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 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(); 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); } } /// /// 清空当前使用的模型文件 /// 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; } /// /// CharModelId如果是人物时装需要转换成对应的CharModelId /// 通过:Globaldata.GetCharModel(职业, 时装ID)获取 /// /// /// /// /// /// /// /// /// /// 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(); 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 }