361 lines
7.6 KiB
C#
Raw Permalink Normal View History

2025-05-18 01:04:31 +08:00
// ***********************************************************************
// Assembly : Unity
// Author : Kimch
// Created : 2018-2-29
// Description : 游戏当前场景,负责游戏的场景数据保存和提供常用方法
// Last Modified By :
// Last Modified On :
// ***********************************************************************
// <copyright file= "GameScene" company=""></copyright>
// <summary></summary>
// ***********************************************************************
#define USE_AddressableAssets
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using Object = UnityEngine.Object;
namespace G
{
partial class GameScene : MonoBehaviour, F.IAsyncResult
{
#region Field
public event Action enterSceneCallback;
public readonly Dictionary<string, Object> sceneCommonAssets = new Dictionary<string, Object>();
private object _sceneUserData;
#endregion
#region Property
/// <summary>
/// 当前场景的服务器ID考虑到副本场景可能资源ID和场景服务器ID不一致的情况
/// </summary>
public int sceneId
{
get;
set;
}
/// <summary>
/// 配置表Id
/// </summary>
public int itemId
{
get;
set;
}
/// <summary>
///
/// </summary>
public bool isLoading
{
get;
private set;
}
#endregion
#region Method
/// <summary>
/// 暂时只用一个场景
/// </summary>
/// <param name="id"></param>
public void EnterScene(int id, object userData = null)
{
_sceneUserData = userData;
if (id == 0)
{
if (this.sceneId != 0)
{
this.sceneId = 0;
this.itemId = 0;
//GameLevel.Instance.OnExitScene();
//EntityManager.Instance.OnExitScene();
//Platform.Instance.ReportEvent("exit_scene", "");
}
StartCoroutine(LoadScene(id));
}
else if (this.sceneId != id)
{
this.sceneId = 1;
this.itemId = id;
StartCoroutine(LoadScene(id));
//Platform.Instance.ReportEvent("enter_scene", "");
}
else
{
this.sceneId = 2;
this.OnEnterSceneCompleted(0);
}
}
private void OnEnterSceneCompleted(int code)
{
if (this.sceneId != 0)
{
//初始化数据
//InitSceneCamera();
//KUIWindow.CloseWindow<UI.LoadWindow>();
//KUIWindow.OpenWindow<UI.GameWindow>();
}
else
{
this.isLoading = false;
if ("again_level".Equals(_sceneUserData))
{
if (LevelProxy.Instance.AgainStartLevel() != 0)
{
KUIWindow.OpenWindow<UI.MainWindow>(_sceneUserData);
}
}
else if ("endless".Equals(_sceneUserData))
{
KUIWindow.OpenWindow<UI.MainWindow>(_sceneUserData);
KUIWindow.OpenWindow<UI.EndlessWindow>(_sceneUserData);
}
else if ("sword".Equals(_sceneUserData))
{
KUIWindow.OpenWindow<UI.MainWindow>(_sceneUserData);
KUIWindow.OpenWindow<UI.SwordWindow>(_sceneUserData);
}
else if ("copy".Equals(_sceneUserData))
{
KUIWindow.OpenWindow<UI.MainWindow>(_sceneUserData);
KUIWindow.OpenWindow<UI.QingMingWindow>(_sceneUserData);
}
else
{
//打开主界面
KUIWindow.OpenWindow<UI.MainWindow>(_sceneUserData);
}
}
enterSceneCallback?.Invoke();
}
/// <summary>
///
/// </summary>
/// <param name="id"></param>
private IEnumerator LoadCommon(int id)
{
if (id > 0 && sceneCommonAssets.Count == 0)
{
_progress = 0f;
AssetProxy.Instance.CreateReleasePool("scene_common");
var handle = AssetProxy.Instance.TryGetAssetsAsync<GameObject>("w_common", "scene_common");
yield return handle;
if (handle.Status == AsyncOperationStatus.Succeeded)
{
var objs = handle.Result;
foreach (GameObject obj in objs)
{
#if UNITY_EDITOR
Debug.Log(obj.name);
#endif
sceneCommonAssets[obj.name] = obj;
}
}
_progress = 0.2f;
}
}
private void UnloadCommon()
{
sceneCommonAssets.Clear();
AssetProxy.Instance.RemoveReleasePool("scene_common");
}
/// <summary>
///
/// </summary>
/// <param name="id"></param>
private IEnumerator LoadScene(int id)
{
if (id > 0)
{
KUIWindow.OpenWindow<UI.LoadWindow>(this);
yield return LoadCommon(id);
LoadSceneAsync("stage", this.OnEnterSceneCompleted);
}
else
{
LoadSceneAsync("main", this.OnEnterSceneCompleted);
}
}
public void EnterCopyScene(int id)
{
if (this.sceneId != id)
{
this.sceneId = 1;
this.itemId = id;
StartCoroutine(LoadCopyScene(id));
}
}
private IEnumerator LoadCopyScene(int id)
{
if (id == 8888)
{
KUIWindow.OpenWindow<UI.LoadWindow>(this);
yield return null;
LoadSceneAsync("stage_ride", this.OnEnterSceneCompleted);
}
}
#endregion
#region Async
/// <summary>
///
/// </summary>
private string _currentSceneName;
private bool _loading;
private float _progress;
#if USE_AddressableAssets
AsyncOperationHandle _sceneAOHandle;
#endif
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="action"></param>
public void LoadSceneAsync(string name, Action<int> completed)
{
StartCoroutine(LoadSceneCoroutine(name, completed));
}
/// <summary>
///
/// </summary>
public void UnloadScene()
{
StartCoroutine(LoadSceneCoroutine(null, null));
}
/// <summary>
///
/// </summary>
/// <param name="sceneName"></param>
/// <param name="completed"></param>
/// <returns></returns>
private IEnumerator LoadSceneCoroutine(string sceneName, Action<int> completed)
{
if (_currentSceneName == sceneName)
{
completed?.Invoke(0);
yield break;
}
_loading = true;
_progress = 0f;
if (!string.IsNullOrEmpty(_currentSceneName))
{
//#if USE_AddressableAssets
// var unloadHandle = Addressables.UnloadSceneAsync(_sceneAOHandle);
// while (!unloadHandle.IsDone)
// {
// _progress = unloadHandle.PercentComplete * 0.2f + 0.2f;
// yield return null;
// }
//#else
// var asyncOp = SceneManager.UnloadSceneAsync(_currentSceneName);
// if (asyncOp != null)
// {
// while (!asyncOp.isDone)
// {
// _progress = asyncOp.progress * 0.2f;
// yield return null;
// }
// }
//#endif
var asyncOp = Resources.UnloadUnusedAssets();
if (asyncOp != null)
{
while (!asyncOp.isDone)
{
_progress = asyncOp.progress * 0.2f;
yield return null;
}
}
_currentSceneName = null;
}
if (!string.IsNullOrEmpty(sceneName))
{
#if USE_AddressableAssets
var asyncOp = Addressables.LoadSceneAsync(sceneName);
while (!asyncOp.IsDone)
{
_progress = asyncOp.PercentComplete * 0.8f + 0.2f;
yield return null;
}
_sceneAOHandle = asyncOp;
#else
var asyncOp = SceneManager.LoadSceneAsync(name);
while (!asyncOp.isDone)
{
_progress = asyncOp.progress * 0.8f + 0.2f;
yield return null;
}
#endif
_progress = 1f + float.Epsilon;
_currentSceneName = sceneName;
}
_loading = false;
completed?.Invoke(0);
}
bool F.IAsyncResult.isDone
{
get { return _progress > 1f; }
}
string F.IAsyncResult.errorMsg
{
get { return ""; }
}
float F.IAsyncResult.progress
{
get { return _progress; }
}
object F.IAsyncResult.userData
{
get { return this; }
}
#endregion
#region Unity
public static GameScene Instance;
private void Awake()
{
Instance = this;
}
#endregion
}
}