// ***********************************************************************
// Assembly : Unity
// Author : Kimch
// Created : 2018-2-29
// Description : 游戏当前场景,负责游戏的场景数据保存和提供常用方法
// Last Modified By :
// Last Modified On :
// ***********************************************************************
//
//
// ***********************************************************************
#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 sceneCommonAssets = new Dictionary();
private object _sceneUserData;
#endregion
#region Property
///
/// 当前场景的服务器ID(考虑到副本场景可能资源ID和场景服务器ID不一致的情况)
///
public int sceneId
{
get;
set;
}
///
/// 配置表Id
///
public int itemId
{
get;
set;
}
///
///
///
public bool isLoading
{
get;
private set;
}
#endregion
#region Method
///
/// 暂时只用一个场景
///
///
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();
//KUIWindow.OpenWindow();
}
else
{
this.isLoading = false;
if ("again_level".Equals(_sceneUserData))
{
if (LevelProxy.Instance.AgainStartLevel() != 0)
{
KUIWindow.OpenWindow(_sceneUserData);
}
}
else if ("endless".Equals(_sceneUserData))
{
KUIWindow.OpenWindow(_sceneUserData);
KUIWindow.OpenWindow(_sceneUserData);
}
else if ("sword".Equals(_sceneUserData))
{
KUIWindow.OpenWindow(_sceneUserData);
KUIWindow.OpenWindow(_sceneUserData);
}
else if ("copy".Equals(_sceneUserData))
{
KUIWindow.OpenWindow(_sceneUserData);
KUIWindow.OpenWindow(_sceneUserData);
}
else
{
//打开主界面
KUIWindow.OpenWindow(_sceneUserData);
}
}
enterSceneCallback?.Invoke();
}
///
///
///
///
private IEnumerator LoadCommon(int id)
{
if (id > 0 && sceneCommonAssets.Count == 0)
{
_progress = 0f;
AssetProxy.Instance.CreateReleasePool("scene_common");
var handle = AssetProxy.Instance.TryGetAssetsAsync("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");
}
///
///
///
///
private IEnumerator LoadScene(int id)
{
if (id > 0)
{
KUIWindow.OpenWindow(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(this);
yield return null;
LoadSceneAsync("stage_ride", this.OnEnterSceneCompleted);
}
}
#endregion
#region Async
///
///
///
private string _currentSceneName;
private bool _loading;
private float _progress;
#if USE_AddressableAssets
AsyncOperationHandle _sceneAOHandle;
#endif
///
///
///
///
///
public void LoadSceneAsync(string name, Action completed)
{
StartCoroutine(LoadSceneCoroutine(name, completed));
}
///
///
///
public void UnloadScene()
{
StartCoroutine(LoadSceneCoroutine(null, null));
}
///
///
///
///
///
///
private IEnumerator LoadSceneCoroutine(string sceneName, Action 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
}
}