using System.Collections; using System.Collections.Generic; using System.Linq; using Games.Events; using Games.GlobeDefine; using Games.LogicObj; using GCGame.Table; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; namespace Games.Scene { public class SceneLogic : MonoBehaviour { public const string playerLightColor = "_PlayerLightStrength"; public const string playerLightPos = "_PlayerLightPos"; public const string playerLightKeyword = "PLAYER_HALO_ON"; //public bool allowSphereCast; public bool forceNoFog; public float playerHalo = -1f; private readonly List _jumpPoints = new List(); private readonly List _teleportPoints = new List(); /// /// 每帧追踪FPS的流程 /// private FpsTracker _frameTracker; private float _nextAssetClean; /// /// 每帧更新的流程 /// private UnityAction _updateAction; public DropItemPool dropItemPool { get; private set; } ////////////////////////////////////////////////////////////////////////// //摄像机相关 ////////////////////////////////////////////////////////////////////////// public static CameraController CameraController { get; private set; } private void Awake() { //_hideLevels[0].Apply(); _updateAction = CleanPool; // 根据当前光辉强度配置 if (playerHalo > 0f) { _updateAction += UpdatePlayerHalo; if (!Shader.IsKeywordEnabled(playerLightKeyword)) Shader.EnableKeyword(playerLightKeyword); Shader.SetGlobalFloat(playerLightColor, playerHalo); } else { if (Shader.IsKeywordEnabled(playerLightKeyword)) Shader.DisableKeyword(playerLightKeyword); } // 添加Fps跟踪功能 Debug.Assert(GameManager.gameManager != null, "GameManager.gameManager != null"); if (GameManager.gameManager.RunningScene != (int) GameDefine_Globe.SCENE_DEFINE.SCENE_LOGIN && !GameManager.gameManager.ActiveScene.IsCopyScene()) { var qualityLevel = PlayerPreferenceData.GetQualityLevel(); if (qualityLevel > 0) { _frameTracker = new FpsTracker(); _updateAction += UpdateFpsTracker; } } //if (GameManager.gameManager.RunningScene != (int) GameDefine_Globe.SCENE_DEFINE.SCENE_LOGIN) //{ // //if (GameManager.gameManager.useGraphicsNotice) // // _frameTracker = new FpsTracker(ProcessGraphicsNotice); // //else // _frameTracker = new DynamicHideTracker(); // _updateAction += TrackFps; //} // if (PlatformHelper.HasSDKObject() == false) // Instantiate(Resources.Load("AndroidHelper")); //将当前场景SceneLogic放入GameManager暂存 if (GameManager.gameManager != null) GameManager.gameManager.SceneLogic = this; dropItemPool = new DropItemPool(transform); CameraController.ForceNoFog(forceNoFog, 1); // // 将Debug工具挂入场景,函数内部会处理是否有Debug模式 // DebugHelper.CreateDebugHelper(); // 动态加载场景无法加载SHADER问题 #if UNITY_EDITOR if (!AssetUpdateManager.useResources) { var shaderFix = FindObjectOfType(); if (shaderFix != null) gameObject.AddComponent(); } // 试图清除额外的摄像机和音效接收器 var audioListeners = FindObjectsOfType(); for (var i = 0; i < audioListeners.Length; i++) if (audioListeners[i] != null && audioListeners[i].GetComponent() != null) { var root = audioListeners[i].transform.root; if (root != null) Destroy(root.gameObject); } #endif } // Use this for initialization //场景内部初始化在此进行 private void Start() { SceneManager.SetActiveScene(gameObject.scene); // 试图卸载当前场景Bundle;拥有子场景的条件下,由子场景加载器实现卸载Bundle; //var subSceneLoader = gameObject.GetComponent(); //if (subSceneLoader == null) //{ // var sceneLoader = LoadAssetBundle.Instance.sceneLoader; // // 注:测试发现RoleSelect会出现诡异情况,因此过滤掉LoadSceneModel 为Additive的情况 // if (sceneLoader != null && sceneLoader.loadMode == LoadSceneMode.Single) // LoadAssetBundle.Instance.UnloadSceneBundle(); //} if (GameManager.gameManager != null) if (GameManager.gameManager.RunningScene != (int) GameDefine_Globe.SCENE_DEFINE.SCENE_LOGIN) GameManager.gameManager.ActiveScene.Init(); // 添加独立特效管理器 // 注:SceneLogic有同时存在两份的诡异情况 if (IndependentEffectManager.Instance == null) gameObject.AddComponent(); // 重新赋值雾效设置 - Hack处理LoginShow。 // if (LoginShow.Instance == null) // RenderSettings.fog = PlayerPreferenceData.SystemQualityFog; EventDispatcher.Instance.Add(EventId.SceneIdUpdate, OnSceneIdUpdate); Debug.Assert(GameManager.gameManager != null, "GameManager.gameManager != null"); OnSceneIdUpdate(GameManager.gameManager.RunningScene); // 删除主要摄像机 #if UNITY_EDITOR if (CameraController != null) { var cameraArray = FindObjectsOfType(); for (var i = 0; i < cameraArray.Length; i++) if (cameraArray[i].gameObject.CompareTag("MainCamera") && CameraController.MainCamera != cameraArray[i]) Destroy(cameraArray[i].gameObject); } #endif #if UNITY_EDITOR if (!AssetUpdateManager.useResources) StartCoroutine(ResetShader()); #endif } private void LateUpdate() { //#if UNITY_EDITOR // if (Input.GetKeyDown(KeyCode.G)) // UIManager.ShowUI(UIInfo.GraphicsNotice); //#endif _updateAction.Invoke(); } private void OnDestroy() { EventDispatcher.Instance.Remove(EventId.SceneIdUpdate, OnSceneIdUpdate, true); } private void OnApplicationFocus(bool hasFocus) { // 失去焦点和获得焦点时,试图重置帧率追踪器 if (_frameTracker != null) _frameTracker.Reset(); } public static void InitCameraControl() { if (CameraController == null) { var cameraObj = GameObject.Find(GlobeVar.sceneCameraName); if (cameraObj == null) { var prefab = CommonUtility.LoadFromResources(GlobeVar.sceneCameraName); cameraObj = Instantiate(prefab); DontDestroyOnLoad(cameraObj); cameraObj.TrimCloneInName(); } CameraController = cameraObj.EnsureComponent(); } else { CameraController.EnableSceneCamera(true); } if (FirstShowScene.CanFindMissionPath() == false && Singleton.Instance.MainPlayer != null) { var distance = Vector3.Distance(GameManager.gameManager.SceneLogic.transform.position, Singleton.Instance.MainPlayer.Position); if (distance <= 20) FirstShowScene.SetCameraPos(); } } public static void UninitCameraControl() { if (CameraController != null) { CameraController.DestroyCamera(); CameraController = null; } } private IEnumerator ResetShader() { var objs = FindObjectsOfType(); for (var i = 0; i < objs.Length; i++) { var render = objs[i]; if (render == null) continue; for (var j = 0; j < render.sharedMaterials.Length; j++) if (render.sharedMaterials[j] != null && render.sharedMaterials[j].shader != null) { var shader = Shader.Find(render.sharedMaterials[j].shader.name); render.sharedMaterials[j].shader = shader; } yield return new WaitForEndOfFrame(); } } private void OnSceneIdUpdate(object args) { var sceneId = (int) args; if (sceneId != (int) GameDefine_Globe.SCENE_DEFINE.SCENE_LOGIN && sceneId != (int) GameDefine_Globe.SCENE_DEFINE.SCENE_LOADINGSCENE && sceneId != (int) GameDefine_Globe.SCENE_DEFINE.SCENE_FIRSTSHOW) RefreshSceneItems(sceneId); } public void RefreshSceneItems(int sceneId, GameObject JumpParent = null) { // 反激活不属于当前场景的传送器 for (var i = 0; i < _jumpPoints.Count; i++) { var isActive = _jumpPoints[i].jumpData.SceneClassId == sceneId; _jumpPoints[i].gameObject.SetActive(isActive); } for (var i = 0; i < _teleportPoints.Count; i++) _teleportPoints[i].gameObject.SetActive(_teleportPoints[i].teleportData.SrcSceneID == sceneId); // 试图添加当前场景的传送器 var jumpTables = from keyValue in TableManager.GetJump().Values where keyValue.SceneClassId == sceneId && keyValue.RangeRadius > 0f select keyValue; var teleportTables = from keyValue in TableManager.GetTeleport().Values where keyValue.SrcSceneID == sceneId && keyValue.ActiveRadius > 0f select keyValue; foreach (var jumpData in jumpTables) { var jumpPoint = _jumpPoints.Find(a => a.jumpData.JumpId == jumpData.JumpId); if (jumpPoint == null) { var initData = new Obj_JumpPoint_Init_Data { m_fX = jumpData.StartPosX, m_fZ = jumpData.StartPosZ, jumpData = jumpData }; jumpPoint = (Obj_JumpPoint) ObjManager.Instance.NewCharacterObj( GameDefine_Globe.OBJ_TYPE.OBJ_JUMPPOINT, initData); if (JumpParent != null) jumpPoint.transform.SetParent(JumpParent.transform, true); _jumpPoints.Add(jumpPoint); } } foreach (var teleportData in teleportTables) { var teleportPoint = _teleportPoints.Find(a => a.teleportData.Id == teleportData.Id); if (teleportPoint == null) { var initData = new Obj_Teleport_Init_Data { m_fX = teleportData.SrcPosX, m_fZ = teleportData.SrcPosZ, Teleport = teleportData }; teleportPoint = (Obj_TeleportPoint) ObjManager.Instance.NewCharacterObj( GameDefine_Globe.OBJ_TYPE.OBJ_TELEPORTPOINT, initData); _teleportPoints.Add(teleportPoint); } } // ******** 处理采集物 ******** CollectItem.Instance.InitCollectItem(sceneId); } // 拿给_updateAction的占位函数 private void CleanPool() { //开始每分钟一次循环 if (GameManager.gameManager != null && Time.unscaledTime > _nextAssetClean) { _nextAssetClean = Time.unscaledTime + 10f; // 大约10秒执行一次模型池回收 if (GameManager.gameManager.modelPool != null) GameManager.gameManager.modelPool.CleanUnusedPool(10f); // 特效池清理略微慢一些,加载挺不容易的 if (GameManager.gameManager.effectPool != null) GameManager.gameManager.effectPool.CleanUnusedPool(60f); GameManager.gameManager.UnloadUnusedAssets(); } } private void UpdatePlayerHalo() { var mainPlayer = ObjManager.Instance.MainPlayer; if (mainPlayer != null) { var playerPosition = mainPlayer.Position; Shader.SetGlobalVector(playerLightPos, new Vector4(playerPosition.x, playerPosition.y + 1F, playerPosition.z, 0f)); } } private void UpdateFpsTracker() { if (_frameTracker == null || !_frameTracker.Update()) _updateAction -= UpdateFpsTracker; } // private void OnApplicationPause(bool paused) // { // if (!paused) // PushNotification.CleanNotification(); // if (GlobeVar.s_FirstInitGame) // return; // //程序进入后台时 // if (paused) // { // PushNotification.CleanNotification(); // PushNotification.NotificationMessage2Clinet(); // LogModule.DebugLog("OnApplicationPause:NotificationMessage2Server"); // PushNotification.NotificationMessage2Server(); // } // } //private void ProcessGraphicsNotice(int delta) //{ // GameManager.gameManager.useGraphicsNotice = false; // _frameTracker = new DynamicHideTracker(); // int targetQuality; // if (delta > 0) // { // var quality = PlayerPreferenceData.GetQualityLevel(); // if (quality < PlayerPreferenceData.qualityStandards.Length - 1) // targetQuality = quality + 1; // else // targetQuality = GlobeVar.INVALID_ID; // } // else if (delta < 0) // { // var quality = PlayerPreferenceData.GetQualityLevel(); // if (quality > 0) // targetQuality = quality - 1; // else // targetQuality = GlobeVar.INVALID_ID; // } // // 追踪时间过长时,认为中等配置为合适配置 // else // { // targetQuality = -2; // } // if (targetQuality > GlobeVar.INVALID_ID) // { // GraphicsNoticeLogic.targetQualityLevel = targetQuality; // UIManager.ShowUI(UIInfo.GraphicsNotice); // } //} private class FpsTracker { private const float _downFpsThreshold = 1f / 15; // _trackTime内,如果没有连续_breakThreshold的达标帧率,视为降级 private const float _trackTime = 30f; private const float _breakTime = 1f; // 跳过初始化的时间 private const float _delayTime = 5f; // 跳过初始化的帧数 private const int _delayFrame = 20; // 自动确定间隔时间 private const float _autoConfirmDelay = 5f; private float _breakStart; private float _downStart; private float _startFrame; private float _startTime; public FpsTracker() { Reset(); } public void Reset() { _downStart = Time.unscaledTime; _breakStart = Time.unscaledTime; _startTime = Time.unscaledTime; _startFrame = Time.frameCount; } public bool Update() { var result = true; if (LoadingWindow._IsLoadingScene) { Reset(); } else if (Time.unscaledTime < _startTime + _delayTime || Time.frameCount < _startFrame + _delayFrame) { _breakStart = Time.unscaledTime; _downStart = Time.unscaledTime; } // 出现低帧率,重置break条件,监测是否达到降级条件 if (Time.unscaledDeltaTime > _downFpsThreshold) { _breakStart = Time.unscaledTime; if (_downStart + _trackTime < Time.unscaledTime) { result = false; _downStart = Time.unscaledTime; ShowPopup(); } } // 出现连续_breakTime的达标帧率 else if (_breakStart + _breakTime < Time.unscaledTime) { _downStart = Time.unscaledTime; _breakStart = Time.unscaledTime; } return result; } private void ShowPopup() { // 注:有可能玩家在过程中已经调低画质 if (PlayerPreferenceData.GetQualityLevel() > 0) MessageBoxLogic.OpenAutoConfirmBox(StrDictionary.GetClientDictionaryString("#{86001}"), null, _autoConfirmDelay, ReduceCurrentQuality); } private static void ReduceCurrentQuality() { // 注:有可能玩家在过程中已经调低画质 var quality = PlayerPreferenceData.GetQualityLevel(); if (quality > 0) { var qualitySetting = PlayerPreferenceData.qualityStandards[quality - 1]; qualitySetting.ApplyToCurrent(); } } } } }