3D RPG Course | Core | Unity学习笔记(九)

这篇具有很好参考价值的文章主要介绍了3D RPG Course | Core | Unity学习笔记(九)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

(一)玩家数据保存

(二)制作主菜单

(三)制作NewGame场景转换

(四)制作场景渐入渐出

(五)玩家死亡返回Menu


(一)玩家数据保存

       创建新的脚本SaveManager专门负责保存数据。为了能够随时调用并保存数据,所以使用泛型单例与设置DontDestroyOnLoad。玩家数据的保存则使用JsonUtility+PlayerPrefs的形式存储,PlayerPrefs提供给玩家int,float,string三个类型进行储存与修改,以键值对的形式存储;而JsonUtility可以对ScriptableObject等类进行存储。存储时先将数据转为json格式,再使用PlayerPrefs进行存储,读取同理。

        保存的数据需要在转换场景时仍然保存,在SceneController的传送协程中,切换场景之前和之后分别进行Save和Load。(顺便把其他场景的UI补上)

        SaveManager:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SaveManager : Singleton<SaveManager>
{
    protected override void Awake()
    {
        base.Awake();
        DontDestroyOnLoad(this);//防止Manager被销毁
    }

    private void Update()
    {
        if(Input.GetKeyDown(KeyCode.S))
        {
            SavePlayerData();
        }
        if (Input.GetKeyDown(KeyCode.L))
        {
            LoadPlayerData();
        }
    }

    public void SavePlayerData()//存储玩家数据
    {
        Save(GameManager.Instance.playerStats.characterData, GameManager.Instance.playerStats.characterData.name);
    }

    public void LoadPlayerData()
    {
        Load(GameManager.Instance.playerStats.characterData, GameManager.Instance.playerStats.characterData.name);
    }

    public void Save(object data, string key)
    {
        var jsonData = JsonUtility.ToJson(data,true);//数据格式转换为json
        PlayerPrefs.SetString(key, jsonData);//构造键值对与存储
        PlayerPrefs.Save();
    }

    public void Load(object data, string key)
    {
        if(PlayerPrefs.HasKey(key))//找到key则读取
        {
            JsonUtility.FromJsonOverwrite(PlayerPrefs.GetString(key), data);
        }
    }
}

(二)制作主菜单

        首先进行主菜单场景的布置,注意当利用player等prefab进行布置时,最好解包并关闭一些组件。

        创建菜单Canvas,调整比例并添加配件。当UI字体模糊时,尝试提高字号的同时将Scale调小会使字体清晰。将Canvas的RenderMode调整为Camera,这样UI界面就在所设定的摄像机的视野中进行布局,再改成WorldSpace模式就可以以合适的初始位置来调整UI的空间视觉效果(自己的作业本来不想改,但是后面做转换效果更好所以改了。)。

        下面编写主菜单的脚本并挂载到主菜单Canvas上。主菜单的功能按钮在脚本中以事件的形式产生作用,可以采用button.onClick.AddListener(xxx)来为按钮事件添加xxx方法。新游戏和继续游戏都需要转换到对应场景并加载Player,这需要在SceneController中再写一个新的协程,在GameManager中完成获得场景入口的方法:

public Transform GetEntrance()
{
    foreach(var i in FindObjectsOfType<TransitionDestination>())
    {
        if(i.destinationTag== TransitionDestination.DestinationTag.Enter)
        {
            return i.transform;
        }
    }
    return null;
}

这样在协程中调用此方法来作为player生成的位置。完成场景加载和玩家生成后,保存数据并结束协程。协程在方法中调用,而方法与事件绑定。(泛型单例在重复时会删除到只剩一个,所以不用担心Manager重复)。传送方法:

    //给NewGame使用跳转到第一个场景
    public void TransitionToFirstScene()
    {
        StartCoroutine(LoadLevel("Level1"));
    }


    IEnumerator LoadLevel(string sceneName)
    {
        if(sceneName!="")//找到场景,跳转并生成player
        {
            yield return SceneManager.LoadSceneAsync(sceneName);
            yield return player = Instantiate(PlayerPrefab, GameManager.Instance.GetEntrance().position, GameManager.Instance.GetEntrance().rotation);
            //保存数据以便下次继续游戏
            SaveManager.Instance.SavePlayerData();

            yield break;
            
        }
    }

最后在按钮处调用即可。

        读档需要让玩家也能回到原本的场景,因此需要在Save同时保存所在场景到PlayerPrefs中,并在SceneController实现读取游戏的传送方法:

public void TransitionToLoadScene()
{
    StartCoroutine(LoadLevel(SaveManager.Instance.SceneName));
}

        玩家数据的读取则应当在player开始时获取,所以写在PlayerController的start中,且玩家注册到游戏中的步骤则应该调整到OnEnable中。可以在Manager的Update中判断按下Input.GetKeyDown(KeyCode.Escape),是则跳转回主界面,跳转本身的实现则需要像上面一样在SceneController中再写一次方法和协程:

        

   public void TransitionToMainScene()
{
    StartCoroutine(LoadMain());
}

    IEnumerator LoadMain()
   {
       yield return SceneManager.LoadSceneAsync("Main");
       yield break;
   }

 这样主菜单的基本功能就完成了,此时的存档会在按下对应按键(Update中设置)、开始与加载游戏以及跨场景传送时触发。

(三)制作NewGame场景转换

        单纯的卡顿不利于场景转换的表现,下面需要制作场景的转换效果。Timeline是一种针对多对象的动画制作功能,一般用于过场动画的制作,其实际操作类似于PR,将需要控制的物体拖入左侧可以创建track,然后通过录制关键帧来控制动画的播放。比如在相机的Transform position上右键添加Key,就可以在相机的track上添加一个关键帧,两个关键帧之间则会自动产生动画效果。录制希望添加效果的对象的track。对于可以使用Animation的对象,Timeline可以直接将动画拖到时间轴上来播放。对于播放动画时的位置偏移,可以选择Add override track,在一条附属轨道上录制正确的位置动画。

        制作的动画希望在点击New Game时播放,所以要取消director的Awake时播放,在MainMenuUI脚本中控制director,director的stopped是动画结束时的事件,所以可以将NewGame注册到这一事件中来,修改一下参数即可。

        对于动画播放中仍然可以用键盘控制按钮的问题,可以在Timeline中创建EventSystem的Activation track,删掉active段。

public void transitiontoloadgame() { startcoroutine(loadlevel(savemanager.in,学习,笔记

(四)制作场景渐入渐出

        使用Canvas Group制作SceneFader效果。创建Canvas并令其image覆盖屏幕,然后添加组件Canvas Group,通过调整其Alpha值来实现渐入渐出的视觉效果,使用脚本SceneFader 控制。

        由于透明度的调整与场景加载同步进行,所以采用协程的形式实现,协程的嵌套则可以在yield return中进行:

        

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SceneFader : MonoBehaviour
{
    CanvasGroup canvasGroup;
    public float fadeInDuration;//渐入时间
    public float fadeoutDuration;//渐出时间

    private void Awake()
    {
        canvasGroup = GetComponent<CanvasGroup>();
        DontDestroyOnLoad(this);
    }

    public IEnumerator FadeOutToIn()//完整渐入渐出
    {
        yield return FadeOut(fadeoutDuration);
        yield return FadeIn(fadeInDuration);
    }

    public IEnumerator FadeOut(float time)//alpha 0-1,渐出
    {
        while (canvasGroup.alpha < 1)
        {
            canvasGroup.alpha += Time.deltaTime / time;//???
            yield return null;
        }
    }
    public IEnumerator FadeIn(float time)//alpha 1-0,渐入
    {
        while (canvasGroup.alpha !=0)
        {
            canvasGroup.alpha -= Time.deltaTime / time;//???
            yield return null;
        }
    }

}

剩下只需要在转换场景前后调用协程即可。

(五)玩家死亡返回Menu

        玩家死亡时GameManager发出广播,可让SceneController也监听并执行返回菜单操作。加入监听操作见敌人制作部分(继承与注册)。收到广播方法后启动返回主菜单协程即可。

        为了防止GameManager持续广播导致SceneController执行过多游戏崩溃,要在SceneController设置bool flag进行判断,并在每次新游戏开始时重置flag保证其功能正常

(六)打包与运行

        将初步完成的项目打包,从而能够脱离unity编辑器来运行。

        打包前需要调整Build Settings,需要把涉及到的场景都添加上,并设置运行的平台环境。名字和图标等设置则在左下角的PlayerSettings中。需要多平台支持的话,可以事先在UnityHub中为编辑器添加模块,就可以在PlayerSettings中设置了。更改打包方式为IL2CPP可以比Mono减少游戏大小,且更难反编译。

        打包前要在Edit菜单中清除所有PlayerPrefs,防止将测试存档带入打包文件。文章来源地址https://www.toymoban.com/news/detail-773055.html

到了这里,关于3D RPG Course | Core | Unity学习笔记(九)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity 3D RPG游戏的设计与实现

    public class PlayerInput : MonoBehaviour {     public float horizontalInput;     public float verticalInput;    public bool mouseDown;             // Update is called once per frame     void Update()     { ///在游戏运行且鼠标当前未被按下的情况下,检测鼠标左键是否被用户按下,并记录这一交互状态。    

    2024年03月14日
    浏览(55)
  • 从public static void main(String[] args)看如何构造数据

    java语言中public static void main(String[] args)里面的ages有什么作用? 在Java语言中, public static void main(String[] args) 是一个特殊的方法,它是Java程序的入口点。当你运行一个Java程序时,程序会从这个方法开始执行。这个方法的参数 String[] args 是一个字符串数组,用于传递命令行参数

    2024年02月12日
    浏览(90)
  • 菜鸟学Java public static void main(String[] args) 是什么意思?

    这是一个经典的 Java 程序,它使用了面向对象的编程风格: 第一行代码: 这行代码定义了一个名为 HelloWorld 的公共类( public class ),该类是程序的入口点。 Java 程序中的每个类都必须以一个公共类来定义。文件名必须与公共类的名称相同,并以 .java 作为文件扩展名。 注:

    2024年02月09日
    浏览(45)
  • 无法解析的外部符号 “public: virtual void * __cdecl MyTcpsocket::qt_metaca

    问题:严重性    代码    说明    项目    文件    行    禁止显示状态 错误    LNK2001    无法解析的外部符号 \\\"public: virtual void * __cdecl MyTcpsocket::qt_metacast(char const *)\\\" (?qt_metacast@MyTcpsocket@@UEAAPEAXPEBD@Z)    SmartTool    D:2023SmartToolSmartToolMyTcpsocket.obj    1     解决

    2024年02月01日
    浏览(36)
  • Unity2D RPG开发笔记 P1 - Unity界面基础操作和知识

    按下 QWERTY 可以选择不同的工具进行 旋转、定位、缩放 按下 Ctrl + D 可以复制物体 16:9 为最常见的分辨率 Transform 组件 物体在空间中的位置、缩放、旋转 点击这里可以进行 reset 操作,位置将会被重置 不知道算不算冷知识的冷知识:鼠标拖动这里可以移动该数值 Sprite Renderer

    2024年02月13日
    浏览(46)
  • 计算机网络-甘晴void学习笔记

    计科210X 甘晴void 202108010XXX 【注明】这一部分是A橙学长划的重点 第一章:分组交换和电路交换的比较 应用层:要看懂HTTP报文,知道cookie,持续连接非持续连接区别,邮件工作的过程,DNS 原理,后面的没空可以不看了 运输层: UDP和TCP比较,可靠数据传输的rdt不需要知道那么

    2024年01月20日
    浏览(41)
  • Unity 3D 学习笔记(1)

    Unity 3D简介 :Unity 3D是虚拟现实行业中使用率较高的一款开发引擎,由Unity Technology公司开发。通过Unity,开发人员可以制作三维视频游戏、建筑可视化和实时三维动画等内容。 引擎的概念 :引擎为设计者提供了编写程序所需的工具,而并非从零开始对项目进行开发。这样可以

    2024年02月02日
    浏览(34)
  • Unity3D学习笔记——物理引擎

    1简介 刚体可以为游戏对象赋予物理特性,是游戏对象在物理系统的控制下接受推力和扭力,从而实现现实世界的物理学现象。 2属性 1简介 碰撞器是物理组件的一类,他与刚体一起促使碰撞发生 碰撞体是简单形状,如方块、球形或者胶囊形,在 Unity 3D 中每当一个 GameObjects

    2023年04月12日
    浏览(49)
  • sheng的学习笔记-【中文】【吴恩达课后测验】Course 1 - 神经网络和深度学习 - 第一周测验

    目录:目录 1.“人工智能是新电力” 这个比喻指的是什么? A. 【  】人工智能为我们的家庭和办公室的个人设备供电,类似于电力。 B. 【  】通过“智能电网”,人工智能正在传递新一波的电力。 C. 【  】人工智能在计算机上运行,因此由电力驱动,但它让计算机做以前

    2024年02月07日
    浏览(36)
  • Unity3D学习笔记8——GPU实例化(3)

    在前两篇文章《Unity3D学习笔记6——GPU实例化(1)》《Unity3D学习笔记6——GPU实例化(2)》分别介绍了通过简单的顶点着色器+片元着色器,以及通过表面着色器实现GPU实例化的过程。而在Unity的官方文档Creating shaders that support GPU instancing里,也提供了一个GPU实例化的案例,这里就详

    2023年04月22日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包