2025-05-18 01:04:31 +08:00

361 lines
7.6 KiB
C#
Raw 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.

// ***********************************************************************
// 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
}
}