Files
JJBB/Assets/Project/Script/Scene/SceneLogic/SceneLogic.cs

480 lines
19 KiB
C#
Raw Normal View History

2024-08-23 15:49:34 +08:00
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<Obj_JumpPoint> _jumpPoints = new List<Obj_JumpPoint>();
private readonly List<Obj_TeleportPoint> _teleportPoints = new List<Obj_TeleportPoint>();
/// <summary>
/// 每帧追踪FPS的流程
/// </summary>
private FpsTracker _frameTracker;
private float _nextAssetClean;
/// <summary>
/// 每帧更新的流程
/// </summary>
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<GameObject>("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<ShaderFix>();
if (shaderFix != null)
gameObject.AddComponent<ShaderFix>();
}
// 试图清除额外的摄像机和音效接收器
var audioListeners = FindObjectsOfType<AudioListener>();
for (var i = 0; i < audioListeners.Length; i++)
if (audioListeners[i] != null && audioListeners[i].GetComponent<Camera>() != 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<SubSceneLoader>();
//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<IndependentEffectManager>();
// 重新赋值雾效设置 - 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<Camera>();
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<GameObject>(GlobeVar.sceneCameraName);
cameraObj = Instantiate(prefab);
DontDestroyOnLoad(cameraObj);
cameraObj.TrimCloneInName();
}
CameraController = cameraObj.EnsureComponent<CameraController>();
}
else
{
CameraController.EnableSceneCamera(true);
}
if (FirstShowScene.CanFindMissionPath() == false && Singleton<ObjManager>.Instance.MainPlayer != null)
{
var distance = Vector3.Distance(GameManager.gameManager.SceneLogic.transform.position,
Singleton<ObjManager>.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<Renderer>();
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();
}
}
}
}
}