一个黑暗料理王皇冠配方的地方游戏是如何制作的

一个黑暗的房间安卓版|一个黑暗的房间下载(小黑屋)已汉化_乐游网安卓下载
安全的单机游戏下载大全
→ 一个黑暗的房间 (小黑屋)已汉化
《一个黑暗的房间》游戏截图
《一个黑暗的房间 A Dark Room》是一款来自非官方发布的汉化版本游戏,简体中文版,对于你来说可能带着冒险元素的探险,极简的风格,没有什么复杂的结构,基于浏览器的游戏,基本就是点击,建造于大量的阅读文字组合。【游戏介绍】一开始玩家会随机出现在一个屋子里。因为是,所以这些都是叙述给你听的,玩家必须在脑海里构想。之后会有一些抉择、购买东西或是建造。总的来说,大量的阅读,大量的构想和记忆。据说慢慢就会展现出一个庞大的世界。【游戏特点】醒了。头好痛。看不清周围。那生个火吧。-来自ADarkRoom官方发布的Android版本。-iOS上病毒式流行的作品。-来自一位热爱游戏的开发者。-无广告。-无内购。-不使用移动数据。-无怪异的权限请求。【游戏玩法】当你觉得跑酷、跳跃、RPG 什么的游戏种类都已经落入俗套时,不妨来试试别开生面的文字游戏。早在图形界面还稀少的时候,游戏就以文字的方式开始了。游戏名为黑暗屋,一开始玩家会随机出现在一个屋子里。因为是文字游戏,所以这些都是英文叙述给你听的,玩家必须在脑海里构想。之后会有一些抉择、购买东西或是建造。总的来说,大量的阅读,大量的构想和记忆。据说慢慢就会展现出一个庞大的世界。英语苦手估计是进不去了,超级 Nerdy 的人快上!话说,如果你老妈老爸每次都批评你游戏时间过长,相信在看见你玩这个的时候,保证玩多久都不会管你的!美区评价不错滴~
点击查看更多
特别说明:
一个黑暗的房间 (小黑屋)已汉化下载
地狱边境的广受关注,让黑白抽象画风的这类游戏走入玩家眼帘,这类游戏在画面上虽然略显粗糙,但一般在玩法
同类排行榜【图片】【评测】浅谈魂1魂3游戏设计。当我们玩黑魂,我们玩什么【黑暗之魂吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0可签7级以上的吧50个
本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:79,531贴子:
【评测】浅谈魂1魂3游戏设计。当我们玩黑魂,我们玩什么
最近楼主打完了魂3 5周目,然后又一边通关了魂1 2周目,感觉颇有些感慨。自己玩的过程中多多少少也是在细节上和整体上做了许多观察和对比,在这里希望能和各位爱好者一起分享一下自己对于这款游戏的一些肤浅的看法。lz是个原画,这篇文章主要从一些画面效果,气氛营造和游戏设计来谈。因为lz不是魂3白金党,也不是超细节的考据党,若有说的不是的地方还请各位指正。本文含有不少lz的主观观点,如果不同意还请当我是傻逼
免责声明写了一堆,现在开始正文。这篇文章主要是以魂1魂3的初版本进行对比,不包括后来的版本以及dlc。原因很简单,因为初版本没有针对客户反馈进行修改,今本上游戏里面的数值设置是制作组认为最合适自己想法的版本,除开游戏掉帧,优化等初版本的硬性bug之外,个人认为初版本最具有讨论游戏设计理念的价值
标题中也写到了,当我们玩黑魂的时候,我们玩什么。很多人都告诉我,是游戏充满的挑战性。是难度。这时候我想黑暗之魂是因为难所以才是个好游戏还是因为它本来就是一个很不错的游戏了,而因为它的挑战性使得游戏锦上添花呢?楼主带着这样的问题进行了思考。后来确实发现,单一的挑战性并不是黑魂真正好玩的原因。所以这就造成了魂3流程上面不足以打动玩家的因素。
那么魂1又怎么就比魂3的挑战性丰富了呢?很简单,是因为坑爹的地图。其实看看魂1的敌人设计,功能性比较多,层次很多样,但实际上每种敌人虽然有很多招式,但是难缠的程度远不如魂3.单兵作战能力魂3每个怪都堪称精英,无论是攻击频率还是攻击范围,要不是因为考虑难度调低了很多敌人的攻击欲望,削了很多敌人的韧性,不然魂3的敌人绝对是系列最具威胁的了。但实际上魂3光是杂兵设计上面就太偏向于“战斗”。就像最开始讲的,魂1的敌人层次感比较强,大多数敌人造型上面很夸张很丰富就不说了,多数敌人都有很强的功能性。比如判定诡异擅长远距离的树精,能够限制人行动的石巨人,注重弹反背刺的盗贼,会出血的狗,会喷火的剧毒囊包怪,会腐蚀武器的大虫子。。。。等等。敌人也大多数有着debuff和投技两种技能。而像最开始所说的黑魂1难的不是杂兵,特别1周目时候,lz随便加点,流程如同砍瓜切菜,但是要说通过一个地点,还是有着相当的难度。
这就是地图的挑战性。魂3的boss设计非常出彩,比起魂1实在是好了不知道多少个档次。但是呢,玩家打流程对于地图没有什么探索感和印象,因为全部的精力都放在如何战胜那些强力的敌人和强力的boss上面了。当玩家通过了一个区域,玩家会告诉自己,哇!我终于打败了这里的boss!而不是哇!我终于通过了这个关卡。而魂1在很多地方都有着这样的关卡,比如古城的滚石,以及最后一组斧头,扔炸药的巨人,王城双弓,巨人墓地,结晶洞穴,绘画天顶,病村木桥,吹箫哥。地图折磨人的地方多数时候是摔死,但也不乏狭窄的场景让玩家苦恼的无法发挥实力。(魂1初版弹刀判定及其严格)又或者怪物的配置和debuff造成的双重压力。
那么为什么会出现这种情况呢?是制作理念的不同。魂1很明显是不想做成一个线性游戏的。而是希望做成一个大型网游,总之就是造出一个大的世界,让玩家在这个开放世界里面游玩。包括剧情什么的都很零散,剧情也大多数时候只是随便交代,主要还是为了游戏场景和怪物设计来服务。说的直观点,魂1更像是黑暗版的怪物猎人。很多敌人都会掉落素材,而初版本像恶魔楔形石,光辉楔形石这样的东西是根本买不到的。那怎么办?刷呗。其实魂1就是有那种破坏神的影子。就是要你刷。特别是掉落绿花草的红色小青蛙,以及各种苔藓球得树精,说白了黑森林,什么是黑森林?就是大家上山采蘑菇的地方。而各种黑骑士爆各种楔形石块这一点,深渊骑士爆圆盘和普通楔形石块,图书馆章鱼蛇爆人性这一点,都是凸显大菠萝类RPG的本质,刷。这也不得不提到为什么魂1有这么多稀奇古怪的怪物,而魂3则都是以人为基本变形出来的一些东西,大多数都是骑士呢。很简单,就是为了丰富这个刷刷刷的rpg世界。感觉上制作团队的目标不是在作一款独立于其他游戏的叫做黑暗之魂的游戏,而是想做一款类似于怪物猎人的开放式探索世界游戏。按照宫崎的标准来看,魂3比起魂1其实更加的黑魂
上面的刷刷刷无形增加了地图的时间和体验感,实际上这就和攻关没什么关系了,因为玩家是为了攻关另一个区域,而在这个区域刷,实际上这个区域刷出来的东西在这个区域内用处并不算明显。那么就有了第二个命题,跑图。魂1跑图是出了名的,无非就是一直被吹上天的地图设计。但不得不说他的处理方式确实要好过魂3.这和跑图有什么关系呢?因为魂1的篝火一开始不能传送就算了,而且还非常少(初版本有了王器也只能传几个关键篝火ps:公爵图书馆不能传要是断白龙尾被诅咒了超级呵呵),最主要制作人并不是像忍者龙剑传或者其他的动作游戏那样,在一个比较难的“战点”之后设计一个存档点,而是在一个大区域内的几个隔得很远的关键地点设置。可以说篝火与篝火之间有无数个这样的“战点”。从病村上面下来,以及整个小隆德遗迹,整个古城,整个结晶洞穴,整个巨人墓地整个王城也就仨篝火,还有一个是打完boss爆的。为了让玩家跑得“方便”一点,于是便有了神乎其神的捷径设计。同时这也很好的起到了营造罗德兰世界的作用。那么为什么魂3捷径更多,地图结构更复杂却不让人津津乐道呢?有下面这些原因
1:捷径的跨区域性。魂1捷径大多数跨区域连接所以捷径究竟连接到了哪里是玩家很难脑补的,所以总是能给玩家带来惊喜。类似于飞龙之谷,夹缝森林这种基本上没什么面积感的区域,与其说是一张完整的图倒不如说是一条稍微大一点的捷径。这也就带来了第二个优点2:捷径的多样性。魂1的捷径不限制于电梯和不能从这一侧打开的门。这种捷径用辟谷想都知道是从哪里通向哪里,开了之后会怎样,甚至在打开之前就知道待会儿可以从这里回来毫无惊喜感。然而魂3有很多这样的重复设计。3:捷径的必要性。魂1大多数捷径实用性太强了,如果不开这个捷径基本上很难继续往下玩。因为一旦中途失败,又得重新攻关。这很是脑热。但魂3不一样,基本上都是可开可不开的。毕竟篝火太多,篝火本身就算一种捷径了,从篝火到篝火,之间有再多捷径都无所谓,莽死所有杂兵,元素瓶还有剩的,根本没有开启捷径的意义。自然,地图设计的再复杂再巧妙,也丧失了它本来设计的初衷。这也是为什么像幽邃教堂这样的图能在魂3给人留下深刻印象的原因了。
那么前面说了这么多魂1的理念,实际上不难看出,魂1算不上真正的“黑魂”,而只是一个充满实验性质的半成品。但很多时候正是因为这些误打误撞甚至于违背优秀游戏设计理念的东西造就了魂1.按照游戏设计规则来讲魂1和恶魂绝对算不上一款入流的游戏。特别是发霉通给恶魂的评价直到现在来看也非常中肯。而后来迫于舆论,魂1还是妥协了。而这样一款误打误撞的作品最后成为了殿堂级还拿下了年度RPG,也算是FS魂系列团队强运了。反观魂3,不管是在游戏难度上还是剧情又或者场景设计都更加的用心了,更加符合现在游戏的标准。也更加像是宫崎想要讲述的黑魂。剧情主线更加清晰,因为剧本更严谨,也更有逻辑,npc之间也不再支离破碎胡乱拼凑,而是有意识的去讲一个末世的人情关系。BOSS和场景设计也是为了剧情而服务,包括活祭品之路等等各种线都能不假思索的串联起来。而游戏体验上也是强调了战斗,取消了解密(魂1古城各种解密要素。贪婪金蛇,杀人电梯,罗根)以及场景的变化魄力(小隆德放水和法兰要塞灭烽火没法比),总的来说是让玩家玩起来很舒服的一款游戏。最重要的,是它没了有刷刷刷的基本概念,所以也不需要跑图或者构架一个完整的世界,只需要玩家跟着剧情线路一步步深入就可以了。所以玩家只需要把精力放在战胜杂兵和boss上面,一路往下走,而不需要去用心体验游戏世界,魂1更像rpg更开放,而魂3更像一款线性动作游戏。
1:景深。先科普一下什么是景深。简单点说就是你盯着一个东西看,(聚焦)这个东西会很清晰,而它周围的或者远处的景物会很模糊。游戏中应用这一点可以让画面主动聚焦,突出近景的细节和表现力1代的景深效果非常牛逼。要想明显体验的话可以去绘画世界大门外,往BOSS长廊哪里看,走进去之后(大概到大门内斯巴达的位置)有非常舒服的变化,对于氛围营造效果十分明显
2:视觉效果人从弱光环境进入强光环境或者在弱光环境下观察强光因为虹膜不能够及时调节,会形成一个变化的炫光效果。这一点1代引擎甚至超越了三。这个效果是1代最牛逼的。类似于使命召唤,GTA这样的高级画面效果的引擎才会用得到这种效果。而因为魂1黑暗场景和光明场景的剧变很多,所以一旦用到这个效果就非常的赞,对于氛围营造很有帮助。想要明显体验建议去魂1公爵图书馆牢房大门那一块,一直盯着远处的结晶山,从门内到门外有非常明显的变化。这个效果也造成了白龙希斯的雾门变成了黑色。
3:光影效果黑暗之魂1能见度不到10m有些地方甚至更短。甚至就算游戏内部设置和屏幕设置调到最亮也是一片漆黑什么都看不见,是一种非常不自然的光照效果(详见病村以及各种洞穴)。而主角的自发光却能高度照亮自己和周围的一些范围。大家想一想这是一个什么情况。是不是和寂静岭三里面主角身上挂着一个便携手电的效果一样?对。这是气氛营造的关键,不是通过滤镜和雾气就可以解决的。原因有以下1:看不清地图,增加了神秘感,降低了辨识度,理解其地图构造更加困难,从而觉得地图复杂,而且也提高了难度2:远处的敌人若隐若现,只能看到剪影,不能用模糊视觉观察敌人的动作,从而增加紧张感,加大游戏难度3:敌人从黑暗中出现,主角的光照效果照在敌人身上,恐怖演出满分,十分有惊悚感(3代类似有霸王沃尼尔),而且增加了突然出现的吓人效果,这很黑魂
总的来说类似于3代那种高级的环境光遮蔽,动态光影,以及自然光照的效果反而不适合黑魂。而且最主要的是,因为光效高级了,各种反射漫反射使得该黑暗的场景一点都不够黑,火把根本失去了存在的意义,也是个十分脑残的设计4:音效魂1的音效没有魂3做的细做得多,但是有一点特别牛逼就是只要场景进入狭小或者密闭的空间,就会有回音效果,整个室内的清晰感非常棒。而室外和环境音乐扩充开来把夸阔场景的那种距离感表现的很出色。这一点不需要金耳朵,魂1地图随便实验。都很明显
然而魂1除非复刻不然并没有玩的欲望
就打白龙那,帧数突然下滑
魂3的场景都这么亮 要比就那血源来比啊
魂3感觉最失败是地图啊
除了打boss
地图没有啥探索性
跑了几次就腻了
魂3地图 真是有够腻的!还不如魂2的丰富
感觉魂3篝火比2代的间隔还小莽完一波找到篝火,原素瓶都没用完
魂3优点也不少,地图也确实大,但探索乐趣少的可怜,,鸡肋的设计也不少,老玩家带着魂1的探索欲玩的话明显会失望很多,光影、景深上赞同楼主,魂1的略带着一种朦胧感,烘托场景或营造气氛,感觉更贴切和舒服
1代世界观和整体系统都做得不错,但是一些小系统却让玩家非常着急;3代虽然把这些小系统优化完善了,但是却少了些耐人寻味的东西
所以我觉得黑魂其实可以尝试一下多周目游戏一周目走魂1风格二周目在玩家对地图熟悉的情况下,把怪的AI调高到魂3的程度,然后再添加一些二周目才有的道具三周目在二周目的基础上,把怪的数量增加到魂2的程度,增加三周目才有的BOSS
还是先期待魂1能否重置,不过目前魂1也还是很好玩的了
魂3怪物設計難聽點就是單調了, 就色調而言也是一片&灰&, 例如蛇人和飛龍~
贴吧热议榜
使用签名档&&
保存至快速回贴&&&&&&&&&&&&黑暗之光RPG游戏制作
嗯,这里我将给大家介绍一个很经典的RPG类型游戏的制作,嗯,这里说一下这个是个半成品文档,,不包括敌人制作和升级系统的
1.场景的铺设,灯光的添加和鼠标的设置
首先,我们将地图拖拽的到当前游戏场景并且保存定位start
然后我们添加一个directLight作为场景的光照,这里光照由大家挑选自己喜欢的即可
在bulid&setting里有个projectSetting,在这里我们将鼠标的图标设置为GUI里的mouse_normal,这样在游戏里图标就会切换成合适的图标了
2.添加天空盒子和水资源
这里用的是unity自带的天空盒子和水资源
1,我们导入水资源和天空盒子
2,将水面平铺整个场景,再通过调整高度让它覆盖河流
3,在MainCamera里加入天空盒子并且导入刚刚引进的素材即可
3.摄像机的缓慢移动和雾的添加
摄像机的移动很简单,设置好位置以后用transform.translate即可控制移动,当然我这里还使用了一个Mathf.Lerp的方法控制,大家选择比较合适的使用,这里雾的添加只需要在edit下render
Setting下的fog勾选上即可
MovieCamera :
MonoBehaviour {
float moveSpeed = 10;
float EndZ = -20;
// Use this for initialization
void Start () {
// Update is called once per frame
void Update () {
//float newZ= Mathf.Lerp(transform.position.z,EndZ, Time.deltaTime * moveSpeed);
//transform.position = newVector3(transform.position.x,transform.position.y,newZ);
if(transform.position.z&EndZ)
transform.Translate(Vector3.forward
* moveSpeed* Time.deltaTime);
4.给初始界面添加个UGUI的切换动画
这里我们希望开始游戏时候能做到由白色屏幕渐渐演变进游戏,因此,我们要加上这样的控制
1,导入NGUi和title两个素材包
2,点开NGUi下的PrefabToolBar并且将其中的backGround拖到视图层
3,切换到移动视角,添加simpleTexture将其设置为WhiteScreen并且点击snap还原图片大小
4,保证图片能够覆盖整个游戏屏幕,添加上AlPhaTween设置延时一秒逐渐从1到0
5,这样,我们渐变的效果就实现了
5.UI界面的一些基础设置
因为UI搭建大多就是图片拼凑,所以这里我讲几个要点
1.我们在NGUI下open一个Atlas并且将所需title素材拖进去做成一个图集,这样方便调用
2.我们拖拽PressAnyKey时候可以将动画显示方式设置为Ping-Pone,这样就可以实现闪烁的效果
3.我们需要NewGame和LoadGame同时显示,因此我们在NGUI下创建一个widget并且将它们都设置为widget的子物体,添加上BoxCollider和UIButton控制点击和图标的变化
6.添加事件,当点击屏幕时候弹出newGame和LoadGame
我们在pressAnyKey下添加这样的脚本
这里逻辑两步
1我们获取到buttonContiner,加上一个Bool值来判断是否点击,input中有个事件
控制当点击时候就会触发的输出
2.我们新建一个方法,通过setActive的方法可以设置显示,当然这里也要将bool值设置成true防止事件反复执行
PressAnyKey :
MonoBehaviour {
bool isAnyKeyDown =
GameObject buttonC
// Use this for initialization
void Start () {
buttonContainer = this.transform.parent.Find(&Container&).gameO
// Update is called once per frame
void Update () {
if (isAnyKeyDown ==
&&&&&&&&&&&
if (Input.anyKeyDown)
&&&&&&&&&&&
&&&&&&&&&&&&&&&
ShowButton();
&&&&&&&&&&&
void ShowButton()
buttonContainer.SetActive(true);
&this.gameObject.SetActive(false);
isAnyKeyDown = true;
7.添加背景声音和按键声音1
在MainCamera上添加auidoSource组件,在newGame和loadGmae上添加UIPlay并且指定声音,即可添加上游戏声效了.
8.创建角色选择场景
这里就单纯是一些Ui的堆砌,没什么好说的,因为角色选择和游戏场景是一样的,因此我们只要复制上个场景即可
9.实现角色的选择功能
将两个角色剑士和魔法师做成prefab,然后我们用脚本来控制它们的生成
1.创建一个GameObject命名为CharacterController,并且将它的位置设置到召唤盘上
2.书写脚本
我们用prefabs数组来存放模型,Controller来进行控制
1.我们在strat里进行初始化并且将prefabs里的模型赋值给控制器
2.创建一个方法来控制模型的显示和隐藏
3.书写两个方法来控制按钮点击后的事件,当前显示的模型由characterIndex决定
4.将物体赋值给两个按钮的点击,然后选择相对应的方法
3.using UnityE
4.using System.C
CharacterCreation :
MonoBehaviour {
7.&&&&public
GameObject[] characterP
8.&&&&private
GameObject[] characterC
9.&&&&private
int characterIndex = 0;
10.&&&&private
int length = 0;
Use this for initialization
12.&&&&void
14.&&&&&&&&length = characterPrefabs.L
15.&&&&&&&&characterController =
GameObject[length];
16.&&&&&&&&for
(int i = 0; i & i++)
17.&&&&&&&&{
18.&&&&&&&&&&&&characterController[i] =
GameObject.Instantiate(characterPrefabs[i],transform.position,
transform.rotation) as
GameObject;//在当前未知
20.&&&&&&&&}
21.&&&&&&&&CharacterShow();
Update is called once per frame
25.&&&&void
CharacterShow()
27.&&&&&&&&characterController[characterIndex].SetActive(true);
28.&&&&&&&&for
(int i = 0; i & i++)
29.&&&&&&&&{
30.&&&&&&&&&&&&if
(i != characterIndex)
31.&&&&&&&&&&&&{
32.&&&&&&&&&&&&&&&&characterController[i].SetActive(false);
33.&&&&&&&&&&&&}
35.&&&&&&&&}
38.&&&&public
void NextChooseButton()
40.&&&&&&&&characterIndex++;
41.&&&&&&&&characterIndex %=//这样可以自我实现循环
42.&&&&&&&&CharacterShow();
46.&&&public&
void PreChooseButton()
48.&&&&&&&&characterIndex--;
49.&&&&&&&&if
(characterIndex == -1)
50.&&&&&&&&{
51.&&&&&&&&&&&&characterIndex = length - 1;
52.&&&&&&&&}
53.&&&&&&&&CharacterShow();
10.处理名字和选择角色的存储
这里就是获取到主角设置的信息和输入的主角名,并且进行存储,方便以后调用
这里获取到UI组件,然后通过setInt和setString来存储角色信息
UIInput nameI
void OnOkButtonClick()
PlayerPrefs.SetInt(&characterInt&,
characterIndex);//存储选择德角色
PlayerPrefs.SetString(&nameInput&,
nameInput.value);//存储角色德名字
11.制作鼠标点击后的特效
这里判断鼠标点击的位置我们采用的是射线检测的方法
首先是camera下有一个点击目标位置会发射一条射线的方法
1.我们保存这条射线
2.RayCastHIt来保存碰撞的信息
3.boolIsCollider来判断是否碰撞到地面,用的是Physics下的RayCast方法
4.我们创建一个方法来实例化特效,实例化的位置就是鼠标点击的位置
CharacterDir :
MonoBehaviour {
//这个是控制实例化点击出现点击特效的
GameObject EffectP
// Use this for initialization
void Start () {
// Update is called once per frame
void Update () {
//我们检测用到的是碰撞检测
if (Input.GetMouseButtonDown(0))
&&&&&&&&&&&
//当鼠标左键按下时
&&&&&&&&&&&
Camera.main.ScreenPointToRay(Input.mousePosition);//这里获取到鼠标点击位置的射线
&&&&&&&&&&&
RaycastHit//保存的是碰撞信息
&&&&&&&&&&&
bool isCollider =
Physics.Raycast(ray,
out hitinfo);//用来判断是否碰撞
&&&&&&&&&&&
if (isCollider && hitinfo.collider.tag
== Tags.ground)
&&&&&&&&&&&
&&&&&&&&&&&&&&&
ShowEffect(hitinfo.point);//在射线碰撞到的位置实例化
&&&&&&&&&&&
void ShowEffect(Vector3
showPosition)
showPosition = new
Vector3(showPosition.x, showPosition.y
+ 0.1f, showPosition.z);
GameObject.Instantiate(EffectPref,
showPosition, Quaternion.identity);//实例化目标
12.控制主角的朝向
这里我们首先要判断主角是否移动,我们判断移动的方法是鼠标是否点下来设置主角朝向的true和false,
1.我们将射线碰撞的位置设置给targetPos
2.我们用transform.lookAt改变主角朝向,但是我们不改变y轴
3.在点击和isMoving两种方法里调用playerLookAt方法
CharacterDir :
MonoBehaviour {
//这个是控制实例化点击出现点击特效的
GameObject EffectP
bool isMoving=false;
Vector3 targetPos=Vector3.
// Use this for initialization
void Start () {
// Update is called once per frame
void Update () {
//我们检测用到的是碰撞检测
if (Input.GetMouseButtonDown(0))
&&&&&&&&&&&
//当鼠标左键按下时
&&&&&&&&&&&
Camera.main.ScreenPointToRay(Input.mousePosition);//这里获取到鼠标点击位置的射线
&&&&&&&&&&&
RaycastHit hitI//保存的是碰撞信息
&&&&&&&&&&&
bool isCollider =
Physics.Raycast(ray,
out hitInfo);//用来判断是否碰撞
&&&&&&&&&&&
if (isCollider && hitInfo.collider.tag
== Tags.ground)
&&&&&&&&&&&
&&&&&&&&&&&&&&&
ShowEffect(hitInfo.point);//在射线碰撞到的位置实例化
&&&&&&&&&&&&&&&
isMoving = true;
&&&&&&&&&&&&&&&
PlayerDir(hitInfo.point);
&&&&&&&&&&&
if (Input.GetMouseButtonUp(0))
&&&&&&&&&&&
isMoving = false;
if (isMoving)
&&&&&&&&&&&
Camera.main.ScreenPointToRay(Input.mousePosition);//这里获取到鼠标点击位置的射线
&&&&&&&&&&&
RaycastHit hitI//保存的是碰撞信息
&&&&&&&&&&&
bool isCollider =
Physics.Raycast(ray,
out hitInfo);//用来判断是否碰撞
&&&&&&&&&&&
if (isCollider && hitInfo.collider.tag
== Tags.ground)
&&&&&&&&&&&
&&&&&&&&&&&&&&&
isMoving = true;
&&&&&&&&&&&
&&&&&&&&&&&
PlayerDir(hitInfo.point);
void ShowEffect(Vector3
showPosition)
showPosition = new
Vector3(showPosition.x, showPosition.y
+ 0.1f, showPosition.z);
GameObject.Instantiate(EffectPref,
showPosition, Quaternion.identity);//实例化目标
//控制主角的朝向
void PlayerDir(Vector3
targetPos = hitP
targetPos = new
Vector3(targetPos.x, transform.position.y,
targetPos.z);//我们控制的是x和z的变化,y不变
transform.LookAt(targetPos);
13.控制主角的移动
这里我们希望主角移动到鼠标的目标位置,因此我们新建一个脚本叫playerMove来管理主角移动
1.我们要获取playerDir里的tarPos并且给魔法师添加CharacterController来控制移动
2.我们计算两者间的距离,通过CharacterController下的SimpleMove来控制移动
CharacterMove :
MonoBehaviour {
CharacterDir charD
float speed = 1;
CharacterController
// Use this for initialization
void Start () {
charDir = this.GetComponent&CharacterDir&();
controller = this.GetComponent&CharacterController&();
// Update is called once per frame
void Update () {
float distance =
Vector3.Distance(charDir.targetPos,
transform.position);
if (distance &0.1f)
&&&&&&&&&&&controller.SimpleMove(transform.forward * speed);
14.控制移动动画的播放
我们移动的时候肯定不能是平移的,因此我们要用动画来控制角色的移动
1.我们新建一个脚本叫PlayerAnimation
2.我们修改PlayerMove,给它添加一个动画状态,在不同状态时候调用不同动画
3.Animation下有一个crossFade的方法可以通过获取动画的名字来播放动画,这里我们获取到playerMove下的状态,在不同状态下播放相应的动画即可实现效果
PlayerState
Update () {
float distance =
Vector3.Distance(charDir.targetPos,
transform.position);
if (distance &0.1f)
&&&&&&&&&&&controller.SimpleMove(transform.forward * speed);
&&&&&&&&&&&
state = PlayerState.M
&&&&&&&&&&&
state = PlayerState.I
4.修改Animation脚本
CharacterAnimation :
MonoBehaviour {
9.&&&&private
CharacterMove charM
Use this for initialization
Start () {
12.&&&&&&&&charMove =
this.GetComponent&CharacterMove&();
Update is called once per frame
LateUpdate () {
18.&&&&&&&&if
(charMove.state == PlayerState.Move)
19.&&&&&&&&{
20.&&&&&&&&&&&&PlayAnim(&Run&);
21.&&&&&&&&}else
if (charMove.state ==
PlayerState.Idle)
22.&&&&&&&&{
23.&&&&&&&&&&&&PlayAnim(&Idle&);
24.&&&&&&&&}
30.&&&&void
PlayAnim(string animName)
32.&&&&&&&&animation.CrossFade(animName);
15.完善主角的移动
1之前的移动有一个bug,就是当我们控制移动的时候,会导致鼠标停止点击的时候,人物还会持续往那个方向移动,这是因为playerMove中当我们修改方向时,动画的播放判断会一直因为大于0,1而一直播放移动动画,因此我们在脚本里加入isMoving,状态改变时分为true和flase
3.我们将isMoving设置给dir,当判断鼠标松开且不再移动时,我们会判断此时是否正在走,如果在走,就会实时更新朝向
16.实现摄像机的跟随
1.我们新建一个followPlayer的脚本,挂在摄像机下
2.我们持有一下player的position。
3.我们让摄像机看向主角并且计算一下当前摄像机和主角的位置偏差
4.在update里实时保持两者的offset
camerMove :
MonoBehaviour {
9.&&&&private
Use this for initialization
11.&&&&//我们通过计算偏差来实现照相机的跟随
12.&&&&private
Start () {
14.&&&&&&&&player =
GameObject.FindGameObjectWithTag(Tags.player).
15.&&&&&&&&transform.LookAt(player.position);
16.&&&&&&&&offset = transform.position -player.
Update is called once per frame
Update () {
21.&&&&&&&&transform.position = offset +player.//保持偏移的大小
17.鼠标滚轮实现镜头的拉近和拉远
这里我们用input,getAxis即可获得鼠标是否按下滚轮,这里返回是个-1到1的值,这样我们就可以通过返回值决定镜头与主角间的距离,然后再把距离重新赋值给两者偏移即可
ScrollView()
20.&&&&&&&&//Input.GetAxis(&Mouse
ScrollWheel&)获得是一个负值到正值的变换,我们获取到滚轮的变化,在当前偏移上做出改变即可实现镜头拉远和拉近
21.&&&&&&&&&distance = offset.&&&&
22.&&&&&&&&&&&&distance +=
Input.GetAxis(&MouseScrollWheel&)
23.&&&&&&&&&&&offset = offset.normalized *
24.&&&&&&&&
18.鼠标右键控制镜头的旋转
我们判断鼠标右键是否按下来决定是否旋转,而旋转用的是Transfom.RotateAround这个方法,我们获取到鼠标在x轴的偏移,向左为负,向右为正数,这样来决定我们旋转的角度是正还是负,然后我们设置完成后要重新设置主角朝向和镜头朝向一致
void RotateCamera()
//用鼠标右键控制视野旋转
if (Input.GetMouseButtonDown(1)){
&&&&&&&&&&&
isRotating = true;
if (Input.GetMouseButtonUp(1))
&&&&&&&&&&&
isRotating = false;
if (isRotating)
&&&&&&&&&&&transform.RotateAround(player.position,
Vector3.up, rotateSpeed*Input.GetAxis(&Mouse
offset = transform.position -player.//这里当摄像机发生旋转时,偏移也会发生改变,我们要重新设置偏移
19.控制视野的上下旋转并且控制它的范围
1.我们要摄像机的上下旋转需要摄像机围绕自身的右方进行上下旋转,获得的是鼠标在y轴的移动
transform.RotateAround(player.position,transform.right, rotateSpeed *
Input.GetAxis(&Mouse
2.我们要控制旋转的范围,每次旋转前保存当前位置,如果x轴上的偏移超出我们的设置范围,我们则将位置设置成最后一次能正常移动范围的位置
RotateCamera()
//用鼠标右键控制视野旋转
if (Input.GetMouseButtonDown(1)){
&&&&&&&&&&&
isRotating = true;
if (Input.GetMouseButtonUp(1))
&&&&&&&&&&&
isRotating = false;
if (isRotating)
&&&&&&&&&&&
Vector3 originalPos
= transform.
&&&&&&&&&&&
Quaternion originalRotation
= transform.
&&&&&&&&&&&transform.RotateAround(player.position, player.up, rotateSpeed*Input.GetAxis(&Mouse
&&&&&&&&&&&transform.RotateAround(player.position, transform.right, rotateSpeed
* Input.GetAxis(&Mouse
Y&));//围绕角色的右边进行旋转
&&&&&&&&&&&
float x = transform.eulerAngles.x;
&&&&&&&&&&&
if (x & 10 || x & 80)
&&&&&&&&&&&
&&&&&&&&&&&&&&&
transform.position =originalP
&&&&&&&&&&&&&&&
transform.rotation =originalR
&&&&&&&&&&&
&&&&&&&&&&
offset = transform.position -player.//这里当摄像机发生旋转时,偏移也会发生改变,我们要重新设置偏移
20,设计任务的界面
导入menu素材,添加上boxCollider和TweenPosion,设置好出现的动画,即可完成任务栏的创建,这里主要是一些UI的堆砌,没啥讲的,就是有一点,当我们移动时候,不想在任务出现时接着移动,在判断鼠标左键点击移动的条件上再加一个判断UICamera.hoverObject==null
21.对话框的显示和隐藏
这里讲一下逻辑
1.获取到TweenPosition这个动画组件
2.书写控制Quest显示的方法,就是将quest设置为true并且播放显示动画
3.在OnMouseOver中进行判断和调用显示方法
4.添加关闭按钮,添加点击事件closeQuest,实现方法就是动画倒放,使其移出屏幕
MonoBehaviour {
TweenPosition
void OnMouseOver()//当鼠标在这个collider上时,就会触发这个方法
if (Input.GetMouseButtonDown(0))
&&&&&&&&&&&
setQuestAwake();
void setQuestAwake()
tween.gameObject.SetActive(true);
tween.PlayForward();
//处理点击事件
void HideQuest()
tween.PlayReverse();//动画倒放
void OnCloseClick()
HideQuest();
22.处理任务面板以及各个按钮的点击
这里就是要处理各个按钮之间的逻辑,我们希望达到的效果有
1.点击accept,显示的是接手后的任务信息
2.点击cancel关闭任务面板
3.点击accept显示ok按钮,处理提交任务
1先封装两个方法,一个是显示任务信息,一个是显示任务进度信息
2.两个方法分别设置各个按钮的状态,因此我们要引用各个按钮,并且还要获得label组件来修改它的text
3.我么书写各个按钮的点击处理事件,然后注册到相应的按钮点击反应上,逻辑如上
4.然后我们定义一个Bool值,通过bool值判断此时应该执行哪个面板
MonoBehaviour {
TweenPosition
bool isTask =
int killCount = 0;
UILabel desL
GameObject acceptB
GameObject cancelB
GameObject okB
void OnMouseOver()//当鼠标在这个collider上时,就会触发这个方法
if (Input.GetMouseButtonDown(0))
&&&&&&&&&&&
&&&&&&&&&&&
if (isTask)
&&&&&&&&&&&
&&&&&&&&&&&&&&&
ShowTaskProgess();
&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&&&&&
ShowTaskDes();
&&&&&&&&&&&
&&&&&&&&&&&
setQuestAwake();
void setQuestAwake()
tween.gameObject.SetActive(true);
tween.PlayForward();
void ShowTaskDes()
desLabel.text = &任务\n杀死10只野狼\n\n奖励:\n获得1000金币&;
acceptBtn.SetActive(true);
cancelBtn.SetActive(true);
okBtn.SetActive(false);
isTask = true;//表示接受了任务
void ShowTaskProgess()
desLabel.text = &任务\n你已经杀死了&
+ killCount + &/10只野狼\n\n奖励:\n获得1000金币&;
acceptBtn.SetActive(false);
cancelBtn.SetActive(false);
okBtn.SetActive(true);
//处理点击事件
void HideQuest()
tween.PlayReverse();//动画倒放
void OnCloseClick()
HideQuest();
void OnAcceptClick()
ShowTaskProgess();
void OnCancelClick()
HideQuest();
isTask = false;
void OnOkClick()
HideQuest();
23.处理一下接受任务系统和人物状态得更新
这里我们希望实现的效果是点击ok成功提交任务并且人物状态栏得金币数量更新
因此我们要这么做
1.在characterState里创建一个方法来处理获得金币事件
CharacterState1 :
MonoBehaviour {
7.&&&&public
int coin = 100;
8.&&&&public
int hp = 100;
9.&&&&public
int mp = 100;
10.&&&&public
int grade = 1;
11.&&&&public
void GetCoin(int
13.&&&&&&&&coin +=
2.在BarNpc那里处理点击事件,获取到PlayerState后,同步进行更新
void OnOkClick()
if (killCount &= 10)
&&&&&&&&&&&
state.GetCoin(1000);
&&&&&&&&&&&
killCount = 0;
&&&&&&&&&&&
ShowTaskDes();
&&&&&&&&&&&
HideQuest();
24.处理点击人物后鼠标指针的变化
这里我们要写两个脚本,第一个是一个共有类,我叫它CursorMannager,是管理各种鼠标指针的,一个是Npc脚本,处理各种Npc相关事件的
1.CursorSetting中我们是通过Cursor.setCursor,获得到点击的位置,设置鼠标的状态和对于的图片,创造了两个方法来处理不同情况,并且我们将这个方法封装成单例模式
CurosorSetting :
MonoBehaviour {
CurosorSetting _
Texture2D cursor_A
Texture2D cursor_LockT
Texture2D cursorN
Texture2D Npc_
Texture2D Pick_
Vector2 hotSpot =
CursorMode mode =
CursorMode.A//鼠标自适应选择软件或者硬件
void Start()
_instance = this;
void SetCursorNormal()
Cursor.SetCursor(cursorNormal,
hotSpot, mode);
void SetCursorNpc()
Cursor.SetCursor(Npc_talk,
hotSpot, mode);
2.我们创建一个Npc脚本并且让BarNpc继承自Npc
其中创建了两个方法处理鼠标进入和离开时后鼠标指针的状态
MonoBehaviour {
7.&&&&void
OnMouseEnter()
10.&&&&&&&&CurosorSetting._instance.SetCursorNpc();
13.&&&&void
OnMouseExit()
15.&&&&&&&&CurosorSetting._instance.SetCursorNormal();
25.设置功能面板
这就是Ui的一些摆放,我们create InvisableWidegt来放置这些按钮,这里注意的就是把Ancor设置成向右对其,使其与屏幕自适应
26,创建物品清单
我们在Asserts下创建一个文本
我们先创建一个药品的清单
27,创建物品信息的管理类
我们将在这个类里解析我们的文本信息,并且将它们存放到字典里
1.我们定义一个枚举类型来存放物品类型
2.我们定义一个叫做ObjectsInfo的来存放物品的相关信息
3.我们定义一个ReadInfo来解析我们的文本信息,首先我们用text.Spilt(“\n”)来分隔语句,通过换行符,然后将这些语句存入数组
4.然后我们定义一个新的数组,通过逗号进行分隔存入数组,再用对应类型的数据进行保存
5.我们得到的分隔数据都通过id依次存储到字典里,这样可以方便查找,用到了ObjectsinfoDic.add
6.我们可以在Awake里测试我们得到了几组数据,输出结果应该是3
usingSystem.Collections.G
ObjectInfo :
MonoBehaviour {
ObjectInfo _
TextAsset objectInfoT
Dictionary&int,
Objectsinfo& objectInfoDic
Dictionary&int,Objectsinfo&();
// Use this for initialization
void Awake()
_instance = this;
ReadInfo();
print(objectInfoDic.Keys.Count);
Objectsinfo GetObjcetsinfoById(int
Objectsinfo info=null;
objectInfoDic.TryGetValue(id, out
void ReadInfo()
string text = objectInfoText.
string[] strArray=text.Split('\n');
//通过换行符进行拆分
foreach(string
str in strArray)
&&&&&&&&&&&
string[] proArray = str.Split(',');//根据逗号拆分各个属性存在数组里
&&&&&&&&&&&
Objectsinfo info =
Objectsinfo();
&&&&&&&&&&&
int.Parse(proArray[0]);
&&&&&&&&&&
&&&&&&&&&&&
string name = proArray[1];
&&&&&&&&&&&
string icon_name = proArray[2];
&&&&&&&&&&&
string str_type = proArray[3];
&&&&&&&&&&&
ObjectType type =
ObjectType.D
&&&&&&&&&&&
&&&&&&&&&&&
switch (str_type)
&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
type = ObjectType.D
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
type = ObjectType.E
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
type = ObjectType.M
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&
info.id = info.name =info.icon_name = icon_ info.type =
&&&&&&&&&&&
if (type ==
ObjectType.Drug)
&&&&&&&&&&&
&&&&&&&&&&&&&&&
int.Parse(proArray[4]);
&&&&&&&&&&&&&&&
int.Parse(proArray[5]);
&&&&&&&&&&&&&&&
int price_sell =
int.Parse(proArray[6]);
&&&&&&&&&&&&&&&
int price_buy =
int.Parse(proArray[7]);
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&
&&&&&info.price_buy = price_
&&&&&&&&&&&&&&&
info.price_sell = price_
&&&&&&&&&&&
&&&&&&&&&&&
objectInfoDic.Add(id, info);//添加到字典,id为key,可以很方便查找到
ObjectType
Objectsinfo
string icon_//这个存储的是图集中的名称
ObjectType
int price_
int price_
26.创建背包的UI并且管理背包下的物品
1.我们给背包添加TweenPosition来控制它的显示和隐藏
2.我们给背包下的所有方格添加了InvertoryGrid并且创建一个列表存储方便管理,然后我们在视图下对列表进行赋值
3.我们定义一个Uiabel来控制金币数量的变化
usingSystem.Collections.G
Invertory :
MonoBehaviour {
TweenPosition
Invertory _
List&InvertoryItemGrid&
itemGridList = new
List&InvertoryItemGrid&();
UILabel coinL
// Use this for initialization
void Start () {
tween = this.GetComponent&TweenPosition&();
_instance = this;
// Update is called once per frame
void Update () {
void PlayTween()
tween.PlayForward();
void HideTween()
tween.PlayReverse();
27.实现背包的拾取功能
这里我们做的是模拟背包拾取的功能,也就是按下x后物品会被拾取
1.首先我们在uodate里更改,也就是按下x,会调用Getid方法,随机实例化一个物品出来
Update () {
if (Input.GetKeyDown(KeyCode.X))
&&&&&&&&&&&
GetId(Random.Range(1001,
1004));//随机数不包括最大值,我们取到1001,1003
2.创建GetId方法
1.我们定义了一个list,这里存放了InvertoryItemGrid,这里存放了所有的方格,我们的墓地就是遍历所有的方格并且判断它当前的状态
2.我们遍历后如果存在该物品的话,就将grid设置为该temp,并且根据Grid是否为空判断该物品是否存在,如果不为空的话,我们将num+1就行了,这里调用了一下ItemGrid下的NumPlus方法
3.如果不存在该物品,我们就要将物品设置到新的方格,
temp.id=0的时候,这时候我们将temp设置给grid,然后再跳出循环。然后我们判断当grid!=null,我们就要通过ItemGrid里的setid来更新id,调用NGUI下的方法来实例化物品并且将物品位置设置到正中间
List&InvertoryItemGrid&
itemGridList = new
List&InvertoryItemGrid&();
void GetId(int
//第一步是查找在所有的物品中,是否存在该物品
//第二步,如果存在,就num+1
//如果不存在,就查找空的方格,并且将新创建的Invertory_item放到该空格中
InvertoryItemGrid grid
//遍历所有的网格,判断网格中是否有物品
foreach(InvertoryItemGrid
temp in itemGridList)
&&&&&&&&&&&
if (temp.id == id)
&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&
if (grid !=
&&&&&&&&&&&
grid.PlusNum();
&&&&&&&&&&&
foreach(InvertoryItemGrid
temp in itemGridList)
&&&&&&&&&&&
&&&&&&&&&&&&&&&
if (temp.id == 0)
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&
if (grid !=
&&&&&&&&&&&
&&&&&&&&&&&&&&&
GameObject itemGo=NGUITools.AddChild(grid.gameObject,
invertoryItem);
&&&&&&&&&&&&&&&
itemGo.transform.localPosition= Vector3.//物品设置到格子的正中间
&&&&&&&&&&&&&&&
itemGo.GetComponent&UISprite&().depth
&&&&&&&&&&&&&&&
grid.SetId(id);
&&&&&&&&&&&
3.这里附上InvertoryItemGrid脚本,这个是管理网格的脚本
InvertoryItemGrid :
UIDragDropContainer {
UILabel numL
int id = 0;
int num = 0;
Objectsinfo info =
void Start()
numLabel = this.GetComponentInChildren&UILabel&();
//外部调用该方法来更新显示
void SetId(int
id,int num=1)
info = ObjectInfo._instance.GetObjcetsinfoById(id);
InvertoryItem item =
this.GetComponentInChildren&InvertoryItem&();
item.SetIcon_name(info.icon_name);
numLabel.enabled = true;//这里更新不能使用gamobject,setActive,因为当我们取消勾选的时候,getCompoentInChildren方法根本不会被调用
this.num =
numLabel.text = num.ToString();
//这个方法是用来情况物品栏信息的,比如你使用了该物品,就会重置信息
void clearInfo()
info = null;
numLabel.enabled = false;
void PlusNum(int
this.num +=
numLabel.text = this.num.ToString();//在文本中显示需要将数字转换成字符串
28.控制物品的拖拽功能
在这里我们要处理的拖拽有三种情况
1.拖拽到自身的方格
2.拖拽到空的方格
3.将两个方格内的物品进行交换位置
所以逻辑如下:
1.拖拽到自身方格,我们什么都不需要做
2.拖拽到空的方格,我们要获取到原先位置的信息,再获取到新位置的的方格,通过setId方法将老方格的信息设置到新方格里,再清空老的方格
3.将两个方格的物品进行交换位置,这里需要先获取到两个方格的物品信息,再通过setId进行设置,实现交换
4.最后,所有的操作都需要重置位置信息
29.using UnityE
30.using System.C
InvertoryItem :
UIDragDropItem {
33.&&&&private
34.&&&&void
36.&&&&&&&&sprite =
this.GetComponent&UISprite&();
38.&&&&protected
void OnDragDropRelease(GameObject
40.&&&&&&&&base.OnDragDropRelease(surface);//这里是鼠标发出一个射线检测,当碰撞到第一个collider时候,就将surface设置成为那个碰撞到的物体
41.&&&&&&&&//在这里我们处理鼠标拖拽物品可能遇到的三种情况
43.&&&&&&&&if
(surface!= null)
44.&&&&&&&&{
45.&&&&&&&&&&&&if
(surface.tag == Tags.Invertory_itemGrid)
46.&&&&&&&&&&&&{
47.&&&&&&&&&&&&&&&&//当我们将物品拖拽到一个空的物品栏下面时,有两种情况,第一时拖放到自己的格子里,第二是放在一个新的格子下
48.&&&&&&&&&&&&&&&&if
(surface == this.transform.parent.gameObject)
49.&&&&&&&&&&&&&&&&{
50.&&&&&&&&&&&&&&&&&&&&
51.&&&&&&&&&&&&&&&&&&&&
52.&&&&&&&&&&&&&&&&}
53.&&&&&&&&&&&&&&&&else
54.&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&
55.&&&&&&&&&&&&&&&&&&&&InvertoryItemGrid
oldParent = this.transform.parent.GetComponent&InvertoryItemGrid&();
56.&&&&&&&&&&&&&&&&&&&&this.transform.parent
= surface.//修改目标位置为当前触碰到的位置
57.&&&&&&&&&&&&&&&&&&&&
58.&&&&&&&&&&&&&&&&&&&&//然后我们要将物品信息也移动,重新设置
59.&&&&&&&&&&&&&&&&&&&&InvertoryItemGrid
newParent = surface.GetComponent&InvertoryItemGrid&();
60.&&&&&&&&&&&&&&&&&&&&newParent.SetId(oldParent.id,oldParent.num);
61.&&&&&&&&&&&&&&&&&&&&oldParent.clearInfo();//清空老的物品栏
62.&&&&&&&&&&&&&&&&&&&
63.&&&&&&&&&&&&&&&&}
64.&&&&&&&&&&&&&&&&
65.&&&&&&&&&&&&}
66.&&&&&&&&&&&&else
if (surface.tag ==
Tags.Invertory_item)
67.&&&&&&&&&&&&{
68.&&&&&&&&&&&&&&&&//这是移动到其他物品上时候的处理,交换两者的位置
69.&&&&&&&&&&&&&&&&InvertoryItemGrid
grid1 = this.transform.parent.GetComponent&InvertoryItemGrid&();
70.&&&&&&&&&&&&&&&&InvertoryItemGrid
grid2 = surface.transform.parent.GetComponent&InvertoryItemGrid&();
71.&&&&&&&&&&&&&&&&int
id1 = grid1.int num1 = grid1.
72.&&&&&&&&&&&&&&&&grid1.SetId(grid2.id,grid2.num);
73.&&&&&&&&&&&&&&&&grid2.SetId(id1, num1);
76.&&&&&&&&&&&&}&&&&&&
77.&&&&&&&&}
78.&&&&&&&&ResetPos();
80.&&&&void
ResetPos()
82.&&&&&&&&transform.localPosition =
84.&&&&public
void SetId(int
86.&&&&&&&&Objectsinfo
info = ObjectInfo._instance.GetObjcetsinfoById(id);
87.&&&&&&&&//这是是要根据id显示物品
88.&&&&&&&&sprite.spriteName = info.icon_//更新物品
90.&&&&public
void SetIcon_name(string
icon_name)
92.&&&&&&&&sprite.spriteName = icon_
29.实现背包的显示和隐藏
我们在背包里通过bool值控制显示和隐藏,然后统一写一个方法在Onfunction里调用里的OnButtonClick方法里调用,这样,就可以实现背包的显示和隐藏了
bool isShow =
void PlayTween()
isShow = true;
tween.PlayForward();
void HideTween()
isShow = false;
tween.PlayReverse();
void OnTransformState()
if (isShow ==
&&&&&&&&&&&
PlayTween();
if(isShow==true)
&&&&&&&&&&&
HideTween();
30.实现物品信息的显示
1.首先我们创建一个sprite叫做ItemDes,并且在它下面创建一个laber,调整好它的大小并且让文字居左对齐
2.我们给这个sprite添加个脚本叫做InvertoryDes
脚本实现两个功能1.从物品信息类那里获取到物品的相关信息,根据对应的物品
3.&在show方法里我们调用根据获得物品信息方法,依据相应的类型显示对应的文本
4.我们使用UI摄像机里有个将局部坐标转换成世界坐标的方法设置好显示信息在物品上
5.我们添加一个计时器,来控制当鼠标不在物品上面时使物品信息隐藏,我们每次调用show方法,就将计时器设置为0.1,然后离开时就会进行时间减少,当时间到0以下时,就会取消显示
InvertoryDes :
MonoBehaviour {
11.&&&&public
InvertoryDes _
12.&&&&private
13.&&&&private
float timmer = 0;
14.&&&&void
16.&&&&&&&&_instance =
17.&&&&&&&&label =
this.GetComponentInChildren&UILabel&();
18.&&&&&&&&this.gameObject.SetActive(false);
21.&&&&void
23.&&&&&&&&//每次调用show方法后,离开时就进行计算
24.&&&&&&&&timmer-=
Time.deltaT
25.&&&&&&&&if
(timmer &= 0)
26.&&&&&&&&{
27.&&&&&&&&&&&&this.gameObject.SetActive(false);
28.&&&&&&&&}
30.&&&&//在这里我,我们要根据我们获得的物品id来获得物品描述信息
31.&&&&public
void Show(int
33.&&&&&&&&this.gameObject.SetActive(true);
34.&&&&&&&&timmer = 0.1f;
35.&&&&&&&transform.position=UICamera.currentCamera.ScreenToWorldPoint(Input.mousePosition);
36.&&&&&&&&Objectsinfo
info = ObjectInfo._instance.GetObjcetsinfoById(id);
37.&&&&&&&&string
38.&&&&&&&&switch
(info.type)
39.&&&&&&&&{
40.&&&&&&&&&&&&case
ObjectType.Drug:
41.&&&&&&&&&&&&&&&&des = GetDrugdes(info);
42.&&&&&&&&&&&&&&&&break;
43.&&&&&&&&}
44.&&&&&&&&label.text =
47.&&&&//我们通过这个方法来获得物品信息
48.&&&&string
GetDrugdes(Objectsinfo info)
50.&&&&&&&&string
51.&&&&&&&&str+=
+ info.name + &\n&;
52.&&&&&&&&str +=
&+Hp& + info.hp +
53.&&&&&&&&str +=
&+MP& + info.mp +
54.&&&&&&&&str +=
&sellMoney& + info.price_sell
+ &\n&;
55.&&&&&&&&return
58.&&&&&&&
然后我们修改InvertoryItem
首先我们在prefab下添加这样两个组件,来判断鼠标是否移动到上面
void OnHoverEnter()
isHover = true;
void OnHoverExit()
isHover = false;
添加好方法后,我们在这里根据Id调用对应的物品信息显示
void Update()
if (isHover)
&&&&&&&&&&&
InvertoryDes._instance.Show(id);
31.创建用户信息面板
拼接好UI后,我们添加一个脚本保存主角信息
CharacterState1 :
MonoBehaviour {
int coin = 100;
int hp = 100;
int mp = 100;
int grade = 1;
int arrack = 20;
int attack_plus = 0;
int def = 0;
int def_plus = 0;
int speed = 20;
int speed_plus = 0;
int point_remain = 0;
void GetCoin(int
coin +=
32.实现状态面板的更新显示
1.我们要获取到组件的信息
2.我们定义一个UpdateState方法来获取玩家状态信息然后更新显示
3.我们给三个按钮注册三个方法来控制加点
MonoBehaviour {
TweenPosition
bool isShow =
UILabel attackL
UILabel defL
UILabel speedL
UILabel remainL
UILabel summaryL
GameObject attackB
GameObject defB
GameObject speedB
CharacterState1
// Use this for initialization
void Start () {
_instance = this;
tween = this.GetComponent&TweenPosition&();
&&&&&&ps = GameObject.FindGameObjectWithTag(Tags.player).GetComponent&CharacterState1&();
// Update is called once per frame
void Update () {
void TransformState()
if (isShow ==
&&&&&&&&&&&
tween.PlayForward();
&&&&&&&&&&&
UpdateState();
&&&&&&&&&&&
isShow = true;
&&&&&&&&&&&
tween.PlayReverse();
&&&&&&&&&&&
isShow = false;
void UpdateState()
attackLabel.text=ps.attack+&+&+ps.attack_
defLabel.text = ps.def+&+&+ps.def_
speedLabel.text = ps.speed + &+&
+ ps.speed_
remainLabel.text =ps.point_remain.ToString();
summaryLabel.text = &伤害:&
+ (ps.attack +ps.attack_plus) +
&&&&&&&&&&&
+ &防御:&
& + (ps.def + ps.def_plus) +
&&&&&&&&&&&
+ &速度:&
& + (ps.speed + ps.speed_plus);
if (ps.point_remain & 0)
&&&&&&&&&&&
attackBtn.gameObject.SetActive(true);
&&&&&&&&&&&
defBtn.gameObject.SetActive(true);
&&&&&&&&&&&speedBtn.gameObject.SetActive(true);
&&&&&&&&&&&
attackBtn.gameObject.SetActive(false);
&&&&&&&&&&&
defBtn.gameObject.SetActive(false);
&&&&&&&&&&&
speedBtn.gameObject.SetActive(false);
void OnAttackBtnClick()
bool success = ps.GetPoint();
if (success)
&&&&&&&&&&&
ps.attack_plus++;
&&&&&&&&&&&
UpdateState();//更新显示
void OnDefBtnClick()
bool success = ps.GetPoint();
if (success)
&&&&&&&&&&&
ps.def_plus++;
&&&&&&&&&&&
UpdateState();//更新显示
void OnSpeedBtnClick()
bool success = ps.GetPoint();
if (success)
&&&&&&&&&&&
ps.speed_plus++;
&&&&&&&&&&&
UpdateState();//更新显示
2.修改玩家状态信息,定义一个GetPoint方法,来判断是否可以进行点数加减
bool GetPoint(int
point = 1)
//判断是否加可以加点数
point_remain -=
if (point_remain & 0)
&&&&&&&&&&&
&&&&&&&&&&&
33.更新药品商店的购买功能
这里我们要实现点击各个按钮实现购买的功能
1.我们要注册各个按钮的点击事件,并且获取到物品列表中的一些UI组件
2.当我们点击各个buy按钮时候,会显示出下面的购买框进行购买,这里我们进行对比看玩家金额是否可以购买对应的数量,所以首先我们要计算出你购买的count和物品价格,这里要获得ObjectsInfo中的物品信息,然后在Invertory里我们写一个判断是否可以购买的bool方法
bool buyPower(int
//判断是否可以进行交易行为
if (coinCount & count)
&&&&&&&&&&&
coinCount-=
&&&&&&&&&&&
coinLabel.text =coinCount.ToString();//更新显示
&&&&&&&&&&&
&&&&&&&&&&&
3.然后我们根据Invertory中的SetId方法,设置点击后更新背包内的物品信息
ShopDrug :
MonoBehaviour {
ShopDrug _
TweenPosition
bool isShow =
UIInput numberI
GameObject numberD
int Buy_id = 0;
// Use this for initialization
void Awake () {
tween = this.GetComponent&TweenPosition&();
_instance = this;
numberInput = transform.Find(&NumberDialog/NumberInput&).GetComponent&UIInput&();
numberDialog = this.transform.Find(&NumberDialog&).gameO
numberDialog.SetActive(false);
void TransformState()
if (isShow ==
&&&&&&&&&&&
tween.PlayForward();
&&&&&&&&&&&
isShow = true;
if(isShow==true)
&&&&&&&&&&&
tween.PlayReverse();
&&&&&&&&&&&
isShow = false;
void OnCloseClick()
TransformState();
void OnButton1001Click()
Buy(1001);
void OnButton1002Click()
Buy(1002);
void OnButton1003Click()
Buy(1003);
void OnButtonOkClick()
int count =
int.Parse(numberInput.value);
Objectsinfo info =
ObjectInfo._instance.GetObjcetsinfoById(Buy_id);//获取物品信息
int price_total = info.price_buy
bool success =
Invertory._instance.buyPower(price_total);
if (success)
&&&&&&&&&&&
if(count&0)
&&&&&&&&&&&
Invertory._instance.GetId(Buy_id,
void Buy(int
ShowDialog();
void ShowDialog()
numberDialog.SetActive(true);
numberInput.value = &0&;
36.创建装备栏并且添加物品信息的读取
首先我们在物品信息类里添加装备信息
Right_Hand,
Left_Hand,
ApplicationType
ObjectType
Objectsinfo
string icon_//这个存储的是图集中的名称
ObjectType
int price_
int price_
DressType dressT
ApplicationType applicationT
3.修改物品信息文件
4.在Equipment里取到各种物品信息
EquipmentUI _
TweenPosition
bool isShow =
GameObject headG
GameObject
GameObject left_H
GameObject right_H
GameObject
GameObject
void Awake()
_instance = this;
tween = this.GetComponent&TweenPosition&();
headGear = transform.Find(&Headgear&).gameO
armor = transform.Find(&Aromr&).gameO
left_Hand = transform.Find(&Left_Hand&).gameO
right_Hand = transform.Find(&Right_Hand&).gameO
shoe = transform.Find(&Shoe&).gameO
accessory = transform.Find(&Accessory&).gameO
5.在物品信息类里实现读取
if (type ==
ObjectType.Equip)
&&&&&&&&&&&
&&&&&&&&&&&&&&&
int attack =
int.Parse(proArray[4]);
&&&&&&&&&&&&&&&
int.Parse(proArray[5]);
&&&&&&&&&&&&&&&
int speed =
int.Parse(proArray[6]);
&&&&&&&&&&&&&&&
int sell_price =
int.Parse(proArray[9]);
&&&&&&&&&&&&&&&
int buy_price =
int.Parse(proArray[10]);
&&&&&&&&&&&&&&&
string str_dresstype = proArray[7];
&&&&&&&&&&&&&&&
switch (str_dresstype)
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&Headgear&:
&&&&&&&&&&&&&&&&&&&&&&&
info.dressType = DressType.H
&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&
info.dressType = DressType.A
&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&Right_Hand&:
&&&&&&&&&&&&&&&&&&&&&&&
info.dressType = DressType.Right_H
&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&Left_Hand&:
&&&&&&&&&&&&&&&&&&&&&&&
info.dressType = DressType.Left_H
&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&
info.dressType = DressType.S
&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&Accessory&:
&&&&&&&&&&&&&&&&&&&&&&&
info.dressType = DressType.A
&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
string str_apptype = proArray[8];
&&&&&&&&&&&&&&&
switch (str_apptype)
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&Magician&:
&&&&&&&&&&&&&&&&&&&&&&&
info.applicationType = ApplicationType.M
&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&SwordMan&:
&&&&&&&&&&&&&&&&&&&&&&&
info.applicationType = ApplicationType.S
&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&
info.applicationType = ApplicationType.C
&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&
6.&&&&&&&&&&&&}
37.显示物品信息
这里我们只需要修改一下InvertoryDes即可
我们添加一个方法来获得物品信息类里的各种属性
GetEquipDes(Objectsinfo info)
string str =
str += &名称:&
+ info.name + &\n&;
switch (info.dressType)
&&&&&&&&&&&
DressType.Headgear:
&&&&&&&&&&&&&&&
str += &穿戴类型:头盔\n&;
&&&&&&&&&&&&&&&
&&&&&&&&&&&
DressType.Armor:
&&&&&&&&&&&&&&&
str += &穿戴类型:盔甲\n&;
&&&&&&&&&&&&&&&
&&&&&&&&&&&
DressType.Right_Hand:
&&&&&&&&&&&&&&&
str += &穿戴类型:右手武器\n&;
&&&&&&&&&&&&&&&
&&&&&&&&&&&
DressType.Left_Hand:
&&&&&&&&&&&&&&&
str += &穿戴类型:左手武器\n&;
&&&&&&&&&&&&&&&
&&&&&&&&&&&
DressType.Shoe:
&&&&&&&&&&&&&&&
str += &穿戴类型:鞋子\n&;
&&&&&&&&&&&&&&&
&&&&&&&&&&&
DressType.Accessory:
&&&&&&&&&&&&&&&
str += &穿戴类型:饰品\n&;
&&&&&&&&&&&&&&&
switch (info.applicationType)
&&&&&&&&&&&
ApplicationType.Common:
&&&&&&&&&&&&&&&
str += &通用类型\n&;
&&&&&&&&&&&&&&&
&&&&&&&&&&&
ApplicationType.Magician:
&&&&&&&&&&&&&&&
str += &魔法师类型\n&;
&&&&&&&&&&&&&&&
&&&&&&&&&&&
ApplicationType.Swordman:
&&&&&&&&&&&&&&&
str += &剑士类型\n&;
&&&&&&&&&&&&&&&
str += &sellMoney& +
info.price_sell + &\n&;
str += & buyPrice& +
info.price_buy + &\n&;
2.然后再在show方法里进行调用即可
//在这里我,我们要根据我们获得的物品id来获得物品描述信息
void Show(int
this.gameObject.SetActive(true);
timmer = 0.1f;
transform.position=UICamera.currentCamera.ScreenToWorldPoint(Input.mousePosition);
Objectsinfo info =
ObjectInfo._instance.GetObjcetsinfoById(id);
string des =
switch (info.type)
&&&&&&&&&&&
ObjectType.Drug:
&&&&&&&&&&&&&&&
des = GetDrugdes(info);
&&&&&&&&&&&&&&&
&&&&&&&&&&&
ObjectType.Equip:
&&&&&&&&&&&&&&&
des = GetEquipDes(info);
&&&&&&&&&&&&&&&
label.text =
38.实现物品的穿戴
在这里我们将实现物品的穿戴,接下来我将讲述一下逻辑
1.我们在IvertoryItem里有一个isHover来判断鼠标是否在格子上,我们通过这个方法来判断穿戴哪个物品,而我们将使用右键来穿戴上对应的物品
2.我们在EquipItemUI中书写一个Dress方法,来判断是否可以进行穿戴,并且处理穿戴事件
(1)我们通过id来获取到我们穿戴的是什么物品,所以我们先要根据Id获取到物品信息
(2)我们先处理三种无法穿戴的事件,当然在这里我们要给PlayerStates里添加一个主角类型的数组并且在EquipmentUi中获取到这个主角类型数组
1.穿戴物品不是装备,返回fasle
2.人物是魔法师穿戴剑士装备,返回false
3.人物是剑士穿戴魔法师装备,返回false
(3)接下来处理穿戴成功的情况,首先,我们需要定义一个parent,来使得物品正确实例化到对应的位置,我们根据物品的穿戴类型将parent设置成各种类型的位置
3这时候我们要在EquipmentItem下添加euqipmentItem脚本,处理实例化物品的方法,这里我们只需要修改贴图即可,因此我们在setinfo里将spriteName修改成icon_name即可,当然,我们要先根据id获得到物品信息才对
4.我们回到dress方法,这时候穿戴成功有两种可能,
(1)即穿戴的位置有物品,有物品我们就调用EquipmentItem中的setInfo方法更新贴图即可,然后还要用Invertory中的getId方法将该物品重新放回背包内
(2)穿戴的位置没物品,这时候我们要减少该物品栏的物品,使用Ngui下的Addchild方法来更新物品栏的显示
4.我们在InvertoryItem里处理穿戴方法,这里我们要调用grid下的一个减少数量的方法,当可以正常进行穿戴时,我们要更新背包信息并且正常穿戴
5.我们要在ItemGrid下书写一个减少数量的方法来处理物品信息的更新,如果数量为0则销毁该物品并且清空信息栏,如果不为0则更新显示将数量减少1
bool MinusItem(int
8.&&&&&&&&if
(this.num &= num)
9.&&&&&&&&{
10.&&&&&&&&&&&&this.num
11.&&&&&&&&&&&&numLabel.text =
this.num.ToString();
12.&&&&&&&&&&&&if
(this.num == 0)
13.&&&&&&&&&&&&{
14.&&&&&&&&&&&&&&&&clearInfo();//清空物品栏信息
15.&&&&&&&&&&&&&&&&GameObject.Destroy(this.GetComponentInChildren&InvertoryItem&().gameObject);//销毁物品
16.&&&&&&&&&&&&}
17.&&&&&&&&&&&&return
18.&&&&&&&&}
19.&&&&&&&&else
20.&&&&&&&&{
21.&&&&&&&&&&&&return
22.&&&&&&&&}
if (isHover)
&&&&&&&&&&&
InvertoryDes._instance.Show(id);
&&&&&&&&&&&
if (Input.GetMouseButtonDown(1))
&&&&&&&&&&&
&&&&&&&&&&&&&&&
//处理穿戴功能
&&&&&&&&&&&&&&&
bool success =
EquipmentUI._instance.Dress(id);//判断是否穿戴成功
&&&&&&&&&&&&&&&
if (success)
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&transform.parent.GetComponent&InvertoryItemGrid&().MinusItem();
&&&&&&&&&&&&&&&
&&&&public
void SetId(int
Objectsinfo info =
ObjectInfo._instance.GetObjcetsinfoById(id);
SetInfo(info);
void SetInfo(Objectsinfo
this.id = info.
sprite.spriteName = info.icon_
bool Dress(int
Objectsinfo info =
ObjectInfo._instance.GetObjcetsinfoById(id);
if (info.type !=ObjectType.Equip)
&&&&&&&&&&&
//如果穿戴类型不对,则无法穿戴
&&&&&&&&&&&
if (ps.heroType ==
HeroType.Magician)
&&&&&&&&&&&
//类型不匹配无法穿戴
&&&&&&&&&&&
if (info.applicationType ==
ApplicationType.Swordman)
&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&
if (ps.heroType ==
HeroType.SwordMan)
&&&&&&&&&&&
//类型不匹配无法穿戴
&&&&&&&&&&&
if (info.applicationType ==
ApplicationType.Magician)
&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&
GameObject parent =
switch (info.dressType)
&&&&&&&&&&&
DressType.Headgear:
&&&&&&&&&&&&&&&
parent = headG
&&&&&&&&&&&&&&&
&&&&&&&&&&&
DressType.Armor:
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&
DressType.LeftHand:
&&&&&&&&&&&&&&&
parent = left_H
&&&&&&&&&&&&&&&
&&&&&&&&&&&
DressType.RightHand:
&&&&&&&&&&&&&&&
parent = right_H
&&&&&&&&&&&&&&&
&&&&&&&&&&&
DressType.Shoe:
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&
DressType.Accessory:
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
EquipmentItem item =
parent.GetComponentInChildren&EquipmentItem&();
if (item !=
&&&&&&&&&&&
//穿戴同样类型的装备,我们不仅要更新显示,还要将卸下来的物品放进背包
&&&&&&&&&&&
item.SetInfo(info);
&&&&&&&&&&&
Invertory._instance.GetId(item.id);
&&&&&&&&&&&
&&&&&&&&&&
GameObject itemGo=
NGUITools.AddChild(parent,
equipmentItem);
&&&&&&&&&&&
itemGo.transform.localPosition = Vector3.
&&&&&&&&&&&
itemGo.GetComponent&EquipmentItem&().SetInfo(info);
39.实现物品的卸下
这里我们只需要处理一下EquipmentItem下的脚本即可
1.我们给物品添加上BoxCollider
2.调用NGUI下的OnHover方法判断鼠标是否在物品上并且更新isHover
3.在Update里更新,当鼠标在它上面并且点击鼠标右键的时候,就会调用InverTory中的GetID方法将物品放入背包,再销毁物品,就可以实现卸下物品的功能了
EquipmentItem :
MonoBehaviour
42.&&&&private
43.&&&&public
44.&&&&private
bool isHover =
45.&&&&void
47.&&&&&&&&sprite = GetComponent&UISprite&();
49.&&&&void
51.&&&&&&&&if
52.&&&&&&&&{
53.&&&&&&&&&&&&if
(Input.GetMouseButtonDown(1))
54.&&&&&&&&&&&&{
55.&&&&&&&&&&&&&&&&Invertory._instance.GetId(id);//将自己放到背包里
56.&&&&&&&&&&&&&&&&Destroy(this.gameObject);
57.&&&&&&&&&&&&}
58.&&&&&&&&}
60.&&&&public
void SetId(int
62.&&&&&&&&this.id
63.&&&&&&&&Objectsinfo
info = ObjectInfo._instance.GetObjcetsinfoById(id);
64.&&&&&&&&SetInfo(info);
66.&&&&public
void SetInfo(Objectsinfo
68.&&&&&&&&this.id
69.&&&&&&&&sprite.spriteName = info.icon_
71.&&&&//鼠标移上或者移出会触发该方法
72.&&&&public
void OnHover(bool
74.&&&&&&&&isHover = isO
40.实现装备更换对于人物属性的更新
1.我们定义三个属性
2.定义一个更新属性的方法,我们通过获取这些装备的属性值,再加在我们预设的装备提供属性上,这样人物信息就可以通过获取这三个装备属性进行更新了
void UpdateProperty()
5.&&&&&&&&//用来更新角色属性
6.&&&&&&&&this.attack
7.&&&&&&&&this.def
8.&&&&&&&&this.speed
9.&&&&&&&&EquipmentItem
headgearItem =headGear.GetComponentInChildren&EquipmentItem&();
10.&&&&&&&&PlusProperty(headgearItem);
11.&&&&&&&&EquipmentItem
armorItem = armor.GetComponentInChildren&EquipmentItem&();
12.&&&&&&&&PlusProperty(armorItem);
13.&&&&&&&&EquipmentItem
lefhandItem = left_Hand.GetComponentInChildren&EquipmentItem&();
14.&&&&&&&&PlusProperty(lefhandItem);
15.&&&&&&&&EquipmentItem
righthandItem =right_Hand.GetComponentInChildren&EquipmentItem&();
16.&&&&&&&&PlusProperty(righthandItem);
17.&&&&&&&&EquipmentItem
shoeItem = shoe.GetComponentInChildren&EquipmentItem&();
18.&&&&&&&&PlusProperty(shoeItem);
19.&&&&&&&&EquipmentItem
accessoryItem =accessory.GetComponentInChildren&EquipmentItem&();
20.&&&&&&&&PlusProperty(accessoryItem);
23.&&&&public
void PlusProperty(EquipmentItem
25.&&&&&&&&if
(item != null)
26.&&&&&&&&{
27.&&&&&&&&&&&&Objectsinfo
equipInfo = ObjectInfo._instance.GetObjcetsinfoById(item.id);
28.&&&&&&&&&&&&this.attack
+= equipInfo.
29.&&&&&&&&&&&&this.def
= equipInfo.
30.&&&&&&&&&&&&this.speed
= equipInfo.
31.&&&&&&&&}
4.我们在EquipItem里调用我们的脱下装备方法
根据物品的id来设置和销毁并且更新信息
void takeOff(int
id,GameObject go)
Invertory._instance.GetId(id);//将自己放到背包里
Destroy(go);
UpdateProperty();
//更新脱下后的信息
关于技能系统中信息的录入
这里我们要制作的是技能系统,首先我们要录入技能信息,然后存储技能的相关属性
usingSystem.Collections.G
SkillsInfo :
MonoBehaviour
TextAsset skillsI
SkillsInfo _
Dictionary&int,
SkillInfo& skillinfoDict =
Dictionary&int,
SkillInfo&();
// Use this for initialization
void Start()
_instance = this;
InitSkillInfoDic();
// Update is called once per frame
void Update()
void InitSkillInfoDic()
ApplicableRole
//这些是角色类型
//作用属性
ApplicableType
SingleTarget,
MultiTarget
ApplicableProperty
AttackSpeed,
ReleaseType
string icon_
ApplicableType applyT
ApplicableProperty applyP
ReleaseType releaseT
int applyV
ApplicableRole applyR
42.获取技能文本信息并且封装方便外部进行调用
这里和之前的背包系统差不多,就不多赘述了,就是分属性,得到数组后存入对应的位置,然后封装成单例模式方便在外部进行调用
SkillInfo GetSkillInfoById(int
SkillInfo info =
skillinfoDict.TryGetValue(id, out
void InitSkillInfoDic()
string text = skillsInfoText.
string[] skillInfoArray = text.Split('\n');//通过换行符区分技能列表数组
foreach(string
skillInfoStr in skillInfoArray)
&&&&&&&&&&&
string[] pa = skillInfoStr.Split(',');//技能的各个属性通过逗号区分
&&&&&&&&&&&
SkillInfo info =
SkillInfo();
&&&&&&&&&&&
info.id = int.Parse(pa[0]);
&&&&&&&&&&&
info.name = pa[1];
&&&&&&&&&&&
info.icon_name = pa[2];
&&&&&&&&&&&
info.des = pa[3];
&&&&&&&&&&&
string str_applyType = pa[4];
&&&&&&&&&&&
switch (str_applyType)
&&&&&&&&&&&
&&&&&&&&&&&&&&&
&Passive&:
&&&&&&&&&&&&&&&&&&&
info.applyType = ApplicableType.P
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
info.applyType = ApplicableType.B
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&SingleTarget&:
&&&&&&&&&&&&&&&&&&&
info.applyType = ApplicableType.SingleT
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&MultiTarget&:
&&&&&&&&&&&&&&&&&&&
info.applyType = ApplicableType.MultiT
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&
string str_applyProerty = pa[5];
&&&&&&&&&&&
switch (str_applyProerty)
&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
info.applyProperty = ApplicableProperty.A
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
info.applyProperty = ApplicableProperty.D
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&Attcak_Speed&:
&&&&&&&&&&&&&&&&&&&
info.applyProperty = ApplicableProperty.AttackS
&&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
info.applyProperty = ApplicableProperty.Hp;
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
info.applyProperty = ApplicableProperty.Mp;
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
info.applyProperty = ApplicableProperty.S
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&
info.applyValue = int.Parse(pa[6]);
&&&&&&&&&&&
info.applyTime = int.Parse(pa[7]);
&&&&&&&&&&&
info.mp = int.Parse(pa[8]);
&&&&&&&&&&&
info.coldTime = int.Parse(pa[9]);
&&&&&&&&&&&
switch (pa[10])
&&&&&&&&&&&
&&&&&&&&&&&&&&&
&SwordMan&:
&&&&&&&&&&&&&&&&&&&
info.applyRole = ApplicableRole.SwordM
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&Magician&:
&&&&&&&&&&&&&&&&&&&
info.applyRole = ApplicableRole.M
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&
info.level = int.Parse(pa[11]);
&&&&&&&&&&&
switch (pa[12])
&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&info.releaseType = ReleaseType.S
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&Position&:
&&&&&&&&&&&&&&&&&&&
info.releaseType = ReleaseType.P
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
info.releaseType = ReleaseType.E
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&
info.distance = float.Parse(pa[13]);
&&&&&&&&&&&
skillinfoDict.Add(info.id, info);
43.制作好技能栏
在这里我们要制作一个技能列表,实现滚动条,这里没什么操作的地方,就是添加一个grid来管理排序,然后添加一个ScrollView和boxCollider来控制滚动,添加一个ScrollBar来作为滚动条,要注意当滚动条不显示时修改depth
44.自动根据职业添加技能条
这里,我们要实现的是动态添加技能条,首先我们要在SkillUI下进行更改
&这里讲一下步骤
1.创建两个数组存放魔法师技能id编号和战士技能id编号
2.我们要获得PlayerStates中角色的状态决定显示哪个角色的技能
3.用foreach遍历数组并且动态添加到Grid下实现自动排序
4.然后我们调用SkillItem中的setId方法来更新技能的显示
MonoBehaviour
TweenPosition
bool isShow =
//存储魔法师和剑士的技能id
int[] magicianS
int[] swordmanS
GameObject skillI
CharacterState1
// Use this for initialization
void Awake()
_instance = this;
tween = GetComponent&TweenPosition&();
ps = GameObject.FindGameObjectWithTag(Tags.player).GetComponent&CharacterState1&();
// Update is called once per frame
void Update()
void Start()
int[] idList =
//根据英雄类型显示对应技能图标
switch (ps.heroType)
&&&&&&&&&&&
HeroType.Magician:
&&&&&&&&&&&&&&&
idList = magicianS
&&&&&&&&&&&&&&&
&&&&&&&&&&&
HeroType.SwordMan:
&&&&&&&&&&&&&&&
idList = swordmanS
&&&&&&&&&&&&&&&
foreach(int
id in idList)
&&&&&&&&&&
GameObject itemGo=
NGUITools.AddChild(grid.gameObject,skillItem);
&&&&&&&&&&&
grid.AddChild(itemGo.transform);
&&&&&&&&&&&
itemGo.GetComponent&SkillItem&().SetId(id);//根据id更新显示
void TransformState()
if (isShow ==
&&&&&&&&&&&
tween.PlayForward();
&&&&&&&&&&&
isShow = true;
&&&&&&&&&&&
if (isShow ==
&&&&&&&&&&&
&&&&&&&&&&&&&&&
tween.PlayReverse();
&&&&&&&&&&&&&&&
isShow = false;
&&&&&&&&&&&
这里是skillItem的脚本,就是获取item的各种信息,然后方便外部进行修改
SkillItem :
MonoBehaviour {
UISprite icon_name_
UILabel nameL
UILabel applyTypeL
UILabel desL
UILabel mpL
void InitProperty()
icon_name_sprite = transform.Find(&Icon_name&).GetComponent&UISprite&();
nameLabel = transform.Find(&Property/Name/name&).GetComponent&UILabel&();
applyTypeLabel = transform.Find(&Property/ApplyType/applyType&).GetComponent&UILabel&();
desLabel = transform.Find(&Property/Des_bg/des&).GetComponent&UILabel&();
mpLabel = transform.Find(&Property/Mp_bg/mp&).GetComponent&UILabel&();
//外部调用显示图标
void SetId(int
InitProperty();
info = SkillsInfo._instance.GetSkillInfoById(id);
icon_name_sprite.spriteName =info.icon_
nameLabel.text = info.
switch (applyTypeLabel.text)
&&&&&&&&&&&
&Passive&:
&&&&&&&&&&&&&&&
applyTypeLabel.text = &增益&;
&&&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&&&&&
applyTypeLabel.text = &增强&;
&&&&&&&&&&&&&&&
&&&&&&&&&&&
&SingleTarget&:
&&&&&&&&&&&&&&&
applyTypeLabel.text = &单体目标&;
&&&&&&&&&&&&&&&
&&&&&&&&&&&
&MultiaTarget&:
&&&&&&&&&&&&&&&
applyTypeLabel.text = &群体目标&;
&&&&&&&&&&&&&&&
desLabel.text = info.
mpLabel.text = info.mp + &MP&;
45.关于技能根据等级显示
这里我们需要的是当等级改变时候,技能会相应的进行解锁
1.在skillItem这个prefab下添加一个skillMask并且由它决定是否可以使用技能
2.然后我们在skillItem下添加一个UpdateLevel来根据等级更新显示
void UpdateLevel(int
if (info.level &= grade)
&&&&&&&&&&&
icon_mask.SetActive(false);
&&&&&&&&&&&
icon_name_sprite.GetComponent&SkillIcon&().enabled=true;
&&&&&&&&&&&
icon_mask.SetActive(true);
&&&&&&&&&&&
icon_name_sprite.GetComponent&SkillIcon&().enabled
3.我们在skillUi中获得主角当前等级,并且根据等级来更新显示
这里我们获取到技能列表,并且根据技能的level判断是否显示
void UpdateShow()
//我们要根据人物等级来更新显示
SkillItem[] items =
GetComponentsInChildren&SkillItem&();//获取所有的SkillItem
foreach(SkillItem
item in items)
&&&&&&&&&&&
item.UpdateLevel(ps.grade);
4我们在transformState中调用,即每次使用的时候更新显示
void TransformState()
if (isShow ==
&&&&&&&&&&&
UpdateShow();
&&&&&&&&&&&
tween.PlayForward();
&&&&&&&&&&&
isShow = true;
&&&&&&&&&&&
if (isShow ==
&&&&&&&&&&&
&&&&&&&&&&&&&&&
tween.PlayReverse();
&&&&&&&&&&&&&&&
isShow = false;
&&&&&&&&&&&&&&&
&&&&&&&&&&&
46.人物头像的制作
1.我们将Magican添加一个分级Player
2.我们给Magician添加一个camera调整位置,使它只渲染我们的主角,它会生成一个动态texture,我们新建一个texture来存放它
3我们添加一个shader和一个mask用来渲染角色的背景
4.在UiRoot下我们添加一个SimpleTexture并且将它添加过去
5.这样我们的任务头像就做完了
没有更多推荐了,}

我要回帖

更多关于 照在了大地上把每个黑暗的地方 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信