首页 > 作文

Unity实战之FlyPin(见缝插针)小游戏的实现

更新时间:2023-04-04 11:11:39 阅读: 评论:0

目录
一、简单介绍二、flypin (见缝插针)游戏内容与操作三、游戏代码框架四、知识点五、游戏效果预览六、实现步骤七、工程源码地址八、延伸扩展

一、简单介绍

unity 游戏实例开发集合,使用简单易懂的方式,讲解常见游戏的开发实现过程,方便后期类似游戏开发的借鉴和复用。

本节介绍,flypin (见缝插针) 休闲小游戏快速实现的方法,希望能帮到你,若有不对,请留言。

二、flypin (见缝插针)游戏内容与操作

1、游戏开始,针 pin 自动准备好,

2、鼠标点击左键发射 pin,飞向目标,同时自动准备下一根针 pin,并增加分数

3、针 pin 插入目标后,会随之一起转动

4、当两个针 pin 发生碰撞,则游戏结束

5、游戏结束动画完成后,自动重新开始游戏

三、游戏代码框架

四、知识点

1、monobehaviour 生命周期函数:awake,start,update,ongui

2、input 按键的监控

3、gameobject.instantiate 物体的生成,gameobject.destroy 物体的销毁

4、camera.orthographicsize 正交相机视口大小修改,camera.backgroundcolor 相机 solidcolor 背景色的修改

5、rigidbody2d 取消重力效果,添加 collider ,进行 trigger 碰撞检测

6、guistyle gui样式,gui.label 添加文字的功能使用

7、vector3.lerp 位移向量插值使用,vector3.distance 位置距离函数的使用

8、mathf.lerp ,color.lerp 数值和颜色插值计算的使用

9、transform.rotate 旋转使用

10、ienumerator 协程 , startcoroutine 开始协程 和stopallcoroutines 停止所有协程的使用

11、simplemessagecenter 简单的消息中心使用

12、action<int> onchangevalue 属性变化中委托的使用

13、resources.load<gameobject>() 代码加载预制体的使用

14、ontriggerenter2d 2d 碰撞检测的使用

15、 scenemanager.loadscene 加载,和 scenemanager.getactivescene() 当前场景的获取

16、等等

五、游戏效果预览

六、实现步骤

这是一个 2d 游戏,主要用到 spriterenderer 、2d collider,2d rigidbody,以及 textmesh 等资源组件,所有资源都是unity自带,没有导入其他外部贴图模型资源。

1、打开 unity,创建工程

2、构建场景,添加 pin 初始生成,准备和飞向的地方,以及旋转的目标圆,和显示分数的 3dtext

3、scoretext,创建是 3d object – 3d text,其中 根据 textmesh的字体大小,根据 character size 和 font size 共同控制

4、如果 textmesh 看起来很模糊,可以改小 character size ,放大 font size ,如图

5、targetcircle 是 spriterenderer ,根据需要设置颜色,sprite 是 unity 自带的 knob

说明,同时 targetcircle 也是 pin 飞向的目标体

6、pinspawnpos 、pinreadypos 是 针 pin 生成的初始位置,和 准备好位置,pinspawnpos 、pinreadypos 下的 cube 是便于观察位置设定的,确定好位置后,可以删掉或者隐藏 cube

7、注意 scoretext 、targetcircle、pinspawnpos、pinreadypos,position.z 都是 0,为了保证实在同一个平面上,满足2d 游戏要求

8、main camera,设置如图,clearflags 为 solid color ,background 颜色根据需要设定,projection 为 orthographic 正交(2d游戏设置相机),size 为 5 ,你可以根据自己需要设置

9、最后,效果如图

10、pin 预制体,包含pinhead 和 pinbody

11、pin 的 pinhead ,spriterenderer 的 sprite 自带的 knob, 颜色根据自己需要设定,添加 circlecollider2d 碰撞体,并且勾选 istrigger(避免发生碰撞,产生碰撞效果,不勾选则会有碰撞的物理效果),circlecollider2d的大小可以根据实际情况调整(一般unity会自动根据renderer 大小设置默认大小);添加 rigidbody2d (发生碰撞的必需条件之一),并且bodytype设置为 kinematic 可以不受重力下坠(或者 bodytype 为 dynamic ,把 gravity scale 设置 为 0 ,也可以不受重力影响)

12、pin 中的 pinbody,spriterenderer 中 sprite 自带的 background ,颜色自选,order in layer 默认是 0 ,设置为 -1,是为针插入 targetcircle 效果,scale 设置为 (1,15,1),是为了细长如针的效果

13、至于 pin ,放置在 resources 文件夹下的prefabs 文件夹,是为了使用 unity 中 resources.load 代码加载预制体,不需要手动挂载预制体,而 resources.load 加载就要求把预制体放在 resources 文件夹下

14、pinhead 类 监听两个针是否插在靠近位置相撞,相撞则发送游戏结束消息

15、pinhead中的 ontriggerenter2d(collider2d collision) 见监听碰撞进入,碰撞则发送游戏借宿消息

       /// <summary>       /// 监听两个针是否插在靠近位置相撞       /// 相撞则发送游戏结束消息       /// </summary>       /// <param name="collision"></param>        private void ontriggerenter2d(collider2d collision)        {            // 两个 pinhead 是否碰撞            if (collision.name.equals(conststr.pin_head_name))            {                // 相撞则发送游戏结束消息                simplemessagecenter.instance.ndmsg(msgtype.gameover);            }        }

16、pin 类,管理 针 pin 的状态和运动

17、pin 类,init 初始化函数,得到相关位置和 pinhead 脚本的挂载到 pin 的 pinhead 物体上

参数说明:

        // pin 准备好的位置        private vector3 m_pinreadypos;        // pin 飞行的目标位置        private vector3 m_pinflytargetpos;        // pin 插入目标位置的距离间隔        private float m_pinflytargetposdistance;        // pin 的移动速度        private float m_pinmovespeed;        // pin 飞到目标位置的 transfrorm        private transform m_pintargetparenttrans;        // pinhead        private pinhead m_pinhead;
/// <summary>/// 初始化函数,得到相关位置和 pinhead/// </summary>/// <param name="pinsmanager"></param>/// <param name="pinreadypos"></param>/// <param name="flytargetpos"></param>/// <param name="flytargetposdistance"></param>/// <param na学生学籍me="pinmovespeed"></param>/// <param name="pintargetparenttrans"></param>public void init(pinsmanager pinsmanager,  vector3 pinreadypos, vector3 flytargetpos, float flytargetposdistance, float pinmovespeed, transform pintargetparenttrans) {m_pinsmanager = pinsmanager;m_pinreadypos = pinreadypos;m_pinflytargetpos = flytargetpos;m_pinflytargetposdistance = flytargetposdistance;m_pinmovespeed = pinmovespeed;m_pintargetparenttrans = pintargetparenttrans;// pinhead 子物体添加pinhead脚本m_pinhead = transform.find(conststr.pin_head_name).gameobject.addcomponent<pinhead>() ;// 设置状态为准备状态m_curpinstate = pinstate.readying;}

18、pin 类,updatepinstate(),pin 的状态监听

/// <summary>/// 状态监听/// </summary>        void updatepinstate() {            switch (curpinstate)            {                ca pinstate.idle:                    break;                ca pinstate.readying:readying(); break;ca pinstate.readyok:m_pinsmanager.curpin = this;break;ca pinstate.fly:fly();m_pinsmanager.curpin = null; break;                default:                    break;            }        }

19、pin 类,readying() 正在准备的状态函数,fly() 飞行目标位置状态,包含 pin真正的运动(vector3.lerp),和满足条件(vector3.distance)对应的状态切换(注意:把 pin 实体至于 targetcircle 即可以 使 pin 随 targetcircle 一起转动 (this.transform.tparent(m_pintargetparenttrans);))

/// <summary>/// 正在准备的状态函数/// </summary>void readying() { // 移动到准备位置transform.position = vector3.lerp(transform.position, m_pinreadypos, time.deltatime * m_pinmovespeed);// 判断是否到达准备位置            if (vector3.distance(transform.position, m_pinreadypos)<=0.1f)            {transform.position = m_pinreadypos;// 到达后切换状态curpinstate = pinstate.readyok;}}  /// <summary>/// 飞行目标位置状态/// </summary>void fly(){// 移动到目标位置transform.position = vector3.lerp(transform.position, m_pinflytargetpos, time.deltatime * m_pinmovespeed);if (vector3.distance(transform.position, m_pinflytargetpos) <= m_pinflytargetposdistance){// 到达后切换状态,并且置于 飞到的目标下,使之随目标一起转动curpinstate = pinstate.idle;this.transform.tparent(m_pintargetparenttrans);}}

20、pinsmanager pins 管理类,主要管理 pin 的生成和 发射 fly

21、pinsmanager pins 管理类,构造函数 pinsmanager(),resources.load 获取预制体 pin 预制体,和参数赋值

参数说明:

        // pin 预制体        private gameobject m_pinprefab;        // pin 生成位置        private vector3 m_pinspawnpos;        // pin 准备位置        private vector3 m_pinreadypos;        // pin 飞向目标位置        private vector3 m_pinflytargetpos;        // pin 飞向目标插入间距        private float m_pinflytargetposdistance;        // pin 移动速度        private float m_pinmovespeed;        // pin 飞向目标实体        private transform m_pintargetparenttrans;
/// <summary>/// 构造函数/// </summary>/// <param name="pinspawnpos"></param>/// <param name="pinreadypos"></param>/// <param name="flytargetpos"></para酶的作用机理m>/// <param name="flytargetposdistance"></param>/// <param name="pinmovespeed"></param>/// <param name="pintargetparenttrans"></param>public pinsmanager(vector3 pinspawnpos, vector3 pinreadypos,vector3 flytargetpos,float flytargetposdistance, float pinmovespeed,transform pintargetparenttrans) { // 获取预制体m_pinprefab = resources.load<gameobject>(conststr.resources_prefabs_pin_path); // 参数赋值m_pinspawnpos = pinspawnpos;m_pinreadypos = pinreadypos;m_pinflytargetpos = flytargetpos;m_pinflytargetposdistance = flytargetposdistance;m_pinmovespeed = pinmovespeed;m_pintargetparenttrans = pintargetparenttrans;}

22、pinsmanager pins 管理类,spawnpin() 根据条件 生成准备的 pin

/// <summary>/// 生成准备的 pin/// </summary>public void spawnpin() { // 生成准备的 pinif (m_pinprefab!=null && m_readypin == null)            {gameobject pingo = gameobject.instantiate(m_pinprefab);// 设置生成位置pingo.transform.position = m_pinspawn小学语文修改病句pos;// 添加 pin 脚本m_readypin = pingo.addcomponent<pin>();// pin 脚本 初始化m_readypin.init(this,m_pinreadypos,m_pinflytargetpos,m_pinflytargetposdistance,m_pinmovespeed,m_pintargetparenttrans); // 添加到集合中m_pinslist.add(pingo); }}

23、pinsmanager pins 管理类,flypin() 根据条件 让当前 pin 飞向目标位置,返回是否有可飞行的 pin,有则 true,destroyallpins() 销毁清空 pins 集合

/// <summary>/// 让当前 pin 飞向目标位置/// 返回是否有可飞行的 pin /// </summary>/// <returns>true : 有可飞行 pin </returns>public bool flypin() {            if (curpin!=null)            {m_readypin = null; if (curpin.curpinstate==pinstate.readyok)                {curpin.curpinstate = pinstate.fly; }return true;} return fal;} /// <summary>/// 销毁清空 pins 集合/// </summary>public void destroyallpins() {            for (int i=m_pinslist.count-1; i >= 0 ; i--)            {gameobject.destroy(m_pinslist[i]);            } m_pinslist.clear();}

24、targetcirclemanager pin 飞向目标圆管理类

25、targetcirclemanager pin 飞向目标圆管理,targetcirclemanager()构造函数 获取设置 旋转的实体和旋转速度

参数说明:

        // 实体transform        transform m_targetcircletrans;        // 转动速度        float m_speed;        // 是否开始转动        bool m_isrotated = fal;
/// <summary>/// 构造函数/// </summary>/// <param name="target">目标实体</param>/// <param name="rotspeed">旋转速度</param>public targetcirclemanager(transform target, float rotspeed) {m_targetcircletrans = target;m_speed = rotspeed;m_isrotated = fal;}

26、targetcirclemanager pin 飞向目标圆管理,void updaterotatelf() 更新自身旋转,startrotatelf() 开始旋转,stoprotatelf() 停止旋转

/// <summary>/// 更新自身旋转/// </summary>public void updaterotatelf() {            if (m_targetcircletrans != null && m_isrotated==true)            {m_targetcircletrans.rotate(vector3.forward,time.deltatime * m_speed * -1);  // -1 是让其反向旋转            }} /// <summary>/// 开始旋转/// </summary>public void startrotatelf(){m_isrotated = true;} /// <summary>/// 停止旋转/// </summary>public void stoprotatelf() {m_isrotated = fal;}

27、scoremanager 分数管理类,管理分数,和分数变化更新的委托事件

public int score { get { return m_scroe; }t {// 判断分数是否更新,更新则触发更新事件                if (m_scroe!=value)                 {m_scroe = value;                    if (onchangevalue!=null)                     {onchangevalue.invoke(value); }                }}} // 分数变化委托public action<int> onchangevalue;

28、simplemessagecenter 简单消息中心,管理消息的注册,触发,和清空,并且设置静态单例(static simplemessagecenter instance),方便被访问使用

29、simplemessagecenter 简单消息中心, registermsg()注册消息,ndmsg()发送消息,clearallmsg() 清空消息

/// <summary>/// 注册消息/// </summary>/// <param name="msgtype"></param>/// <param name="action"></param>public void registermsg(msgtype msgtype, action action) {if (m_msgdict.containskey(msgtype) == true){m_msgdict[msgtype] += action;}el {m_msgdict.add(msgtype,action);}} /// <summary>/// 发送消息/// </summary>/// <param name="msgtype"></param>public void ndmsg(msgtype msgtype){if (m_msgdict.containskey(msgtype) == true){m_msgdict[msgtype].invoke();}} /// <summary>/// 清空消息/// </summary>public void clearallmsg() { m_msgdict.clear();}

30、conststr 统一管理一些不可变的常量字符串

/// <summary>/// 不可变字符串/// </summary>public class conststr {// pin 飞行目标圆 名字路径public const string world_targetcircle_name_path = "world/targetcircle"; // pin resources 预制体路径public const string resources_prefabs_pin_path = "prefabs/pin"; // pin head 名字public const string pin_head_name = "pinhead";}

31、enum 统一管理枚举类型

/// <summary>/// pin 状态/// </summary>public enum pinstate{idle = 0,// 闲置状态readying,// 正在准备状态readyok,// 装备好状态fly,// 飞向目标状态}  /// <summary>/// 消息类型/// </summary>public enum msgtype{gameover = 0, // 游戏结束}

32、gamemanager 游戏管理类 ,直接挂载到场景中,获取一些场景游戏实体,并管理一些游戏逻辑的初始化等

33、gamemanager 游戏管理类 ,awake() 和start() unity自带函数,初始化变量和类,以及启动游戏,targetcircle 开始旋转,pin 开始准备,在简单消息中心注册监听游戏结束事件,设置 分数变化更新到 textmesh 上,等等

        private void awake()        {            // 初始化参数值            m_maincamera = camera.main;            m_isgameover = fal;            transform targetcircletrans = gameobject.find(conststr.world_targetcircle_name_path).transform;            m_targetcirclemanager = new targetcirclemanager(targetcircletrans, rotatespeed);            m_pinsmanager = new pinsmanager(m_pinspawnpos.position,m_pinreadypos.position, targetcircletrans.position,                m_pinflytargetposdistance,m_pinmovespeed,targetcircletrans);            m_scoremanager = new scoremanager();        }         private void start()        {            // 开始targetcircle旋转            m_targetcirclemanager.startrotatelf();            // 生成第一个 pin             m_pinsmanager.spawnpin();            // 注册监听游戏结束消息            simplemessagecenter.instance.registermsg(msgtype.gameover,togameover);            // 初始化分数 0            m_scoremanager.score = 0;            // 分数更新事件,更新 ui            m_scoremanager.onchangevalue += (score)=> { scoretext.text = score.tostring(); };        }

34、gamemanager 游戏管理类 ,update() unity自带函数,游戏未结束,targetcircle 每帧转动,并监听鼠标左键按下,fly pin 和生成下一个 pin 准备

        private void update()        {            // 游戏结束            if (m_isgameover == true)            {                return;            }            // targetcircle 更新旋转            m_targetcirclemanager.updaterotatelf();             // 监听鼠标左键按下            if (i幼儿园装修方案nput.getmoubuttondown(0))            {                // pin 飞向目标,则增加分数,并且生成下一个 pin                bool isfly = m_pinsmanager.flypin();                if (isfly==true)                {                    m_scoremanager.score++;                    m_pinsmanager.spawnpin(); // 生成下一个                }                           }        }

35、gamemanager 游戏管理类 ,ondestroy() 在游戏重新加载销毁时,进行一些数据清理置空,并停止可能的所有协程(不阻碍主程运行的小程序),ongui() 做一些游戏操作说明

        private void ondestroy()        {            // 销毁所有 pin            m_pinsmanager.destroyallpins();            // 清空消息中心            simplemessagecenter.instance.clearallmsg();            // 置空分数更新事件            m_scoremanager.onchangevalue = null;            // 置空相关参数            m_pinsmanager = null;            m_targetcirclemanager = null;            m_scoremanager = null;            // 停止所有协程            stopallcoroutines();        }         // unity 周期函数 每帧调用        private void ongui()        {            // 游戏操作说明            guistyle fontstyle = new guistyle();            fontstyle.normal.background = null;    //设置背景填充            fontstyle.normal.textcolor = new color(1, 0, 0);   //设置字体颜色            fontstyle.fontsize = 40;       //字体大小            gui.label(new rect(10, 10, 200, 200),                "操作说明:\n1、点击鼠标左键发射球体;\n2、两针 哥哥别离开我pin 碰撞会自动触发重新开始游戏;",                fontstyle);         }

36、gamemanager 游戏管理类 ,togameover()游戏结束事件,停止旋转,开启协程,进行游戏结束特效处理,然后自动重新加载当前场景,重新开始游戏

        /// <summary>        /// 游戏结束        /// </summary>        void togameover() {            // 游戏结束            if (m_isgameover==true)            {                return;            }            // 游戏结束            m_isgameover = true;            // 停止目标旋转            m_targetcirclemanager.stoprotatelf();            // 开始结束协程            startcoroutine(gameover());        }         /// <summary>        /// 游戏结束协程        /// </summary>        /// <returns></returns>        ienumerator gameover() {            while (true)            {                // 等待帧最后                yield return new waitforendofframe();                 // 更新主camera 视口                m_maincamera.orthographicsize = mathf.lerp(m_maincamera.orthographicsize, m_orthographicsize,time.deltatime * 10);                // 更新主camera 背景色                m_maincamera.backgroundcolor = color.lerp(m_maincamera.backgroundcolor, color.red,time.deltatime * 5);                // 更新主camera 视口 到位,跳出循环                if ((m_maincamera.orthographicsize - m_orthographicsize)<0.01f)                {                    break;                }            }             // 加载当前场景            scenemanager.loadscene(scenemanager.getactivescene().buildindex);        }

37、把 gamemanager 挂载到场景中,根据 gamemanager 参数说明赋值,一些速度等可以根据实际需要修改

38、运行场景, pin 自动准备好,游戏就开始了

39、点击鼠标左键,即可发射fly,如图

七、工程源码地址

github 地址:github – xankui/unityminigameparadi: unity 游戏开发集合代码集

八、延伸扩展

游戏的好不好玩,趣味性,视觉化等诸多因素影响,下面简单介绍几个方面拓展游戏的方向,仅做参考

1、可以根据自己需要修改游戏资源,换肤什么的等

2、可以根据需要添加撞击特效,音效等

3、添加 ui 面板等,美化游戏

4、等等

以上就是unity实战之flypin(见缝插针)小游戏的实现的详细内容,更多关于unity见缝插针游戏的资料请关注www.887551.com其它相关文章!

本文发布于:2023-04-04 11:11:37,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/8be03f4f9dad570a903c29436d466cd9.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:Unity实战之FlyPin(见缝插针)小游戏的实现.doc

本文 PDF 下载地址:Unity实战之FlyPin(见缝插针)小游戏的实现.pdf

标签:游戏   目标   位置   状态
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图