【服务器08】之【游戏框架】之【加载主角】

2024-06-24 10:20

本文主要是介绍【服务器08】之【游戏框架】之【加载主角】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先简单了解一下帧率

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.

这篇关于【服务器08】之【游戏框架】之【加载主角】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1089877

相关文章

Apache Tomcat服务器版本号隐藏的几种方法

《ApacheTomcat服务器版本号隐藏的几种方法》本文主要介绍了ApacheTomcat服务器版本号隐藏的几种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需... 目录1. 隐藏HTTP响应头中的Server信息编辑 server.XML 文件2. 修China编程改错误

最好用的WPF加载动画功能

《最好用的WPF加载动画功能》当开发应用程序时,提供良好的用户体验(UX)是至关重要的,加载动画作为一种有效的沟通工具,它不仅能告知用户系统正在工作,还能够通过视觉上的吸引力来增强整体用户体验,本文给... 目录前言需求分析高级用法综合案例总结最后前言当开发应用程序时,提供良好的用户体验(UX)是至关重要

如何在一台服务器上使用docker运行kafka集群

《如何在一台服务器上使用docker运行kafka集群》文章详细介绍了如何在一台服务器上使用Docker运行Kafka集群,包括拉取镜像、创建网络、启动Kafka容器、检查运行状态、编写启动和关闭脚本... 目录1.拉取镜像2.创建集群之间通信的网络3.将zookeeper加入到网络中4.启动kafka集群

Python如何实现 HTTP echo 服务器

《Python如何实现HTTPecho服务器》本文介绍了如何使用Python实现一个简单的HTTPecho服务器,该服务器支持GET和POST请求,并返回JSON格式的响应,GET请求返回请求路... 一个用来做测试的简单的 HTTP echo 服务器。from http.server import HT

如何安装 Ubuntu 24.04 LTS 桌面版或服务器? Ubuntu安装指南

《如何安装Ubuntu24.04LTS桌面版或服务器?Ubuntu安装指南》对于我们程序员来说,有一个好用的操作系统、好的编程环境也是很重要,如何安装Ubuntu24.04LTS桌面... Ubuntu 24.04 LTS,代号 Noble NumBAT,于 2024 年 4 月 25 日正式发布,引入了众

如何提高Redis服务器的最大打开文件数限制

《如何提高Redis服务器的最大打开文件数限制》文章讨论了如何提高Redis服务器的最大打开文件数限制,以支持高并发服务,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录如何提高Redis服务器的最大打开文件数限制问题诊断解决步骤1. 修改系统级别的限制2. 为Redis进程特别设置限制

MyBatis框架实现一个简单的数据查询操作

《MyBatis框架实现一个简单的数据查询操作》本文介绍了MyBatis框架下进行数据查询操作的详细步骤,括创建实体类、编写SQL标签、配置Mapper、开启驼峰命名映射以及执行SQL语句等,感兴趣的... 基于在前面几章我们已经学习了对MyBATis进行环境配置,并利用SqlSessionFactory核

MyBatis延迟加载的处理方案

《MyBatis延迟加载的处理方案》MyBatis支持延迟加载(LazyLoading),允许在需要数据时才从数据库加载,而不是在查询结果第一次返回时就立即加载所有数据,延迟加载的核心思想是,将关联对... 目录MyBATis如何处理延迟加载?延迟加载的原理1. 开启延迟加载2. 延迟加载的配置2.1 使用

Android WebView的加载超时处理方案

《AndroidWebView的加载超时处理方案》在Android开发中,WebView是一个常用的组件,用于在应用中嵌入网页,然而,当网络状况不佳或页面加载过慢时,用户可能会遇到加载超时的问题,本... 目录引言一、WebView加载超时的原因二、加载超时处理方案1. 使用Handler和Timer进行超

Python开发围棋游戏的实例代码(实现全部功能)

《Python开发围棋游戏的实例代码(实现全部功能)》围棋是一种古老而复杂的策略棋类游戏,起源于中国,已有超过2500年的历史,本文介绍了如何用Python开发一个简单的围棋游戏,实例代码涵盖了游戏的... 目录1. 围棋游戏概述1.1 游戏规则1.2 游戏设计思路2. 环境准备3. 创建棋盘3.1 棋盘类