今天在捣鼓QQ机器人,我的机器人框架是用go语言编写的开源框架(我是使用者、不是开发者),想自己尝试着给机器人编写插件、结果发现自己不会go语言。
在开始学前,我稍微有些顾虑。听别人说,不要一开始就学两门语言、建议先把一门语言学稳学好、再开始学习另一门语言。不过我还是去学习go语言了,因为很想快速地给我的机器人编写插件、调用很多API接口。学习go语言给我的感觉,这门语言很奇怪,因为不管是C、C#、java,声明变量都是“int a = 32;”,然后go语言是“var a int = 32”,把变量写前面、类型写后面;同时go语言对语言规范又很高的要求,对花括号的位置还有要求,因为设计者希望大家能用统一的规范去编写代码。不过整体来说,语言里一直存在的东西:变量、函数、接口、继承,这些都没变,属于是编程语言的共通性了。
本文用于详细记录我想实现的demo的游戏功能,我感觉需要先有目标才能做好。
demo概述
demo是一款简单的ACT游戏,类似《只狼》简化版,场景中有一个boss。通过格挡、刀砍、把boss打死算获胜。
玩家需求:WASD控制移动,鼠标左键攻击,右键格挡,有一套组合技;有格挡值、生命值,Shift向前冲刺,S+Shift向后闪避,A/D+Shift分别向左和向右闪避。
Boss需求:有几套组合技,通过有限状态机控制Boss状态,有生命值、格挡值,格挡值被打满进入硬直状态,可以进行格挡
UI需求:有开始界面、游戏界面、设置界面、退出界面;显示角色血条格挡值和Boss血条格挡值。
玩家拓展部分(可选):按U键发射飞镖。
音乐音效方面简单配置即可。
***
以上就是一个简单的游戏需求。
突然想写一写,觉得对于想学习游戏开发的朋友,帮助应该挺大的。
很多Unity学习者,状态和我一样:会使用Unity,也会C#编程,但你问我会不会开发游戏,我表示不会…明明已经会编程了,接口、继承、事件委托张口就来、代码写得行云流水;明明已经会用Unity这款软件了,为什么还不会游戏开发?
这里我想到一个很好的比喻,是“建房子”。我们Unity学习者就像工人,学习Unity和C#,相当于在学习一些技能:怎样抹水泥、怎样打钢筋,到现在,这些我们都是会的。然而建房子的精髓是什么?是如何设计这座房子、怎么把房子设计得好看,不光有工人挥洒汗水、背后还有一个拿着设计图纸的人,缺少的主要就是这些了。就像武林高手比武,不光要有招式、更要有深厚的内力。
我也看了很多教程,最终我觉得,学习Unity和“游戏开发”不是一回事,说到底,Unity和C#只是游戏开发的工具,不是游戏开发本身。市面上好多课,感觉其实挺不值的。跟着别人的视频、照猫画虎把游戏做出来,发个视频展示下成果,貌似也很有成就感,但实际上还是什么也不会。我感觉吧,最好的学习方式是结合具体需求去完善相关功能,可以先去参考市面上一些常见的游戏, ...
前伍六七第六集、第七集比较水,招致很多观众不满,评分跌破7.5分,啊哈大概看见了观众不满的声音,这周三《伍六七之记忆碎片》一连更新两集。第八集感觉中规中矩,第九集可谓信息量炸裂,交代了首席的身世,同时强化主旨和核心,令我印象深刻。
在第九集中,有一个画面我印象很深刻,伍六七拥抱着过去满是戾气的自己。当时伍六七得知真相,无眼法师预测伍六七会展开复仇、准备杀掉阿七,然而阿七接受了自己的过去。“我已经和以前不一样了”,阴霾散去,阳光迎来。
之所以感触深,大概有两点吧。第一点是,伍六七和很多人很像,我能从伍六七身上看到自己曾经的影子(但是是负面意义的):逃避过去、逃避自己。很多人一直不能与自己、与过去和解,厌恶自己的过往、讨厌曾经或者现在的自己;亦或是有很多后悔和遗憾:我以前要是怎么样怎么样就好了,我有着如何不堪回首的过往和经历。否定自己的过去,否定曾经的自己。然而,我觉得阿七身上传递出一个很正的价值观——接纳自己、拥抱过去。无论过去怎么不堪,但其实,正是有了过去的你、才有了现在的你自己,过去的你构成了现在的你,否定过去、既否定你自己。拥抱过去、接纳自己、与自己和解。
另一点是,在剧情中,阿 ...
最近在试图制作连招系统,每次遇到这种逻辑稍微复杂的我都容易头痛,总感觉逻辑好乱啊,于是准备稍微系统性地记录思路,这样更好。
思路
采用“从大到小”的思路:首先我们需要一个连招表,用于记录不同连招逻辑,比如按三下左键打出什么组合。
然后需要思考,什么时候可以攻击,那么这就会引入bool变量CanAttack,先考虑不能攻击的时候:翻墙时、在空中时、被敌人攻击时、格挡时;可以攻击的时候:待机时、跑步时。
接下来考虑我们的攻击冷却时间和攻击距离。先是冷却时间,防止玩家快速点击鼠标键、导致角色攻击动画快速切换造成抽搐效果(比如有人用连点器一秒点999次)。然后是攻击距离,敌人在这个距离内可以被打到播放受伤动画,距离外就不可以。关于冷却时间这点,我们需要自己写个计时器,先做记录
再往下小的方面去考虑,该考虑怎么进行组合呢?我的想法是用ScriptableObject将不同动画文件储存起来,形成一套连招技能配置器
再往小的方面去考虑每个单一的动作,我们需要什么?首先是动作名字ComboName,然后是造成伤害Damage,接着是冷却时间ColdTime,还有攻击距离Distance,此外,每个攻 ...
在学习一项新事物前,要先了解我们的需求是什么,为什么需要计时器。我在试图做ACT游戏demo时,想要给角色加上技能冷却CD,在CD时间内角色不能释放技能,CD后才可以。于是有了需求就开始制作计时器吧。
很早前,我在b站看到网友的Unity制作视频,看到丝滑的跑步、冲刺、急停、待机切换,很是羡慕,自己操作起来总是困难重重。意识到自身不足后,我又回去补唐老狮的Unity小框架了,我现在的进度是这样的(供参考):唐老狮C#四部曲、唐老狮Unity入门基础核心、Unity进阶之InputSystem、唐老狮Unity基础小框架。
流程
在实现这个简单的动作系统之前,我先进行了三个工作,一是写了单例模式基类脚本,二是把相机逻辑、InputSystem配置和书写好了,三是写(抄袭)了个角色控制器基类脚本。之后才开始实现这个简单的动作系统。
动画系统思路
最先我想用有限状态机FSM+blendtree实现的,但最后还是采用以下的方式(先从比较常规的方法做起来比较好)
大体思路是,将跑步动画、冲刺动画装到1D混合树,设置bool变量HasInput、速度变量Speed、bool变量Spring。如果HasInput为false,且Speed小于0.65,从混合树过渡到跑步急停;如果HasInput为true,且Speed大于0.65,从混合树过渡到冲刺急停;至于Spring,按下的时候,会将spee ...
如今的Unity提供官方写好的缓存池,但我还是打算讲讲自定义缓存池怎么写。
缓存池用途
在射击游戏中,游戏中存在着频繁的子弹创建和销毁工作。如果内存大量频繁地创建和销毁物体,势必会带来很明显的卡顿和性能开销。游戏开发者思考,我是不是可以重复利用固定几个物体、减少内存浪费和性能开销?于是有了缓存池。
思路
以射击游戏为例,先去思考怎么实现子弹缓存效果,我的想法是,场上能看见的子弹也就五、六个,射出去的子弹超出玩家视野后、进行重复利用。于是分类:子弹类——子弹1、子弹2、子弹3、子弹4...
然而缓存池不一定只有子弹类,可能还有炮弹类、垃圾类等等,最后划分大概是这样的一张图表:
物体
子弹类
炮弹类
垃圾类
...
子弹二
炮弹二
垃圾二
...
子弹三
炮弹三
垃圾三
...
这就类似于我们的衣柜,衣柜里有不同的抽屉,每个抽屉里放着不同的衣服,于是联想到字典和List,用Dictionary<string,List>来存储
本文引入一种常见的设计模式:观察者模式。
事件中心模块作用
在玩游戏时经常有这样的场景,你打死了一只怪:怪物爆金币、角色经验提升、角色天赋升级。假如你是游戏开发者,会怎么处理这些逻辑?我最先的想法是这样的:写一个void MonsterDead(){},在里面添加各种方法,GetMoney()、PlayerUpdate()。
这样写貌似也没问题,但是当逻辑多起来、维护起来就比较困难了,又杂又乱。用专业的语言来说,就是我们“代码耦合性高”。因此引入事件中心模块。
思路
在军队中,有着指挥部。我们是不是也可以在代码里建立个“指挥部”,把各种命令都交给指挥部来做?
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354//既然是指挥部,那就只有一个,继承单例模式基类public class EventMgr : SingletonBase<EventMgr>{ //我们用字典来存储,思路是,用string来存储游戏里的事 ...
这篇文章介绍一下公共Mono模块。
为什么有公共Mono模块?
很多时候我们写代码,不想继承MonoBehaviour类(比如减少性能开销、简化代码量,MonoBehaviour),但又想用MonoBehaviour里Update、Start等方法。这时候就需要搭建公共Mono模块来实现我们的需求了。
思路
以实现Update为例,既然我们知道,不继承MonoBehaviour类的不能直接调用Update等方法,那么有没有什么办法、把我们的方法塞到update里呢?
答案是有的,这里有个知识点是“委托和事件”,我们可以把我们的方法、塞到委托里,在继承Mono的脚本里调用这个委托就可以了。我们创建一个继承MonoBehaviour的脚本MonoController,我们需要声明委托、还有向委托里添加删除方法的函数:
1234567891011121314151617181920212223242526272829303132333435363738394041using UnityEngine.Events;public class MonoController : MonoBehav ...