Files
2024-08-23 15:49:34 +08:00

480 lines
19 KiB
C#
Raw Permalink 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 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();
}
}
}
}
}