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