(一)
不要和我说话,我不想和任何人说话,我要安安静静的写文章,说也不要打扰我。
我是初学unity两个多月的新手,我也没能力和大家说话。
这篇文章的名字:unity游戏源码:智能分析话语的三维唯美世界。
游戏开发语言和人工智能的语言都是C#。
数据库是单机数据库sqlite,就是在用户电脑游戏文件里的不联网的数据库,不用安装服务,也不用做任何配置,直接就能用。数据库内容对用户是完全可见的。
编辑器是unity2022.3.38。
这个游戏的源码(含教程文档)我放到了夸克网盘https://pan.quark.cn/s/618fb9459029
智能分析话语的教程,我写了六章,每一章都是在前一章的基础上增加一些内容,这样有个循序渐进的过程,大家才能看懂源码。如果直接给大家源码的最终结果,大家就看不懂了。源码的注释量比程序还多,所以源码本身就是教程。我已经尽心尽力去写这个教程了,如果还看不懂,那就不是我的问题了,而是你自己智力的问题。
(二)界面
小区:
小区傍晚的雪:
小区的晚上:
家里:
市中心:
市街道:
郊区:
(三)声明
小区场景的三维模型来自于UnityStore的unity包:Low Poly Japanese Housing Complex。很多人在用,所以我的游戏和其他人的游戏出现这个相同场景,不是抄袭。而且那只是个三维模型,程序要自己写,每个人写的程序是不同的。
市中心、市街道、郊区场景,来自UnityStore的unity包:258316_Anime_Tokyo_(Japanese_City),也有很多游戏开发者在用这个场景三维模型。
人物三维模型来自于网络上大家常见、常用的三维人物模型,我做了骨骼绑定、蒙皮、走路动画。
雪景程序来自于unity包:Global Snow,天空盒来自于unity包:AllSky。
(四)基本操作
W键(长按):向前走。
S键(长按):向后走。
A键(长按):向左转。
D键(长按):向右转。
鼠标左右上下移动来控制摄像机视角(屏幕视角),人物前进方向自动朝向摄像机视角。
键盘右边的方向键:上:抬高摄像机视角,下:降低摄像机视角,左:拉近摄像机视角,右:拉远摄像机视角。
F键(单击):第三人称视角和第一人称视角的切换。第三人称视角适合用在街上,第一人称视角适合用在家里。
空格键(单击):显示或关闭文字的输入输出框(默认不显示,需要点击空格键才显示)。输入完文字后,按回车键发送。
M键(单击):背景音乐,继续按,是下一首背景音乐。
数字键1(单击):小区场景(默认场景)。
数字键2(单击):市中心场景。
数字键3(单击):市街道场景。
数字键4(单击):郊区场景。
Esc键(单击):退出游戏。
小区场景中:
H键(单击):小区场景时,可以一键回家。
G键(单击),男主角和女主角分开,女主角停留在原地。男主角走远后,第二次按G键,女主角会自动寻路来找男主角,到男主角身边。
J键(单击):女主角一键换服装。
K键(单击):每点击一次,就变换一次天色。浅夜→夜晚→白天→傍晚→夜晚→清晨→白天→阴天。
L键(单击):正常景色和雪景的切换。
(五)
即便没有安装unity编辑器的情况下,play文件夹里DreamStart.exe可以直接运行此游戏。
unity的一份源码,只能适配一个编辑器版本,这个源码适配的是2022.3.38,其它版本打开此源码,会故障。
unity导入此项目时,不是导入哪个具体启动文件,而是用unity Hub(unity启动器)直接打开(导入)DreamStart文件夹。
如果unity编辑器没有显示场景,就在编辑器里手动打开park文件夹里的Scenes文件夹里的park场景文件即可。
在unity编辑器界面,不要把窗口最大化后再运行游戏,那样运行不了。但可以在游戏后,再最大化窗口。
地上的蓝色,是自动寻路烘培的地面,游戏运行时不显示那蓝色。
(六)话语分析
话语分析是有用的,假如游戏中,你是队长,带着NPC队友张三和李四,路上遇到蛇,你可以说“张三打蛇,李四保护张三。”这就需要先分析出主语、谓语、宾语,程序才能处理。
输入完成后,按回车键发送。
示例:
输入:猫吃鼠
显示:主语:猫,谓语动词:吃,宾语:鼠
输入:白色的猫吃黑色的鼠
显示:主语:猫,谓语动词:吃,宾语:鼠,主语的形容词:白色的,宾语的形容词:黑色的
输入:两只猫吃3只鼠
显示:主语:猫,谓语动词:吃,宾语:鼠,主语的数词:2只,宾语的数词:3只
输入:张三的猫吃李四的鼠
显示:主语:猫,谓语动词:吃,宾语:鼠,主语的名词所有格:张三,宾语的名词所有格:李四
输入:张三给李四苹果
显示:主语:张三,谓语动词:给,间接宾语:李四,直接宾语:苹果
输入:张三让李四打扫教室
显示:主语:张三,谓语动词:让,宾语:李四,宾语补足语动词:打扫,宾语补足语名词:教室
输入:2024年张三在学校吃饭
显示:主语:张三,谓语动词:吃饭,时间:2024年,地点:学校
如果分析显示不了,可能词语不在词库里。先找动词分割句子,再找名词,所以如果动词不在词库里,即便名词在词库里,也没用。
连接的单机数据库是garden.db,是sqlite单机数据库,就是在用户电脑的游戏文件里的,不联网的、不用安装服务的、不用配置的,直接就可以用的数据库。
目前词库里,名词7128个,动词5886个,形容词1777个。
第一章的主要内容:
判断输入的句子中,是否包含名词。
找出句子的主语、谓语、宾语。
解决三个基本问题
前面的方法,靠句子包含的词直接与词库的词对比,来找主语(名词)、谓语(动词)、宾语(名词),会有问题:
第一个问题:熊猫吃竹子,这句话里你感觉有感觉有两个名词:熊猫、竹子,但是电脑会找出四个名词:熊猫、熊、猫、竹子。
对于第一个问题的解决方法:
新找到的长词(熊猫)覆盖已找到的短词(熊、猫)。
已找到的长词(熊猫)吸收新找到的短词(熊、猫)。
所以创建一个函数:WordCover(覆盖)。
词语槽(WordBox)存放这些找到词,以实现覆盖和吸收。
第二个问题:熊猫喜欢森林的竹子,这句话动词右边句有两个名词,竹子是宾语,而森林不是宾语,因为森林后边有个“的”字,是名词所有格。
对于第二个问题的解决方法:
找到的名词右边的第一个字符,看它是不是“的”字,如果是“的”字,那么这个名词就不是宾语,找主语也是同理。
所以创建一个de函数。
第三个问题:“学”字是动词,但是在“学生”这个词里,“学”字就变成名词了,还当动词理解,就会错。
对于第三个问题的解决方法:
建立词性辨析表:verb_judge,词性辨析表在数据库里,已经做好了。
第二章的主要内容:
基本单句有六种句型:
只有性质状态(表语):真漂亮、对啊、太好了。句子里没有谓语动词,其余五种句型里,都有谓语动词。
主语(动作执行者)-谓语(动作):张三摔倒。
主语(动作执行者)-谓语(动作)-宾语(动作对象):猫吃鼠。
主语-谓语(是)-表语(表明主语的身份和性质状态):张三是老师,太阳是美丽的。
双宾语句型:主语(传输的人)-谓语(传输动作)-间接宾语(传输对象)-直接宾语(传输的事物):张三给李四苹果,张三教李四数学。
宾语补足语句型:主语-谓语(例如把、使、让)-宾语-宾语补足语(做什么):张三让李四跳舞,张三把房间弄脏了。
前面只说了主谓宾句型,还要处理其它句型。
双宾语句型:
双宾语句型的谓语动词后面有两个名词,例如张三给李四苹果,李四是间接宾语(名词),苹果是直接宾语(名词)。
但是有两个名词的就是双宾语句型吗?不是的。例如张三喜欢足球学校。谓语动词后面有两个名词:足球、学校,但显然足球学校是一个整体名词,也就是主谓宾句型,而不是双宾语句型。因此判断双宾语句型,还要看谓语动词是不是适合双宾语句型的。
双宾语句型的谓语动词主要是传输事物的动词:给、送给、教。
那么谓语动词是双宾语句型的动词(例如给、教),且谓语动词后面有两个名词(体现为谓语动词右边的语句处理时,名词槽NounBox有两个名词,NounBox1和NounBox2都有值),就可以判断为双宾语句型。
还有,像“足球学校”这样两个名词连在一起,就要合并成一个名词,作为主语或宾语。
仅从双宾语句型的标志动词“教”判断双宾语句型,不一定准确,例如“他教我数学”是双宾语句型,但“他教书”就不是双宾语句型,所以还要根据宾语名词的数量,来判断到底是不是双宾语句型,如果动词右边只有一个名词,例如“他教书”的“书”,句子就不是双宾语句型。所以通过谓语动词判断一个句子是双宾语句型后,根据找到的名词数量,例如只有一个宾语名词,那么就要把双宾语句型,修正回主谓宾句型。
名词次序:间接宾语在直接宾语之前,所以找到两个名词,次序在前面的那个名词,是间接宾语,次序在后面的那个名词是直接宾语。
宾语补足语句型:
和主谓宾句型不同,宾语补足语句型含有主谓宾句型的部分,但宾语后面还有个动作(动词),也就是宾语补足语。
因此看宾语后面是否还有动词,是判断宾语补足语句型的方法。
但是有两个动词就麻烦了,如何判断这个动词是谓语动词还是宾语补足语动词呢?那就需要先把所有动词找出来,如果是宾语补足语动词,那么这个动词在谓语动词的后面,如果是谓语动词,则在前面。
既然要存放多个动词进行判断,就要有动词槽(VerbBox)。
动词次序:谓语动词在宾语补足语动词之前,所以找到两个动词,词语次序在前面的是谓语动词,词语次序在后面的是宾语补足语动词。
宾语补足语动词后面还有个名词,宾语补足语动词和这个名词合并在一起,作为宾语补足语。例如他让我打扫教室。如果宾语补足语只是“打扫”,话就说不清楚了。但是有些宾语补足语,就只有动词,后面没有名词,例如“他让我跳舞”就只有“跳舞”这一个动词,“跳舞”这个词后面没有名词,因为“跳舞”是不及物动词。
双宾语句型和宾语补足语句型,都是由主谓宾句型拓展而成的。双宾语句型在主谓宾句型的基础上,多加了一个宾语。宾语补足语句型在主谓宾句型的基础上,多加了一个动词(宾语补足语)。所以先完成主谓宾句型,再根据是否有拓展,来判断是不是双宾语句型或宾语补足语句型。
第三章的主要内容:
省略主语有两种情况:一种是主动语态省略主语,例如“跳过去”,全句指“你跳过去”。另一种是被动语态省略主语,例如“张三被打了”,没说谁打了张三,这里张三是宾语。如果说“李四打了张三”,李四就是主语。
被动语态的标志是“被”字,如果没有“被”字,而且省略了主语,就是主动语态省略主语的情况,那么这种情况下,主语应该填什么呢?例如“过来”,一般指“你过来”,但“走吧”一般指“我们走吧”。所以程序要根据具体的动词来判断省略的主语应该填什么。但是动词太多,每个动词都要设置省略的主语判断,太麻烦。所以省略主语,按最通常情况,就默认填“你”字,作为主语。如果主语是“我们”而不是“你”字,就不该省略主语。
被动语态应该还原为主动语态去理解,但被动语态往往没有主语,那么默认主语应该填什么呢?毕竟不知道主语,那就填“事物”这个词作为主语。
程序分析句子时,被动语态的主语位置的词,是宾语。例如“李四被打了”,李四在谓语动词左边句,程序会把李四当成主语,但在被动语态句里,李四不是主语,所以有“被”字的时候,主语要挪动到宾语位置,然后在主语位置补充“事物”这个词,作为主语。
但是有些时候,被动语态的主语是说明了的,例如“李四被张三打了”就还原为主动语态“张三打了李四”,张三做主语,而不是填“事物”做主语。
简而言之,被动语态里,主语放到了宾语位置,宾语放到了主语位置,所以变为主动语态时,要把宾语挪回主语位置,主语挪回宾语位置。
如果被动语态有主语,例如“李四被张三打了”,那么主语(张三)位于“被”字与谓语动词之间。
那么谓语动词左边句中,又分为“被”字左边句和“被”字右边句,被字左边句里的名词是宾语,被字右边句里的名词是主语。
名词合并:
名词合并:例如“足球学校”这个词,会被当成两个名词“足球”和“学校”。但实际中,要把它们合并成一个组合名词,作为主语或宾语。
合并方法:如果两个字符(词语)是连续的,那么这两个词语之间的内容为空。
动词合并:
例如“应该爱”是两个动词:情态动词“应该”和普通动词“爱”,应该合并成一个动词。
动词前面是否有否定词,也很重要。
例如“他爱猫”和“他不爱猫”,虽然谓语动词都是“爱”字,但前面加个“不”字,意义就相反了。所以看谓语动词前面是否有否定词,是很重要的事。
谓语动词前面的否定词,一般有不、不要、不可以、不应该、不能、别。
还有不确定肯定还是否定动词,例如“他不一定去”,“去”字是动词,但是动词前的“不一定”,并不像是“不”字那样对动词进行否定,而是对动词既不像是肯定,也不像是否定,而是不确定。
因此对每句话的谓语动词,都要加一个性质:肯定、否定、不确定。
但不确定,有时候偏向于肯定,例如“他可能去”。有时候不确定偏向于否定,例如“他不太可能去”以及“他或许不去”。
那么动词发生概率分为五种:肯定、偏向肯定、不确定、偏向否定、否定。
这其实就是在分析事情(谓语动词)发生的概率,这在概率分析上有用。
第五章的主要内容:
对于数词,之前用正则表达式直接抽取出数字,那种方法太简单了,我用逐字分析的方法重写了。
还有就是分析出时间,不仅分析出是年、月、日、时、分,还要分析出一些时间词:
"今天", "明天", "后天", "昨天", "前天", "这个月", "下个月", "上个月", "今年", "明年", "去年"
"早晨", "上午", "中午", "下午", "傍晚", "晚上", "傍晚", "夜晚", "半夜", "黎明", "黄昏", "清晨"
"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日", "礼拜一", "礼拜二", "礼拜三", "礼拜四", "礼拜五", "礼拜六", "礼拜天"
"春天", "夏天", "秋天", "冬天", "春季", "夏季", "秋季", "冬季"
"元旦", "大年三十", "除夕", "春节", "大年初一", "大年初二", "大年初三", "正月十五", "寒假", "清明节", "五一节", "劳动节", "儿童节", "暑假", "中秋节", "国庆节", "圣诞节", "假期", "休息日"
第五章可用的动词单位是:
"个", "名", "位", "只", "头", "匹", "条", "棵", "朵", "片", "根", "座", "栋", "台", "部", "本", "块", "件", "盏", "把", "所", "辆", "艘", "架", "扇"
"米", "厘米", "毫米", "分米", "公里", "里", "微米", "纳米", "克", "斤", "公斤", "吨", "毫克", "升"
先找到动词单位,才能找到数词。
第六章的主要内容:
直接宾语的定语(形容词、数词、名词所有格),在间接宾语和直接宾语之间。
例如张三给李四红色的苹果,李四是间接宾语,苹果是直接宾语,红色的是形容词。
间接宾语的定语在谓语动词和间接宾语之间,对于谓语动词右边句,也就是句子开始到间接宾语之间。
例如张三给美丽的李四苹果,李四是间接宾语,美丽的是形容词。
宾语补足语名词的定语(形容词、数词、名词所有格)在宾语补足语动词的右边。
例如张三让李四打扫蓝色的房子,打扫是宾语补足语的动词,房间是宾语补足语的名词,蓝色的是形容词。
第六章增加了猜测词语的功能,但不建议用猜测词语,因为如果一个词语,词库里没有,要靠程序猜测,那么游戏剧情肯定对这个词语没做任何准备,就算猜测出这个词,也没用。
例如张三爱雅娜,名词词库肯定没有“雅娜”这个词,但是谓语动词“爱”字右边的句子的两个字,显然是宾语名词,所以猜测词语是很容易猜测的。
就算猜测出宾语是雅娜,又怎样了呢,对雅娜的信息和属性,什么都没有设置,程序没法分析。甚至连雅娜到底是一个人还是一块石头,都没法分析。
那么张三带着雅娜去海边,到底是张三带着女人雅娜去海边,还是张三带着石头雅娜去海边,准备扔石头玩水漂。计算机分析程序一头雾水,所以猜测词语会降低计算机的分析能力。
还是勤快点吧,把词语录入词库,并给词语设置信息和属性。什么时候用猜测词语呢?词库词汇量还不够多的时候,只能靠猜词来补偿,但这不是长远的办法。
这就好比编程强调“对变量,要先定义,后使用”,猜测词语就好比不定义就直接使用。
猜测词语的原理:抽取掉已知的词语(词库里有的词语),剩下的未知的词语(词库里没有的词语),就是要猜测的词。
例如“张三喜欢美丽的雅娜”,谓语动词右边句是“美丽的雅娜”,词库已有的形容词是“美丽的”,抽取掉形容词“美丽的”,剩下的词语“雅娜”就是要猜测的宾语。
此外说明:
第一章的动词只能是一个字的动词,否则可能出错。从第二章开始,动词可以是多个字的。
第二章还不能用组合名词,例如足球学校,但可以用单个名词:足球、学校。
第三章可以用组合名词、组合动词,并修复了有时候动词只显示一部分的情况。
第四章,一次可以输入多句话,但只能用逗号或句号隔开,不能用问号和感叹号分隔句子。对主谓宾结构的句型,可以分析出定语(形容词、数词、名词所有格),但双宾语句型和宾语补足语句型,还没有做定语分析程序,而且数词只能用阿拉伯数字,也就是1、2、3这类数字,还不能用汉字型数字。
到第六章,各个方面都正常了。