NoiseFloor 发表于 2023-2-15 21:52

unity实战项目[命运之手].1星难度.含全部源码

【原创不易,若喜欢请收藏点赞 (ˊωˋ*) 】
本文将带你做一个完整的文字游戏小项目,只涉及极少的新知识点.大多数是之前已经学到过的内容.学以致用嘛,如果已经学到的却用不上,那学来干嘛呢!
所以,我们不仅要用,还要让它们挑大梁。切记!思路,思路很重要,我们是做游戏,游戏的本质是什么?这点也许千人千面,各有喜好,但终归来说离不开有趣(想象力,创意,好玩,脑洞等等,你怎么理解都可以),说个题外话,曾经做过一个头脑游戏,就是如果只给你一个圆,你能做出什么样的游戏来?如果再给你一个方,你又能做出什么来?再退回几十年前,那时候只有DOS,只能玩玩批处理,那么批处理那种有限程度又能玩出什么花来呢?
掌握知识的多寡不应成为限制,想象力才是。
即使是之前已经学到过的,这里我也会再次提到,但不会细说了,主要就是尽量确保项目案例教学的完整性.如果有不明白的,可以翻看之前的教学文章哦~
那么,下面就开始了!
<hr/>【项目简述】
我们先建一个基础项目,或者说核心玩法,之后再逐步扩展更多周边玩法。
核心玩法很简单,我们在一个地下迷宫中,初始生命3,初始宝物0,每走一步,会产生随机事件,可能是生命+1,也可能生命-1,也可能宝物+1。生命为0游戏结束。具体数值可以在代码中自行调整。
因为以复习巩固之前教程的知识点为主,所以本章进度会比较快。
【制作流程】
首先,请新建项目.名字自己随便定了,虽然要命名规范统一,但这也不是本章的重点。



做好准备工作,搭建画板,创建一个前进按钮. 并且画板和主摄像机做好关联,设定屏幕尺寸分辨率等,这些在前面教程已经教过,就不细说了,和本章内容无关的暂不纠结,对照操作即可.



创建的按钮。按钮显示自己随意填,我这里是前进



我们再创建一个文本框Text,用来显示当前的角色属性。因为开始游戏时会对text进行初始化,所以开发状态下怎么写其实都无所谓。
这里不仅会显示属性,还要显示一个对应属性的历史最好成绩。



由上图我们可以得知,我们至少需要记录6个变量,分别是当前生命、历史最好生命、持有宝物、历史最好宝物、前进步数、历史最好步数。
现在我们保存一下scene,并且创建一个C#脚本文件,参照下图。



大家没有忘记吧。右键菜单如下图。



接下来我们在脚本里声明之前创建的text文本框,在声明之前,我们需要先using一个,否则会声明失败的,前面教程都有说,这里不纠结了。看下图。



新增一个空对象, 见下图红框,然后把RKmain脚本拖进去,作为一个承载脚本的容器.然后将text_info拖进去完成关联.前面教程有详解,这里不复述了.



接下来,我们要创建六个变量,分别是life、best_life、gift、best_gift、step、best_step;能看懂吧,分别用来记录生命、宝物、步数。以及对应的best最好成绩。其中life可以赋一个初值3。见下图。



然后我们声明一个方法,用来在text里显示并更新属性。具体实现上,我们仍然用最直观最简单,你绝对能看懂,看不懂我退呼的方法来实现【巨型滑稽脸】。


好咯,到现在为止,如果你操作没有错误,可以点击运行看看.应该是类似下图这个样子(具体差异只会是你的UI控件摆放位置不同)


然后,我们发现游戏胜负的规则清晰了,但是如果游戏结束之后,要怎么重新开始呢?
所以我们还要加一个重新开始的按钮.
我们讲一下策划思路,只有在生命>0时才能前进,如果生命<=0则游戏结束,此时只有点击重新开始按钮将生命值重置为初始的3.然后就可以继续游戏了.
大概就是下图这些元素.你可以搞得更漂亮,比如专门的按钮,背景图片,等等


策划思路如下图实现,根据随机值来判定玩家的命运,



然后将代码中的方法与按钮操作关联起来.如下图





现在,咱们运行游戏,不断点击前进,不断收获未知的命运,直到生命终结...如下图.



然后,我们重新开始第二局.这一局就厉害了..运气爆棚..这时候,也许你会怀疑,是不是数值判定上有问题,太简单了也不行啊..你可以考虑调整下数值.比如将减生命的0~30范围调整为0~50,这样难度就会大幅提升了,诸如此类.



然后,我们重新开始的时候..发现...
WHAT!我的历史最好呢?难过,痛苦,悔恨,遗憾...好不容易打到这么好的成绩,居然没有记录...是的,接下来我们还要实现存取档!


关于存取档,这个就简单了,在前面的教程已经有详细教学了,这里,我们直接上代码!
需要补充说明的是,这里的存取档有两种策划方案,只存档历史最好成绩或者全部存档,前者意味着不保存当前游戏进度,在重启游戏后之前的游戏进度不会保留会从新游戏.如果全部属性存档,重启游戏依然会保存之前的游戏状态.我们这里就全部存档吧.
存档使用也有很多方案,你可以随时存档,也可以在退出时存档,也可以做一个按钮让玩家手动保存.我们这里简单一点,就随时存档吧,把存档方法在点击前进按钮后立即进行调用.
读档的使用,我们就在start中调用吧,在游戏启动时立即读取.
上面是补充说明,下面才是代码..


关于存取档,大家注意一个逻辑原则,在显示属性之前读档.在更新属性之后存档.
接下来,我们如何实现历史最好成绩呢?我们只需要在前进按钮的方法中增加判断,以生命为例,如果当前生命比历史最佳要高,则历史最佳 = 当前生命. 这样就完成了新旧历史属性的更替.
代码见下图


运行游戏,一切正常


那么,命运之手的最小核心版本已经全部完成啦!
最后贴上全部代码!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Rk_main : MonoBehaviour {
        public Text Text_info;
    int life=3,best_life,gift,best_gift,step,best_step;
        // Use this for initialization
        void Start () {
      Load_F(); //进入游戏立即读档
      info_F();//如果希望进入游戏时就显示并更新玩家属性,就在start里调用
        }
        //属性的显示和刷新
    void info_F()
    {
                Text_info.text = "当前生命 "+life+"\n历史最佳 "+best_life+
            "\n\n持有宝物 "+gift+"\n历史最多 "+best_gift+
            "\n\n前进步数 "+step+"\n历史最强 "+best_step;
    }

    //前进按钮的执行逻辑,只有在生命>0时才可以前进
    public void Button_go_F()
    {
      if (life>0)
      {
            step++;//每次前进都会递增步数.
            if (step > best_step) { best_step = step; }
            //如果当前步数超过历史最好,则更新历史最好
            int i = Random.Range(0, 100);//从0~99之间随机取值
            if (i < 30)
            {
                life--; print(i+";倒霉哦,你踩到迷宫中的陷阱,生命-1");
                //i作为调试信息显示,下同
            }else if (i <60)
            {
                life++; print(i+";胆大运气好,你捡了一颗蘑菇吃,生命+1");
                if (life > best_life) { best_life = life; }
                //如果当前生命超过历史最好,则更新历史最好
            }
            else
            {
                gift++; print(i+";激运!发现宝物啦");
                if (gift > best_gift) { best_gift = gift; }
                //如果当前宝物超过历史最好,则更新历史最好
            }
            info_F();//每一次前进都会刷新属性显示.
            Save_F();//每一次前进都会存档.
      }
      else { print("生命为0,游戏已结束,大侠请重新开始吧"); }
    }

    //重新游戏的执行逻辑,主要是将当前生命,持有宝物,前进步数重新初始化
    public void Button_restart_F()
    {
      life = 3;gift = 0;step = 0;
      info_F();
    }

    ///----------------------SAVE & LOAD--------------------------///
    void Save_F()
    {   
      PlayerPrefs.SetInt("life", life); PlayerPrefs.SetInt("best_life", best_life);
      PlayerPrefs.SetInt("gift", gift); PlayerPrefs.SetInt("best_gift", best_gift);
      PlayerPrefs.SetInt("step", step); PlayerPrefs.SetInt("best_step", best_step);
    }
    void Load_F()
    {   
      life = PlayerPrefs.GetInt("life"); best_life = PlayerPrefs.GetInt("best_life");
      gift = PlayerPrefs.GetInt("gift"); best_gift = PlayerPrefs.GetInt("best_gift");
      step = PlayerPrefs.GetInt("step"); best_step = PlayerPrefs.GetInt("best_step");
    }

}
希望能玩到你做的游戏嗷!
欢迎转载,转载请注明出处.
如果大家觉得本文对你还有些帮助,请将此文分享给更多需要的盆友,山宗也会继续做一些更深入的公益教学文档!谢谢捧场辣撸大家!永远爱你们!
<hr/>

kirin77 发表于 2023-2-15 21:56

设定屏幕尺寸分辨率等,这些在前面教程已经教过,就不细说了---------前面的教程没讲过屏幕尺寸分辨率还有镜头什么的呀,是我没找到吗?

acecase 发表于 2023-2-15 22:02

如果没有可能在其它教程里。
这些是旁枝末节,暂时不用投精力在上面。可以初步理解为不同平台/和机型有不同的分辨率设置需求。但这也不是强需求,通常都会简单取一个中间值,做一个多机型适配。
目前是默认pc平台的编辑器环境下,分辨率设置可以随意,也可以在案例中自行改变值查看会带来什么不同的效果。
如果实在感兴趣可以多多大胆尝试。

xiangtingsl 发表于 2023-2-15 22:06

总是显示void infoF()这里文本赋值的错误:NullReferenceException。Text_info只能显示初始值,不能及时更新,确定每一步都有写info_F();大神有空的话解答一下,或者有没有其他解决方法。

redhat9i 发表于 2023-2-15 22:12

而且,点击重新开始也没有给几个值赋值,在console里显示的还是0

zifa2003293 发表于 2023-2-15 22:20

把Text_info.text=""这个赋值换成print,就发现没有错误了。大神有空分析一下什么原因,谢谢。

pc8888888 发表于 2023-2-15 22:21

后来再把葡萄吃了一遍就没问题了,谢谢大神。

pc8888888 发表于 2023-2-15 22:28

大佬好棒!
页: [1]
查看完整版本: unity实战项目[命运之手].1星难度.含全部源码