基于 Unity3D技术的农场体验游戏的设计与开发_第1页
基于 Unity3D技术的农场体验游戏的设计与开发_第2页
基于 Unity3D技术的农场体验游戏的设计与开发_第3页
基于 Unity3D技术的农场体验游戏的设计与开发_第4页
基于 Unity3D技术的农场体验游戏的设计与开发_第5页
已阅读5页,还剩61页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

摘要随着人们日常生活内容的丰富,以及现代计算机技术的提升,计算机游戏成为了一个崭新的娱乐载体渐渐进入了大家的视野。在众多类型游戏之中,模拟养成类游戏始终是一棵常青树,经久不衰。模拟类型游戏的宗旨是把人们向往的生活带到游戏中,体验不同的生活方式。本研究项目是一款模拟农场生活,体验田园风光的模拟类养成游戏,基于Windows10系统Unity3D引擎并且采用编程语言C#制作。在制作过程中,使用Photoshop进行素材以及UI界面的处理。本研究项目许多功能借鉴于小时候的农村经历,将日常生活中的农作物耕作,以及与家畜的互动加入游戏中,因此玩家在体验该游戏时会有更多的真实感,会有更深层次的沉浸式体验。本研究项目的初衷是推广农村文化,让玩家对农村生活有更多的了解,并且喜欢上农村生活。□□关键词:模拟农场游戏Unity3D场景交互农作物动物AbstractWiththeenrichmentofpeople'sdailylifeandtheimprovementofmoderncomputertechnology,computergameshavebecomeabrand-newentertainmentcarrierandgraduallycomeintoourvision.Amongthemanytypesofgames,thesimulatednurturinggameisalwaysanevergreentree.Thepurposeofsimulationtypegameistobringpeople'syearninglifeintothegameandexperiencedifferentlifestyles.Thisresearchprojectisasimulationgameoffarmlifeandruralscenery,Itisbasedonunity3dengineofwindows10systemandmadebyC#.Intheprocessofproduction,PhotoshopisusedtoprocessmaterialsandUIinterface.Manyfunctionsofthisresearchprojectdrawlessonsfromtheruralexperienceinchildhood,Addthefarmingofcropsindailylifeandtheinteractionwithlivestocktothegame,soplayerswillexperiencethegamewithmorerealismanddeeperimmersionexperience.Theoriginalintentionofthisresearchprojectistopromoteruralculture,sothatplayerscanhavemoreunderstandingofrurallife,andletthemlikerurallife.□□Keywords:SimulationfarmgameUnity3DSceneinteractioncropsanimals广东东软学院本科生毕业设计(论文)目录TOC\o"1-3"\u第一章 引言 引言研究背景与意义随着科学技术的提升,电脑已经成为人们日常生活中不可或缺的一部分,电子信息技术不仅应用在人们日常的办公中,从电子信息技术中诞生了许多的娱乐媒体,充实了人们日常生活中的娱乐。在众多的娱乐媒体中,电子游戏作为新兴的娱乐载体,成为了在日常生活中让人们喜闻乐见娱乐项目。迄今为止,游戏产业在我国蓬勃发展,提供了许多的就业岗位,为我国生产总值贡献了越来越多的力量,与游戏制作相关的职业也成为了前景较好的职业。为了研究电子游戏的开发过程,在本项目中,我选择制作一模拟养成农场类游戏作为研究对象。模拟类游戏的发展现状随着游戏技术的发展,电子游戏也发展出了许多方向、类型的游戏种类。其中模拟类游戏作为一种较为经典的游戏种类,从诞生开始一直经久不衰。在早期的电脑游戏中,《三维弹球之太空军校生》就是一款比较经典的模拟类游戏。该游戏就是模拟当时社会中比较流行的弹珠弹球游戏的内容创作的。当时该电脑游戏出现后,销量一直火爆,直到现在依然是人们所津津乐道的游戏。模拟类游戏的主要方向是:从已有日常生活中获得灵感,在游戏中模拟出这种生活文化,让玩家即使没有亲身经历这种生活也能感同身受。模拟类游戏从某种意义来说就是日常生活的延伸,不仅可以让玩家获得游戏上的享受,更是或多或少的宣传了被模拟的生活文化。农场游戏目前的发展在电子游戏发展的历史长河中,不乏许多农场养成游戏名作,比如十几年前的《牧场物语:矿石镇的伙伴们》;在steam平台中前些日子比较火的《星露谷物语》和国人自行研发的《波西亚时光》;还有时下刷屏各大媒体平台,话题量火爆的《集合!动物森友会》。农场游戏一直以贴近自然,休闲放松而著称。目前人们快节奏的生活给予了人们很多压力,人们开始向往以前美好的田园生活。在农场游戏中,玩家可以体验与自然的接触,享受丰收的喜悦,感受与动物的交往,农场游戏无疑是人们紧张生活时的一款缓冲剂。在让玩家享受游戏之外,农场游戏还向玩家宣传了自然知识,农村文化,让玩家知道生活中食物的来源,了解到食物来之不易。章节安排为了方便阅读,我将在这里阐述本论文的主要内容,以及各个章节的组成部分。第一章:引言。介绍研究的背景以及意义、模拟游戏的发展、农村游戏的现状。第二章:使用工具。介绍所使用工具,在制作游戏过程中所起到的作用。第三章:游戏功能设计。介绍创作游戏的想法,策划该游戏的功能,游戏的操作方法。第四章:功能实现。实现所设计的功能的过程,实现功能过程中的难点、具体步骤和主要思路。第五章:游戏测试。将游戏导出打包,进行测试以及运行结果。

使用工具2.1Unity3D引擎2.1.1介绍Unity3D第一个版本由UnityTechnologie公司于2005年6月发布。Unity3D引擎搭载的编程语言是C#,方便使用者轻松的创建游戏。除了创建游戏以外,Unity3D还广泛的应用于制作动画,建筑三维建模等方面。2.1.2在本游戏中的应用本游戏是以Unity3D引擎为平台来进行开发设计的。在Unity3D中进行了模型的整合,场景的搭建,各个游戏对象的层级判断和位置判断。除此之外,Unity3D还作为了一个中间桥梁,将脚本与游戏对象联系起来,并且将脚本所编写的功能于游戏对象上实现。Unity3D本身还提供了各种组件,节省了脚本实现功能的工作量,让使用者更加有效率的创建游戏。在运行脚本的时候,Unity3D还提供检查功能,如果脚本报错,它会提醒使用者错误的来源地。2.2VisualStudio2.2.1介绍VisualStudio第一个版本由微软公司于1997年发布。VisualStudio是一个完整的开发工具集,适用于微软的所有平台。VisualStudio早期版本的语言开发主要是C++。在编写游戏脚本中使用的C#最早是于2002年版本所开发的面向对象的编程语言。2.2.2在本游戏中的应用编写游戏脚本所使用的工具,所使用的编程语言为VisualStudio所自带的C#。2.3PhotoShop2.3.1介绍PhotoShop是由Adobe公司开发的专门用于对图片进行处理以及编辑的专业工具。PhotoShop具有强大的的编修以及绘图功能,除了处理编辑图片以外,它还在文字、视频、出版等方面有广泛的运用。2.3.2在本游戏中的应用制作游戏时对素材进行处理的工具。获取了初始资源后,通过PhotoShop对其进行截取,修改大小,编辑形状,最终成为游戏素材。游戏中的UI界面也是通过PhotoShop的图形绘画制作的,通过绘制基本图形,再加以整合,贴图。2.4Unity3d使用相关函数Start:当脚本被加载时执行,并且只执行一次。Update:脚本实时调用。GetComponent:获取对象组件信息。Destroy:摧毁对象。Return:返回函数。Instantiate:添加对象。GameObject.Find:从游戏中查询对象。Public:声明公共对象,可以被外部调用。Private:声明私有对象,不可以被外部调用。If:判断语句。如果符合判断条件则继续向下执行。For:循环语句。如果符合条件则继续使用,不符合则跳出循环。Load:从文件中加载资源。Substring:检索字符串。

游戏功能设计3.1场景设计3.1.1游戏功能结构 游戏功能结构如下图所示图3-1功能结构联系图

3.1.2素材选择以及美工画风本游戏是一款画风为像素风格的模拟养成类型的农场游戏,基于这个游戏格调,场景素材以及人物素材自然就不能选择3D的模型素材,应该选择像素风的游戏素材,应该考虑像是塞班平台的《阿尔卑斯牧场物物语》、GameBoy平台的《矿石镇的伙伴》这类型的游戏的模型和人物、动物、植物素材就比较符合游戏的基调,在处理本游戏素材的时候,美工就可以向它们借鉴。图3-2矿石镇的伙伴图3-3阿尔卑斯牧场物语3.1.3场景素材以及地图规划本游戏的场景对象组成主要有4种:建筑、人物、动物、植物、自然风光、工具、以及UI界面。建筑主要的建筑是主角的家、商店、栅栏。家:主要的作用就是让主角恢复体力,并且加速时间的流逝,到第二天。商店:主要作用就是提供一个交易平台,让主角能购买植物的种子、动物幼崽。并且能让主角卖出自己的农作物以及动物。栅栏:用来限制动物的移动,当从商店处购买动物幼崽的时候,动物幼崽将出现在这里。栅栏里面还需要2个功能块:a、饲料槽C、收获槽。喂养槽用来放饲料,收获槽用来收获动物产品。人物总共需要4个,分别是左、右、上、下四个行走的模型。图3-4人物模型动物羊、鸡、牛、羊、兔五种动物模型。以及羊毛、鸡蛋、牛奶、兔肉、羊肉、牛肉、鸡肉各种模型。图3-5动物

植物植物有冬瓜、可可、向日葵、土豆、小麦、柠檬、橘子、玉米、番茄、稻米、窝瓜、红玫瑰、蓝玫瑰、肉桂、茄子、草莓、菠萝、萝卜、葡萄、黄瓜。每种农作物还需要5个生长状态,在生长状态里面还包括种子和果实。图3-6植物自然风光自然风光里面包括可互动的以及不可互动的两种。不可互动的是各种地图装饰品,像是草地,树木。可互动的包括河流、地障。地障碍包括:树桩、岩石、杂草。每种地障都有两种状态贴图。图3-7障碍物工具工具总共包括:镰刀、斧头、锤子、锄头、水壶。图3-8工具3.2主角操作3.2.1移动主角通过“W”“A”“S”“D”以及上下左右箭头移动。在移动的时候,主角会因为位置的移动而改变动作模型。比如说按下“A”向左走,模型也会切换成向左的模型。当主角移动到有障碍的地方就不能移动,像是建筑物,树木等。3.2.2与其他场景对象的互动与其他物体的互动键都是“E”键。当主角与房屋大门互动的时候,可以进入屋子,与屋子内的床互动的时候可以跳到下一天。当与商店大门互动可以购买物品。与喂养槽互动可以加饲料,与收获槽互动可以收获动物产品。与小河互动可以为水壶装水。与耕地互动可以改变地形或者播种,收获农产品。3.2.3打开背包以及工具箱背包:按“X”键打开背包系统。在背包系统下按“W”“A”“S”“D”控制物品的选择,再按下“E”实现物品的使用。工具箱:按下键盘的1、2、3、4、5、6键改变工具的选择。图3-9背包3.3植物系统想要种植植物,收获农作物,首先要去商店购买种子,然后清理耕地上的杂物,耕好田,再浇上水,这样才能把种子种进地里。每种植物都有两个属性:水分值以及品质。随着时间的流逝,每个植物都需要浇水,如果没有浇水会影响植物的生长。植物的成长总共有五个阶段,每个阶段都有独立的贴图。随着时间的改变,植物会慢慢成长,从种子最终长成农作物。

图3-10植物系统3.4动物系统想要养动物,并且收获动物产品,首要去商店购买动物幼崽,购买后商店会把动物幼崽放入栅栏里面。动物幼崽有两个属性:饥饿度以及成长度。随着时间的流逝,动物需要喂养饲料,不然会影响成长。在饲料方面,每种农作物都能作为普通饲料,每种动物都可以使用普通饲料和最佳饲料。但是每种动物的最佳饲料都不一样,喂养合适的饲料可以缩减动物的成长时间。到了动物成熟期以后,每种动物会产生不同的副产品:鸡产生鸡蛋,牛产生牛奶,羊产生羊毛。图3-11动物系统3.5工具系统在耕作农作物之前需要先将荒地开垦成耕土,然而荒地上的障碍物也是多种多样的,并且清除障碍物的难度也是不同的。开不同的垦障碍物也需要不同的开垦工具。开垦完荒地之后土地会变成耕地。如果想要在耕地上种植农作物,还需要先吧耕地浇水润湿。工具系统总共有五种工具:空手,镰刀,斧头,锤子,锄头,水壶。如果耕地不种植物,开垦好的田地又会重新变成荒地,需要重新开垦。荒地的类型总共有三种,杂草,石头,木桩。每种荒地都有小和大两种不同的程度。开垦每种不同的荒地需要不同的工具:杂草对应镰刀;斧头对应木桩;锤子对应石头。每种荒地都有耐久值,只有用工具不停的处理荒地,荒地才能减轻程度,最终变为空地。变成空地后需要用锄头耕耘才能变成耕地。变成耕地后种子还不能种下,需要用水壶去小河接水后湿润了耕地后才能种下种子。在使用工具的时候,如果使用错了工具,工具将会消耗耐久值,如果耐久值变成零了,就不能使用了,需要去商店修理才能继续使用。随着玩家经济实力的提升,玩家可以去商店用金钱升级工具。升级后的工具不仅耐久值会增加,提高容错率,还能提高生产效率。图3-12工具系统3.6商店系统商店是玩家获得初始生产材料,或者出售生产产品的平台。操作方法和背包系统一样,“W”“A”“S”“D”控制选择的物品,按“E”出售自己的农产品和动物产品。在商店里有许多可以购买的东西,如植物种子,动物幼崽,动物普通饲料。还能升级自己的工具,以及接取不同的订单任务。如果只是普通的购买种子,种成农作物,出售农作物的话,赚钱始终是不够快的。如果接取了订单,并且按照订单的要求生产农作物或者是动物产品的话,玩家将获得更多的收入。

图3-13商店系统

游戏功能实现4.1场景与素材加载4.1.1距离单位在游戏开始制作之前,首先要把自己精心准备的背景以及人物素材,人物动作素材,植物素材,动物素材,以及各种各样的房屋建筑和自然场景加载入项目之中。这些素材将作为游戏脚本的载体来使用,不然就算编写了脚本,也没有实现功能的载体。并且在编写脚本来实现各种功能之前,首先要考虑素材的基本属性,并贴合素材的状况来编写脚本,这样才保证素材能契合项目属性。图4-1网格纸4.2主角动作切换以及移动4.2.1动作切换主角有8个动作图片切换,在同个方向行走的时候动作会切换左右脚。通过wasd上下左箭头按键移动。先是实例动作图片入脚本。这里有两种方法:第一种方法:通过(GameObject)Resources.Load("prefab/");用名字查询。第二种方法:直接在脚本public对象,然后在引擎中拖入对象进脚本组件。图4-2载入游戏对象4.2.2监听键盘按键事件通过Input.GetKeyDown(KeyCode.S)实现。每个方向的移动就通过监听WASD按键来控制移动的方向。4.2.3人物的距离移动使用transform.Translate改变主角的位置。在移动之前,要先声明一个变量MoveSpeed,用来记录移动的距离。由于游戏是2d游戏,所以不用改变主角Z方向轴的的位移,只需要改变X,Y方向的位置。每当按下WS时使用transform.Translate(0,MoveSpeed,0);,按下AD时使用就可以transform.Translate(MoveSpeed,0,0);实现在XY方向轴上的位移了。由于摄像机是跟着主角移动的,只要把摄像机的初始位置和主角位置一样,然后把摄像机放进主角里面就可以实现摄像机跟着主角走了。4.2.4人物动作图片切换先统一把8张图片的Z位置调整到摄像机看不见的地方GameObject.transform.position.Z==101。在移动的时候每个方向的图片都有左右脚的变化,这样才会有走路的感觉。为了实现,使用了偶数的概念。需要声明一个int变量MoveNum,初始值为0,无论wasd按下,MoveNum都会加1。用来numdown%2确定单双数,结果为0时游戏中显示左脚图片,为1时使用右脚图片。改变图片位置先要初始所有图片Z位置,然后把对应图片的位置调到视野中。代码如下:if

(Input.GetKeyDown(KeyCode.S)

||

Input.GetKeyDown(KeyCode.DownArrow)){transform.Translate(0,

-1

*

MoveSpeed,0);numdown

=

numdown

+

1;switch

(yushudown){case

0:right1.z

=

right2.z

=

left2.z

=

left1.z

=

up1.z

=

up2.z

=

down1.z

=

down2.z

=

101;npc1right2.transform.localPosition

=

npc1right1.transform.localPosition

=npc1left2.transform.localPosition

=

npc1left1.transform.localPosition

=npc1up2.transform.localPosition

=

npc1up1.transform.localPosition

=npc1down2.transform.localPosition

=

npc1down1.transform.localPosition

=down2;down1.z

=

2;npc1down1.transform.localPosition

=

down1;break;case

1:right1.z

=

right2.z

=

left2.z

=

left1.z

=

up1.z

=

up2.z

=

down1.z

=

down2.z

=

101;npc1right2.transform.localPosition

=

npc1right1.transform.localPosition

=npc1left2.transform.localPosition

=

npc1left1.transform.localPosition

=npc1up2.transform.localPosition

=

npc1up1.transform.localPosition

=npc1down2.transform.localPosition

=

npc1down1.transform.localPosition

=down1;down2.z

=

2;npc1down2.transform.localPosition

=

down2;break;}}4.3场景互动与处理格4.3.1处理格主角无论怎么移动,正前方永远用来判断处理的事物对象。新建一个处理格对象point,在脚本中记录主角的位置,并且监听键盘事件,当按下WASD,先把处理格的位置初始为主角的位置,按键为WS,处理格的Y坐标加一或减一。按键为AD,处理格的X坐标加一或减一。代码如下:if

((Input.GetKeyDown(KeyCode.S)

||

Input.GetKeyDown(KeyCode.DownArrow))&&

panduanbag){point.transform.position

=

savepa;point.transform.Translate(0,

-1,

0);}if

((Input.GetKeyDown(KeyCode.W)

||

Input.GetKeyDown(KeyCode.UpArrow))&&

panduanbag){point.transform.position

=

savepa;point.transform.Translate(0,

+1,

0);}if

((Input.GetKeyDown(KeyCode.A)

||

Input.GetKeyDown(KeyCode.LeftArrow))&&

panduanbag){point.transform.position

=

savepa;point.transform.Translate(-1,

0,

0);}if

((Input.GetKeyDown(KeyCode.D)

||

Input.GetKeyDown(KeyCode.RightArrow))&&

panduanbag){point.transform.position

=

savepa;point.transform.Translate(+1,

0,

0);}4.3.2场景互动主角的场景事物互动基本都通过处理格来完成。与场景的互动有两种方式:一、记录处理格与场景事物的位置,当两者相同时处理格脚本中的对象即为该物体。二、碰撞实现判断物体。给处理格加上碰撞体组件和刚体组件,给场景中需要判断的事物加上碰撞体组件。处理格刚体组件的xyz都固定不能改变,以免在与物体相碰撞时导致处理格位置改变。在脚本中,先声明碰撞游戏对象duixiang,当处理格与物体在持续碰撞时OnCollisionEnter,处理格声明的碰撞判断对象即为该游戏对象,当结束碰撞OnCollisionExit,处理格中的碰撞判断对象需要被赋值空值NULL,以免在其他功能调用该判断碰撞对象时出现延迟或者是对象错误。代码如下:

void

OnCollisionStay(Collision

duixiang){peng

=

duixiang.gameObject;bepeng

=

peng;}void

OnCollisionExit(Collision

collision){peng

=

null;}4.4工具系统与障碍物清除4.4.1工具包UI工具包UI主要由3部分组成:一、工具框;二、选择框;三、工具图标。工具包一直停留于主角头顶,并且随着键盘按键触发而出现,并选择不同的工具,选择完后自动关闭工具包。先要实例化工具框和选择框,初始时工具框被隐藏SetActive(false)。记录下每个工具格的位置。当按下1234,选择框的位置会移动到对应各自工具的位置,并且将工具框重新显现SetActive(true)。if

(anxia6Down){heikuang.SetActive(true);baikuang.transform.localPosition

=

new

Vector3(0.90f,

0,

-0.1f);usinggongju.tag

=

shuih.tag;}if

(anxia1Up||

anxia2Up

||

anxia3Up

||

anxia4Up

||

anxia5Up

||

anxia6Up){heikuang.SetActive(false);}4.4.2障碍物的生成每天荒地上的障碍物类型都会随机刷新,除非你先给荒地种上农作物。障碍物类型主要有3种:木桩、杂草、石头。对应的工具类型为:斧头、镰刀、石头。每种障碍物都有两个程度的图形,当障碍物清除到一定程度后,障碍物会转化为轻程度的障碍物。每天随机生成障碍物使用函数Random.Range()。先建立一个长度为8的对象数组nongtianzhuangtai,并且把八个不同类型不同程度的障碍物实例进数组。随机生成的函数由(1,8)之中选择,随机到哪个数字,就生成哪个对应数字的障碍物。for

(int

i

=

0;

i

<

6;

++i){int

a

=

0;nongtianzhuangtai[i]

=

Random.Range(1,

7);a

=

nongtianzhuangtai[i];GameObject

xingtai=Instantiate(dixing[a],

tianoj[i].transform.position,

tianoj[i].transform.rotation);xingtai.transform.parent

=

tianoj[i].transform;}4.4.3障碍物的清理先需要建立6个标签,对应六个不同的工具。在工具包中选择哪种类型的工具,就把游戏对象处理格chulige的标签改为对应的标签。当处理格的位置接触到需要开垦的荒地,只有处理格的标签所代表的工具对应上相应的障碍物,荒地之后的判断才会继续进行。模拟开垦的过程,需要定义两个int类型用来存障碍物的耐久度,以及工具每一次开垦的程度。每一次开垦障碍物都会消耗障碍物的耐久度,当障碍物的耐久度下降到一定程度,障碍物会退化为更低一个程度的障碍物,当障碍物的耐久度为零,障碍物会消失。工具可以升级,总共有3个等级的工具。并且每次开垦会使障碍物消耗更多的耐久值。每一次的开垦都会使障碍物闪烁。在障碍物闪烁的过程中,需要增加限定条件,停止障碍物脚本的使用,防止系统报错。代码如下:if(Input.GetKeyDown(KeyCode.E)&&chulige.tag==

tianoj[i].transform.GetChild(1).tag){shake2

=

shake;saveb

=

i;savdishu[i]

=

savdishu[i]

-

wuqidengji;Invoke("move1",

0.2f);savec

=

i;}4.5背包功能实现4.5.1背包的开启以及位置处理背包由三部分组成:一、背包本体、二、选择框、三、背包图标。当背包开启时,摄像头画面将被背包覆盖,取消背包后才会恢复农场画面。这里使用了Input.GetKeyDown(KeyCode.X)作为背包的开启条件。每触发该按键事件之前背包处于z==10000的位置,当按下后背包处于z==2的位置,再触发一次按键事件,背包会重新回到z=10000的位置。实现只需要添加判断条件:当背包位置z为10000并且按下X就可以实现背包的开启,当背包位置z为2并且按下X就可以实现背包的关闭。代码如下:if

(Input.GetKeyDown(KeyCode.X)

&&

bag.transform.localPosition.z

==

10000)//按下X背包背包显示{Vector3

abc

=

bag.transform.localPosition;abc.z

=

1.6f;bag.transform.localPosition

=

abc;GameObject.Find("npcs1").GetComponent<johnmove>().enabled

=

false;//关闭人物行走功能return;}if

(Input.GetKeyDown(KeyCode.X)

&&

bag.transform.localPosition.z

==

1.6f){Vector3

abc

=

bag.transform.localPosition;abc.z

=

10000;bag.transform.localPosition

=

abc;GameObject.Find("npcs1").GetComponent<johnmove>().enabled

=

true;return;}4.5.2图标位置的建立背包设定为4*10的格子位置,通过建立一个长度为40的Vector3数组:格子位置组,用来记录每个格子的位置,然后通过循环给之后每个格子x轴方向增加相同的间距,格子每增加10,格子的y轴间距也相同增加。代码如下:float

a

=

0.4f;firpos[10]

=

new

Vector3(2.2f,

-0.1f,

-0.2f);for

(int

i

=

9;

i

>

-1;

i--){firpos[i]

=

firpos[i

+

1];firpos[i].x

=

firpos[i].x

-

a;}firpos[20]

=

new

Vector3(2.2f,

-0.5f,

-0.2f);for

(int

i

=

19;

i

>

9;

i--){firpos[i]

=

firpos[i

+

1];firpos[i].x

=

firpos[i].x

-

a;}firpos[30]

=

new

Vector3(2.2f,

-0.9f,

-0.2f);for

(int

i

=

29;

i

>

19;

i--){firpos[i]

=

firpos[i

+

1];firpos[i].x

=

firpos[i].x

-

a;}firpos[40]

=

new

Vector3(2.2f,

-1.3f,

-0.2f);for

(int

i

=

39;

i

>

29;

i--){firpos[i]

=

firpos[i

+

1];firpos[i].x

=

firpos[i].x

-

a;}4.5.3处理框的移动背包里通过按下wasd来控制处理框的移动,由于会与游戏场景中主角移动的按键相矛盾,会导致在处理框移动的时候,主角也会跟着移动,所以当背包开启时要关闭主角移动的脚本,当关闭背包时重新开启主角移动的脚本,通过查询对象,然后获取对象脚本组件来实现GameObject.Find("").GetComponent<>().enabled。定义一个int类型处理格位置编号savei用来存放处理格当前所在的格子位置,只要通过改变该对象数字,然后将处理框移动到该数字对象对应的格子位置,就能实现格子的移动。处理格的初始位置为格子的第一格,通过按键wasd可以移动到周围的格子。由于处理框移动会超出背包格子的范围,因此添加限定条件:当处理格位置编号小于10或大于29时处理格不能向上或向下移动,当处理格位置编号为0或39时不能向或左向右移动。代码如下:if

(Input.GetKeyDown(KeyCode.W)

&&

savei

>

9)//黑框移动限制,当在背包最上面的时候,不能往上;后面一样{savei

=

savei

-

10;Vector3

abc

=

firpos[savei];abc.y

=

abc.y

-

aaa;blackkuang.transform.localPosition

=

abc;return;}4.5.4背包图标的增加在脚本中声明一个公共字符串变量panduanduixiang,用来存所判断物品的名字。增加背包里的物体首先要在游戏场景中的物体做判断。当处理格碰撞到物体时,背包会获取处理格所碰撞物体的名字,然后根据名字从资源库中查询名字来添加物体,并且删除该碰撞体。建立一个游戏对象数组:图标组,用来存放所添加的对象cuncopy[],然后图标组里成员的位置与格子位置组一一对应,这样就实现了图标的增加。代码如下:GameObject

agc

=

(GameObject)Resources.Load("prefab/tubiao/"

+

panduanduixiang.GetComponent<cunnon>().names);cunchaxun

=

GameObject.Find("bag/"

+

panduanduixiang.GetComponent<cunnon>().names);//获取判断物体的名字,并且在背包找到对应名字的图标cuncopy[chuncopynum]

=

Instantiate(agc);//把相应图标放进背包cuncopy[chuncopynum].name

=

panduanduixiang.GetComponent<cunnon>().names;//图标的名字==物体的名字cuncopy[chuncopynum].transform.parent

=

bag.transform;//图标的父节点为背包cuncopy[chuncopynum].transform.localPosition

=

firpos[chuncopynum];//图标位置为对应序号格子的位置farmertext[chuncopynum]

=

Instantiate(firtext);//把文字放入图标中farmertext[chuncopynum].transform.parent

=

cuncopy[chuncopynum].transform;farmertext[chuncopynum].transform.position

=

cuncopy[chuncopynum].transform.position;ojnum[chuncopynum]

=

1;4.5.5背包图标堆叠以及数字显示添加图标的时候由于会有图标重复浪费背包空间的现象,为了避免该现象发生,需要将相同图标的物体做堆叠,以及显示堆叠的数目。在游戏场景中新增一个游戏对象firtext,该对象上增加一个文字组件。在脚本中新添一个长度为40的游戏对象数组:文字组farmertext[],用来存放图标的文字对象。以及新添一个长度为40的int数组:数字组ojnum[],用来存放图标的堆叠数字,初始值为0。在添加图标时,先查询背包的子节点里面有没有该图标对象,如果返回值为空,则在背包中添加该物体的新图标,并且给该图标子节点文字对象,在数字组中与该图标编号相同的数字对象值+1,然后文字组中相应的文字的显示为数字组中对应的数字。如果背包的字节点中存在与该物体相同的图标,则在数字组中获取对应该图标对象的数字,使其+1。代码如下:if

(cunchaxun

==

null)//检测背包里没有这个物体时{GameObject

agc

=

(GameObject)Resources.Load("prefab/tubiao/"

+

panduanduixiang.GetComponent<cunnon>().names);cuncopy[chuncopynum]

=

Instantiate(agc);//把相应图标放进背包cuncopy[chuncopynum].name

=

panduanduixiang.GetComponent<cunnon>().names;//图标的名字==物体的名字cuncopy[chuncopynum].transform.parent

=

bag.transform;//图标的父节点为背包cuncopy[chuncopynum].transform.localPosition

=

firpos[chuncopynum];//图标位置为对应序号格子的位置farmertext[chuncopynum]

=

Instantiate(firtext);//把文字放入图标中farmertext[chuncopynum].transform.parent

=

cuncopy[chuncopynum].transform;farmertext[chuncopynum].transform.position

=

cuncopy[chuncopynum].transform.position;ojnum[chuncopynum]

=

1;farmertext[chuncopynum].GetComponent<TextMesh>().text

=

ojnum[chuncopynum].ToString();chuncopynum++;Destroy(panduanduixiang);shopbagoj.transform.GetComponent<shopping>().shopgetbuything

=

false;if(shopbagoj.transform.GetComponent<shopping>().shopgetbuything){shopbagoj.transform.GetComponent<shopping>().shopgetbuything

=

false;}return;}else//背包里已经有物体了{int

abc

=

int.Parse(cunchaxun.transform.GetChild(0).GetComponent<TextMesh>().text);//abc++;cunchaxun.transform.GetChild(0).GetComponent<TextMesh>().text

=

abc.ToString();Destroy(panduanduixiang);if

(shopbagoj.transform.GetComponent<shopping>().shopgetbuything){shopbagoj.transform.GetComponent<shopping>().shopgetbuything

=

false;}return;}4.5.6背包物品的使用新声明游戏对象:使用的物品

handname。在移动选择框之后,如果选择框内的图标非空,监听键盘按键事件在按下E后,将使用的物品即为处理格位置编号所对应的图标。如果该图标的堆叠数字值大于1,该数字值减一;如果该图标的堆叠数字为1,删除该图标。代码如下:if

(Input.GetKeyDown(KeyCode.E)

&&

foodbag.transform.position.z

==

-0.5f)//在背包状态按下E,删除物品{int

abc

=

int.Parse(bag.transform.GetChild(savei

+

2).transform.GetChild(0).GetComponent<TextMesh>().text);abc--;string

sn

=

bag.transform.GetChild(savei

+

2).name;handname

=

sn;bsn

=

true;bag.transform.GetChild(savei

+

2).transform.GetChild(0).GetComponent<TextMesh>().text

=

abc.ToString();return;}由于删除该图标后,背包中被删除的图标所在的格子位置会空出来,所以要将删除图标后面的图标前进一位。新建一个循环,将图标组中编号大于删除图标编号的图标对象,位置新改为格子位置组中自身编号减一的格子位置。代码如下:if

(bag.transform.GetChild(savei

+

2).transform.GetChild(0).GetComponent<TextMesh>().text

==

"0")//当图标数目为0时删除图标,+2是因为背包原本有两个物体,图标是第3个开始{int

savds

=

savei

+

2;int

savech

=

childnum;GameObject

savdesto

=

bag.transform.GetChild(savei

+

2).gameObject;Destroy(savdesto);for

(int

v

=

savds

+

1;

v

<

savech;

v++){bag.transform.GetChild(v).transform.localPosition

=

firpos[v

-

3];//把删除后的图标位置前移一格}chuncopynum--;return;}4.6商店系统实现4.6.1商店系统的触发以及商店UI的位置改变将商店UI放入游戏场景中,初始z位置为10000。在游戏中的商店模型前新增一个带有碰撞体的空游戏对象shopoj,当主角走到商店前面,处理格接触到碰撞体之后,商店UI的Z位置移动到2.5,进入摄像机视野中。但是商店UI的位置要求比使用后的背包UI更后面,这样才能选择卖背包中的物品给商店。代码如下:if

(npc.transform.position.x

!=

shopoj.transform.position.x

||

npc.transform.position.y

!=

shopoj.transform.position.y)//没碰到商店

{

ExitK1

=

true;//商店没开启

}

if

(npc.transform.position.x

==

shopoj.transform.position.x

&&

npc.transform.position.y

==

shopoj.transform.position.y&&ExitK1)//人物碰到了商店

{

shopbag.transform.position

=

new

Vector3(shopbag.transform.position.x,

shopbag.transform.position.y,

2);

GameObject.Find("npcs1").GetComponent<johnmove>().enabled

=

false;

}

4.6.2商店系统的组成以及功能商店UI主要由6部分组成:一、商店UI贴图。包括商人头像贴图,欢迎语句,以及金币贴图。二、菜单。总共有种子、动物、工具、委托单、退出5个菜单。三、选择框。包括菜单选择框以及商品选择框。四、显示金币数。在商店中会实时显示你现存的金币以及你想买的商品的价格。4.6.3菜单选择的实现以及商品页面的切换由于菜单只有一行五个,所以移动菜单选择框只需要AD两个按键监听事件,定义一个int类型变量:当前菜单编号K1用来记录移动到哪个菜单,当按触发键盘AD按键事件,菜单编号就会增减,菜单选择框也会向左向右移动,所有的商品页面都会隐藏gameObject.SetActive(false);然后对应当前菜单编号的商品页面设置为显示gameObject.SetActive(true);。当菜单选择框移动到退出菜单时,商店UI退出摄像机视野,位置回到z==10000。由于选择框的移动会与游戏中主角的移动相矛盾,所以在开启商店时,主角的移动脚本将被关闭。代码如下:if

(Input.GetKeyDown(KeyCode.A)&&K1!=0&&

shopbag.transform.localPosition.z==4&&

DontUningShopLconthing)//按A键上一个菜单{K1--;Blackkuan1.transform.localPosition

=

ShopLconmenu[K1];}if

(Input.GetKeyDown(KeyCode.D)

&&

K1

!=

5

&&

shopbag.transform.localPosition.z

==

4&&

DontUningShopLconthing)//按D键下一个菜单{K1++;Blackkuan1.transform.localPosition

=

ShopLconmenu[K1];}if

(Input.GetKeyUp(KeyCode.S)&&

DontUningShopLconthing)//按S键转到商品栏{Blackkuan2.gameObject.SetActive(true);DontUningShopLconthing

=

false;K2

=

0;}if

(K1==5)//当选到第六个菜单退出商店UI{K1

=

0;Blackkuan1.transform.localPosition

=

ShopLconmenu[K1];ExitK1

=

false;shopbag.transform.position

=

new

Vector3(shopbag.transform.position.x,

shopbag.transform.position.y,

9998);GameObject.Find("npcs1").GetComponent<johnmove>().enabled

=

true;return;}4.6.4商品的选择在商品页面中,所有的格子位置和背包格子位置的设置方法一样,并在之后将所有商品的位置移动到对应编号的格子位置。商品选择框的初始状态设置为隐藏,当键盘监听事件S触发时,商品选择框将显示,并且将菜单选择框的移动功能关闭。商品选择框的移动功能也和背包系统中选择框的移动功能实现方法一样。代码如下:Blackkuan2.transform.localPosition

=

ShopLconthing[K2];

if

(Input.GetKeyDown(KeyCode.A)

&&

K2

!=

0

&&

shopbag.transform.localPosition.z

==

4&&bag.transform.position.z>10)

{

K2--;

Blackkuan2.transform.localPosition

=

ShopLconthing[K2];

}

if

(Input.GetKeyDown(KeyCode.D)

&&

K2

!=

19

&&

shopbag.transform.localPosition.z

==

4

&&

bag.transform.position.z

>

10)

{

K2++;

Blackkuan2.transform.localPosition

=

ShopLconthing[K2];

}

if

(Input.GetKeyUp(KeyCode.W)

&&

K2

>9

&&

shopbag.transform.localPosition.z

==

4

&&

bag.transform.position.z

>

10)

{

K2=K2-10;

Debug.Log(K2);

Blackkuan2.transform.localPosition

=

ShopLconthing[K2];

}

if

(Input.GetKeyDown(KeyCode.S)

&&

K2

<

10

&&

shopbag.transform.localPosition.z

==

4

&&

bag.transform.position.z

>

10)

{

K2

=

K2

+

10;

Blackkuan2.transform.localPosition

=

ShopLconthing[K2];

}

当商品选择框的位置移动到最上面一层的商品,此时再按W按键,菜单选择框的移动功能将重新开发,并且商品选择框的显示状态将关闭。代码如下:if

(Input.GetKeyDown(KeyCode.W)

&&

K2

<

10

&&

shopbag.transform.localPosition.z

==

4

&&

bag.transform.position.z

>

10){K2

=

0;Debug.Log(123123123);Blackkuan2.transform.localPosition

=

ShopLconthing[K2];Blackkuan2.gameObject.SetActive(false);DontUningShopLconthing

=

true;}4.6.5金币系统在背包与商店的交互中需要货币系统来实现物品交互。所有物品都要有价格,因此为所有物品添加脚本,在脚本中声明一个公共int变量buythingmoney存该物品的价格。在背包中新添一个公共int变量money用来存现存的金币数量。商店UI的显示金币模块脚本中引用背包中的现存金币数,并且获取子节点中的文字对象,将文字对象中的数字组件的值显示为现存金币数。当商品选择框移动到商品上面时,获取商品脚本中的金币变量,并同理显示到商品价格模块中。代码如下:图4-3物品价格属性int

buythingmoney=0;//获取商品价格buything

=

Blackkuan2.transform.GetComponent<shoppnegzhuang>().shoppeng;//商品选择框碰撞判断选择的商品if(Blackkuan2.transform.GetComponent<shoppnegzhuang>().shoppeng){buythingmoney

=

buything.transform.GetComponent<cunnon>().gold;//获取商品本身脚本的价格}4.6.6购买商品如果现存金币数大于商品价格,并且在商品选择框移动到商品上并且按下键盘按键E后,获取背包系统中的碰撞判断物体,并将该变量改为所选商品的名字。在背包脚本中复制添加脚本的函数,并且给该函数增加判断条件:当商店开启,并且按下按键E,这样之后就能把商品加入背包。并且将现存金币数减去商品的价格,文字组件重新显示。代码如下:GameObject

abc

=

Instantiate(buything);

=

;GameObject.Find("npcs1/Main

Camera").GetComponent<BAG>().panduanduixiang

=

abc;//把买了的商品改成背包栏中判断添加的对象shopgetbuything

=

true;Debug.Log("panduanduixiang:

"

+

GameObject.Find("npcs1/Main

Camera").GetComponent<BAG>().);Debug.Log("shopgetbuything"

+

shopgetbuything);weather.GetComponent<weather>().money

=

weather.GetComponent<weather>().money

-

buythingmoney;//减了商品价格后的钱4.6.7出售商品在商店开启的基础上,如果再开启背包就可以出售背包中的商品。由于要显示物品的价格,因此新建一个出售UI,用来显示背包图标的价格,出售UI的位置要求在背包位置的上面。在出售UI的脚本中,出售UI的初始位置为z==10000,如果商店系统和背包系统同时打开,出售UI的位置改为z==1.5。在背包中的图标选择框移动时,商店中的商品选择框和菜单选择框两者的移动函数关闭。在背包中,复制脚本的使用物品函数,限定条件改为商店开启,背包开启。销售结束后,将现存金币数加上商品的价格,文字组件重新显示。代码如下:if

(Input.GetKeyDown(KeyCode.E)

&&

shopbag.transform.position.z<10&&bag.transform.position.z<10)//在背包状态按下E,删除物品{int

abc

=

int.Parse(bag.transform.GetChild(savei

+

2).transform.GetChild(0).GetComponent<TextMesh>().text);abc--;string

sn

=

bag.transform.GetChild(savei

+

2).name;bsn

=

true;weatherth.transform.GetComponent<weather>().money

=

weatherth.transform.GetComponent<weather>().money

+

bag.transform.GetChild(savei

+

2).transform.GetComponent<cunnon>().gold;bag.transform.GetChild(savei

+

2).transform.GetChild(0).GetComponent<TextMesh>().text

=

abc.ToString();return;}4.7植物系统实现4.7.1时间系统在种下种子之后,该植物会随着天数的增加而慢慢成长。因此需要添加时间系统。在游戏场景的灯光对象中新添一个脚本,声明公共int对象:已过天数。已过天数初始值为一,并且随着限定事件发生,值+1。图4-4声明公共变量已过天数4.7.2种下种子复制背包的使用物品函数,给函数添加限定条件:使用的图标的标签为种子,主角处理格的判断对象为浇了水的耕地。此时按下按键E,公共字符串变量:判断对象即为使用的种子名字。在开垦浇过水的耕地新添脚本,声明字符串对象:使用的种子seed,如果背包的判断对象为湿润耕地自身,则引用背包的使用物体,赋值与使用种子名字,声明游戏对象:植株nowseed,然后从资源文件夹中查询使用种子名字所对应的种子,将其赋值于植株,并将植株于作为子节点,复制到湿润耕地中。因为出现了同一片湿润耕地可以同时种下多颗种子的情况,所以要在添加种子的函数中添加判断条件:湿润耕地自身的子节点数目为0。gameobject.transform.childCount<1。4.7.3种子的成长当种下了种子以后,种子会随着已过天数的增加而长大。因此在脚本中声明int类型变量:已有日期,初始值为0.声明int类型变量:出生日期,初始值为0。引用已过日期,当种子种下的时候出生日期被赋值于已过日期。已过日期减去出生日期的值赋值于已有日期。代码如下:string

hsname

=

"

";

hsname

=

GameObject.Find("npcs1/Main

Camera").GetComponent<BAG>().handseed;

seed

=

(GameObject)Resources.Load("prefab/planting/"

+

hsname);

dealweather

=

GameObject.Find("Directional

Light");

ae

=

dealweather.GetComponent<weather>().nowdaytime;

GameObject

panduanplant

=

seed;

nowseed

=

Instantiate(panduanplant);

nowseed.transform.parent

=

tuself.transform;

nowseed.transform.position

=

tuself.transform.position;

nowseed.transform.localPosition

=

new

Vector3(0,

0,

-0.1f);

danxiang

=

false;

4.7.4植物图片的改变植物的图片会随着已过日期的增加而改变,直至其成熟。在处理植物素材的时候,将对应植物素材的名字按照成长程度顺序排序,并将其名字改为:植物种子+数字顺序。在植物已有天数函数中,随着已有天数增加,声明一个字符串类型:植物名字,将植株的名字删除后两位字符串,然后加上已过天数,将其赋值于植物名字,之后从资源文件中查询植物名字对应的物体,将其赋值于植株,植株作为子节点复制进湿润土壤中。代码如下:if

(abc

<

5

&&

abc

!=

0)

{

Destroy(nowseed);

panduanplant

=

(GameObject)Resources.Load("prefab/planting/"

+

+

abc.ToString());

nowseed

=

Instantiate(panduanplant);

nowseed.transform.parent

=

tuself.transform;

nowseed.transform.position

=

tuself.transform.position;

nowseed.transform.localPosition

=

new

Vector3(0,

0,

-0.1f);

return;

}

4.7.5植物的成熟与收获当植物随着已过天数慢慢成长,终于成长成熟,成为农作物。在脚本中声明int类型:成熟所需天数。当已有天数等于成熟所需天数,则将植株字符串删去后4位,即为农作物的名字,删除植株,在资源文件中查询该名字所对应的物体,将其赋值于植株,然后将其作为子节点复制进湿润土壤中。为了将其收获入背包之中,需要主角的处理格能与该农作物作交互。因此需要给农作物加上碰撞体组件。由于湿润的耕地也有碰撞体,因此处理格所判断的对象会受湿润耕地的干扰。在丝润土地增加种子的脚本中,如果湿润耕地拥有子节点,则将湿润耕地的碰撞体组件关闭。如果湿润耕地没有子节点,则将湿润耕地的碰撞体组件重新打开。代码如下:Destroy(nowseed);

string

a

=

.Substring(0,

.Length

-

2);

panduanplant

=

(GameObject)Resources.Load("prefab/nongzuowu/"

+

a);

=

("冬瓜");

nowseed

=

Instantiate(panduanplant);

nowseed.transform.parent

=tuself.transform;

nowseed.transform.position

=

tuself.transform.position;

nowseed.transform.localPosition

=

new

Vector3(0,

0,

-0.1f);

ifend

=

false;

return;

4.8动物系统实现4.8.1动物的添加牧场总共有三个,用来培养不同的动物。在商店购买了动物之后,获取动物商品的名字,不需要通过背包,直接通过名字查询特定的牧场,然后把动物幼崽添加到牧场。先在牧场脚本声明公共int类型变量:当前的动物数量animalnum,初始值为0,当买了动物之后,获取该变量,使其+1。代码如下:if(K1==2)//当选了动物栏,并且买了动物。不用把商品加入背包,动物自动出现{string

abc

=

+

"zoo";GameObject.Find(abc).GetComponent<addanimal>().animalnum++;}4.8.2动物的加载牧场脚本声明一个int变量:牧场动物旧数量oldanumalnum,初始值为0。因为牧场的动物数量会动态增加,所以当前动物数量减去旧的动物数量就等于需要增加的动物数量。之后旧数量被赋予新数量的值。从资源文件里查询与动物名字相同的动物,作为子节点Instantiate增加入牧场对象。代码如下:if

(oldanumalnum

<

animalnum){for

(int

a

=

0;

a

<

animalnum

-

oldanumalnum;

oldanumalnum++){GameObject[]

savanimal

=

new

GameObject[animalnum];savanimal[oldanumalnum]

=

Instantiate(loadanimal);savanimal[oldanumalnum].transform.parent

=

zooself.transform;savanimal[oldanumalnum].transform.position

=

zooself.transform.position;Vector2

zs

=

new

Vector2(GameObject.Find("Directional

Light").GetComponent<weather>().nowdaytime,

0);}}4.8.3动物的随机移动在牧场里的动物会随机移动,但是动物又不会移动出栅栏在脚本中声明四个Int类型变量,用来记录栅栏中格子位置中X和Y最大值和最小值。由于动物随机会往上下左右四个方向移动,使用随机函数Random.Range(1,5);1到4代表四个方向。再随时记录牧场XY最大值最小值减去动物自身的坐标,就可以得到动物能移动的最大距离。再使用Random.Range(1,最大距离);就可以实现动物的随机移动。由于动物这样移动是改变位置,瞬间移动的,使用平滑阻尼Mathf.SmoothDamp()将动物追踪生成的坐标就可以实现平滑移动。代码如下:int

MaxX

=

11;int

MinX

=

4;int

MaxY

=

9;int

MinY

=

6;switch

(suijizb){case

1:float

a;Vector3

abc1=

chunzan.transform.position;a

=

chunzan.transform.position.x;a

=

Random.Range((int)animalOJ.transform.position.x,

MaxX

+

1);abc1.x

=

a;chunzan.transform.position

=

abc1;break;case

2:float

b;Vector3

abc2

=

chunzan.transform.position;b

=

chunzan.transform.position.x;b

=

Random.Range(MinX,

(int)animalOJ.transform.position.x

+

1);abc2.x

=

b;chunzan.transform.position

=

abc2;break;case

3:float

c;Vector3

abc3

=

chunzan.transform.position;c

=

chunzan.transform.position.y;c

=

Random.Range(MinY,

(int)animalOJ.transform.position.y

+

1);abc3.y

=

c;chunzan.transform.position

=

abc3;break;case

4:float

d;Vector3

abc4

=

chunzan.transform.position;d

=

chunzan.transform.position.y;d

=

Random.Range((int)animalOJ.transform.position.y,

MaxY

+

1);abc4.y

=

d;chunzan.transform.position

=

abc4;break;}4.8.4动物的成长在脚本中声明int类型变量:动物出生日期,在增加动物的时候,引用已过天数,赋值给出生日期。已过日期减去出生日期就等于动物成长天数。在动物脚本中定义动物成熟所需要的时间,当动物成长天数haveday等于动物成熟所需要的时间needday,删除该动物贴图,然后从资源文件中加载成熟期的动物图片。代码如下:if

(haveday

>=

needday

&&

firstonr){Destroy(animalOJ);chuntu

=

(GameObject)Resources.Load("prefab/animals/cow");animalOJ

=

Instantiate(chuntu);animalOJ.transform.parent

=

transform;animalOJ.transform.position

=

transform.position;firstonr

=

false;}4.9饲料系统实现随着天数增加,如果动物没用饲料食用,动物也不会成长的,如果有优质的饲料可以使动物生长时间缩短。为此需要新建一个饲料UI,显示所添加的饲料,和合成的普通饲料,以及优质饲料。4.9.1饲料槽UI以及位置饲料槽UI由3部分组成:一、UI框架;二、所添加的三种饲料格子;三、所合成的普通饲料和优质饲料的数目。在牧场门前设置碰撞体,当主角处理格碰撞到该碰撞体,饲料槽UI将显示在摄像机视野中,否则饲料槽UI的z位置为1000。4.9.2饲料槽饲料的添加在背包脚本中复制使用物体的函数,并添加限定条件:先当饲料槽UI显示,背包UI显示时,在背包使用的物体将为饲料槽中的饲料配方。在饲料槽脚本中,声明一个长度为3的字符串组:饲料槽组inst,用来存放所添加的饲料配方。声明一个int类型对象:当前饲料槽编号foodpsnownum,用来存放当前使用的饲料槽,初始值为0。获取背包中的饲料配方,根据名字从资源文件中加载相对应的物体,将其复制到饲料槽组中,当前饲料槽编号加1。当饲料槽编号为3,将饲料槽组清空,饲料槽编号为零。声明一个int类型变量:普通饲料数量ptsiliao,初始值为0。普通饲料数量加1。每种

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论