首先简单了解一下帧率
FixedUpdate( ) > Update( ) > LateUpdate( )
首先FixedUpdate的设置值 默认一秒运行50次
虽然默认是0.02秒,但FiexedUpdate并不是真的0.02秒调用一次,因为在脚本的生命周期内,FixedUpdate有一个小循环,这个循环也是通过物理时间累计看是不是大于0.02了,然后调用一次。有多数物体都进行物理更新时,FixedUpdate的调用也会慢下来。
我们继续编写代码:
首先添加两个函数
接下来我们写一个管理器代码,用来增添删除 这个游戏中运行中的Object
创建一个代码WorldManager.cs 用来在这个脚本中创建 树、房子、人物等等对象
编写代码:
重写以下代码框架:
运行测试加载场景
下一步开始加载主角
在Unity中新建一个目录
区别于创建Resources文件夹 ,Resources修改资源后又需打包才能运行,
而Res目录存放所有资源,我们可以单独打一个包,单独更新资源
拖拽资源
编写资源管理代码ResManager.cs
增添函数
编写WorldManager.cs脚本
修改代码:
using UnityEngine;
public class WorldManager : BaseManager<WorldManager>{
//世界(场景)状态机
enum LoadState {
//初始化状态
Init,
//加载场景状态
LoadScene,
//更新状态
Update,
//等待状态
Wait,
}
//需要变量保存一个当前状态
LoadState mState;
string mLoadSceneName;
//初始化
public void Init() {
EnterState(LoadState.Init);
}
//世界更新
public void Update() {
if (mState == LoadState.Init) {
}
//"rpgpp_lt_scene_1.0"
if (mState == LoadState.LoadScene) {
EnterState(LoadState.Wait);
ResManager.Instance.LoadSceneAsync(mLoadSceneName, () =>
{
//等待场景加载完成后 加载玩家到场景中
LoadMainPlayer();
//EnterState(LoadState.Update);
});
}
}
//世界管理中的加载场景
public void LoadScene(string name) {
mLoadSceneName = name;
EnterState(LoadState.LoadScene);
}
//改变当前的状态机
void EnterState(LoadState state) {
mState = state;
}
//加载主角
void LoadMainPlayer() {
//ResManager.Instance.InstantiateGameObject("Assets/Res/Role/Peasant Nolant Blue(Free Version)");
//- GameObject loadedObject = Resources.Load("Role/Peasant Nolant Blue(Free Version)") as GameObject;
// GameObject instance = GameObject.Instantiate(loadedObject, new Vector3(0, 0, 0), Quaternion.identity);
GameObject mainPlayer = ResManager.Instance.InstantiateGameObject("Assets/Res/Role/Peasant Nolant Blue(Free Version).prefab");
if (mainPlayer == null)
{
Debug.LogError("Load Main Player Error");
}
mainPlayer.transform.position = new Vector3(63.0f, 22.23f, 43.0f);
//mainPlayer.GetComponent<UnityEngine.Animator>().Play("metarig|Idle");
mainPlayer.GetComponent<UnityEngine.Animator>().Play("metarig|Walk");
}
}
修改ResManager.cs脚本
using UnityEngine;
using UnityEngine.SceneManagement;
//资源管理类 单例模式
public class ResManager : BaseManager<ResManager>{
//枚举状态机
enum LoadState {
//空闲状态
Idle,
//加载状态
LoadScene,
//进度条状态
TickLoadSceneProgress,
}
LoadState mCurrentLoadState = LoadState.Idle;
string mCurrentSceneName = null;
OnLoadCallBack SceneLoadedCallback;
public delegate void OnLoadCallBack();
AsyncOperation mCurrentSceneAsyncOperation;
public void Update() {
switch (mCurrentLoadState) {
case LoadState.Idle:
break;
case LoadState.LoadScene:
//通过回调的方式告诉我们 场景加载完成
//场景切换之后才执行回调函数
SceneManager.sceneLoaded += SceneManager_sceneLoaded;
//异步加载核心语句******
mCurrentSceneAsyncOperation = SceneManager.LoadSceneAsync(mCurrentSceneName, LoadSceneMode.Single);
// ******
if (mCurrentSceneAsyncOperation == null){
Debug.LogError("Failed to load scene,mCurrentSceneAsynvOperation is null");
mCurrentLoadState = LoadState.Idle;
return;
}
mCurrentLoadState = LoadState.TickLoadSceneProgress;
break;
//加载百分比此次没有调回至应用层
case LoadState.TickLoadSceneProgress:
Debug.Log("Loading scene " + mCurrentSceneName + " progress " + mCurrentSceneAsyncOperation.progress);
break;
}
}
//异步加载场景
public void LoadSceneAsync(string name, OnLoadCallBack callback) {
//判断当前是否正在加载场景
if (mCurrentLoadState != LoadState.Idle) {
Debug.LogError("On Scene is Loading, scene name " + name);
return;
}
mCurrentLoadState = LoadState.LoadScene;
mCurrentSceneName = name;
SceneLoadedCallback = callback;
}
//已经淘汰了-本项目没有使用
public void LoadScene(string name) {
//同步加载场景
SceneManager.LoadScene(name);
}
// unity 回调给我们的加载完成
public void SceneManager_sceneLoaded(Scene scene, LoadSceneMode loadSceneMode) {
//删掉委托
SceneManager.sceneLoaded -= SceneManager_sceneLoaded;
//证明场景加载完成
mCurrentLoadState = LoadState.Idle;
if (SceneLoadedCallback != null) {
SceneLoadedCallback();
}
}
//加载资源
Object LoadResource(string resPath)
{
#if UNITY_EDITOR
//只能在unity 的 editor 下载资源的加载方式 只是从磁盘加载到内存中
Object obj = UnityEditor.AssetDatabase.LoadAssetAtPath<Object>(resPath);
return obj;
#else
//
其它的加载方式
#endif
}
//实例化显示一个资源-----包装LoadResource()加载资源函数 包装上面函数
public GameObject InstantiateGameObject(string resPath)
{
//强转成GameObject
GameObject obj = LoadResource(resPath) as GameObject;
if (obj != null)
{
//实例化资源
GameObject go = GameObject.Instantiate(obj);
if (go == null)
{
Debug.LogError("game instantiate faild " + resPath);
return null;
}
//激活资源
go.SetActive(true);
return go;
}
else
return null;
}
}
修改BaseManager.cs脚本
修改GameStart.cs脚本
using System;
using UnityEngine;
public class GameStart : MonoBehaviour{
//在游戏运行期间始终保留的Object-切换场景时也不让删除
GameObject mGo;
void Start(){
Debug.Log("Game Start");
mGo = gameObject;
//切换场景加载时不销毁
DontDestroyOnLoad(mGo);
//逻辑写到try里面
try{
//场景世界初始化
WorldManager.Instance.Init();
}
//异常将它catch掉
catch (Exception e) {
Debug.LogException(e);
}
WorldManager.Instance.LoadScene("rpgpp_lt_scene_1.0");
}
//以固定频率更新
void FixedUpdate(){
try
{
}
catch (Exception e)
{
Debug.LogException(e);
}
}
//游戏循环
void Update(){
try{
ResManager.Instance.Update();
WorldManager.Instance.Update();
}
catch (Exception e) {
Debug.LogException(e);
}
}
//在Update() 后更新
private void LateUpdate(){
try{
}
catch (Exception e){
Debug.LogException(e);
}
}
//游戏退出时调用
//作用是 退出游戏是销毁资源
private void OnApplicationQuit(){
Debug.Log("Game Quit");
try{
}
catch (Exception e){
Debug.LogException(e);
}
}
}
点击运行
人物运行成功
End.