文章目录

  • Easy, Normal, Hard, SuperHard
    • 1.(E)模型缩小后材质漆黑无变化问题。
    • 2.(N)脚本变量赋值后运行游戏变量值没有赋值成功问题
    • 3.(N)Mathf.clamp函数并没有限定值的范围
    • 4.(N)wheelCollider只允许加4个吗?
    • 5.(H)为什么[serializable]属性并没有让类里头的成员在inspector中出现?
    • 6.(E)书2.5.3节明显存在问题,update方法内连坦克position都没加,怎么可能实现运动。(我错了)
    • 7.(E)炮管随鼠标奇怪的扭转,不跟随炮塔。
    • 8.(H) partical包导入后prefab无效
    • 9.(E)炮弹射击音效声很短问题
    • 10.(H)炮弹攻击伤害爆表之谜
    • 11.(E)炮管上下旋转角度不对
    • 12.(E)坦克悬挂多个音源脚本怎么判断哪个是哪个
    • 13. (E)4.3.3节有一个错误,NoTarget方法最后minHp没有更新
    • 14.(E)如何进入游戏即可发射炮弹,之后才有发射间隔
    • 15.(E)记录点书中小错误
    • 16.(SH)坦克车速要么过快,要么过慢,容易打滑怎么办
    • 17. (E)4.7.3节巡逻逻辑并没有编写完善
    • 18.(N)prefab要慎重删除
    • 19.(SH)AI坦克间互相不攻击问题
    • 20.(N)击杀图片显示问题
    • 21.(N)坦克寻路谜之走法问题
    • 22.(SH)游戏开始时有半秒长的6下咯吱声
    • 23.(E)一些小tips
    • 24.(N)5.3节错误 PanelLayer并没有定义
    • 25. (E)九宫格的使用
    • 26.(H)UI界面关闭不了,显示错误The given key was not present in the dictionary.
    • 27. (E)P186 OptionPanel类OnStartClick方法有错误
    • 28. (ENHSH)一些增加与修改
    • 29.(E)Terrain如何变好看,怎么添加多层材质?
    • 30.(H)ToLua的使用问题
    • 31. (SH)AI坦克间会相撞,如何避免,以及如何实现躲避逻辑问题
    • 32. (SH)血条并没有成功减少
    • 33.(H)P129页错误
    • 34.(H)实现手游摇杆功能
    • 35.(SH)实现滑动屏幕右半边旋转相机功能
    • 36.(H)第四章重大问题:changestatus()并没有更新AI的status状态
    • 37.(E)翻车逻辑判定更新
    • 38.(E)书上PanelManager的closePanel方法存在漏洞

Easy, Normal, Hard, SuperHard

1.(E)模型缩小后材质漆黑无变化问题。

  旧版的模型不行了,下载第二版书里的素材

2.(N)脚本变量赋值后运行游戏变量值没有赋值成功问题


  如图所示,定义的值并没有在Start或者awake中初始化。所以有可能存在运行后unity里并没有成功赋值的情况,再在unity里重新赋值就好了(需先把运行的游戏关闭)。

3.(N)Mathf.clamp函数并没有限定值的范围

  自作聪明的用了clamp方法,后来发现并没有赋值,没有赋值当然就没有限定了。clamp函数是有返回值的,返回值才是限定的范围。很多方法不要光调用,人家的返回值是关键

4.(N)wheelCollider只允许加4个吗?

  当然不是,但因为我之前的自作主张在轮子上直接加wheelcollider,然后我给忘了,之后按书上的要求建空物体加,加到第5个发现加不了了。最后找到问题所在。

目前还不懂为啥我直接在轮子上加会搞的这么大。

5.(H)为什么[serializable]属性并没有让类里头的成员在inspector中出现?

  我怀疑是现在的List冲突了,但是去掉list依旧不行,感觉使用这个属性一点意义都没有,它到底有啥用。
  我先妥协了,创建两个Axleinfo吧,难受。
  受mentor指导领悟到,原来确实是能将类内成员序列化入unity,可显示在inspector上,但切记 [serializable]修饰类时这个类一定不要继承monobehavior

6.(E)书2.5.3节明显存在问题,update方法内连坦克position都没加,怎么可能实现运动。(我错了)

  只给了扭矩没有用,f = m*a 啊,等着还得自己算加速度,有加速度就得有最高速度,它书里目前这代码非常不对。还整了前驱和后驱,是否真的有用目前也感觉不出。
  我错了,确实可行,要注意到motorTorque是wheelCollider的内置变量,也就是说是wheelCollider帮我们做了物理计算工作,只需给个扭矩就给你算出位移与速度了。

7.(E)炮管随鼠标奇怪的扭转,不跟随炮塔。

是我自作主张的将三行汇聚一行,这没毛病,但汇聚之后却将LocalEuler的定义放到了118行,语句定义顺序不可小觑。

8.(H) partical包导入后prefab无效

  非常奇怪,无论用老版本还是新版本的书上的素材,无论用unity2018还是2019都不行。不信邪的我甚至打开了它第三章所用的整体资源包,果然就是不行。但它第三章的演示视频里确实是有爆炸效果。
  那就只有两种可能了,一是这个partical包实在太老了,估计得是5.x版本的才能用,二是他上传包的时候上传错了,总之爆炸特效还是自己搞个或者下载个吧。**
  我下载了detonator explosion,好用。

9.(E)炮弹射击音效声很短问题

  处理方式不对呗,我自作主张把音效挂在了炮弹prefab上,这个对象可是生成后很快就会被销毁的,销毁了上面的音效怎么可能播完嘛。这个问题其实瞬间就能发现,但是还是犯了这种低级错误。
  果然书里也说了这个问题,放到爆炸效果里确实是个好主意。

10.(H)炮弹攻击伤害爆表之谜

  这个问题确实困扰了我一阵,明明发射一发,怎么对面坦克直接GG了?刚开始以为是代码数值没调对,但左看右看也是对的,debug之后发现我的一发炮弹竟然debug出来两次,也就是说射了两发?再看代码,也没多调用方法啊,应该就是没问题,最后想会不会是距离过近了导致collision误认一发炮弹为两发,离远些打一炮还确实成了!然而事情没有这么简单。目前的情况让我意识到代码准定是没问题的,我知道速度过快容易穿模,但没听说过一次判定能判成两次啊,距离远近真的会影响有关系么,最后明白了其实是因为我在做坦克的碰撞体时把坦克分成了炮台与坦克身体两个碰撞体,而我那一发炮弹同时打到了两个碰撞体上。

11.(E)炮管上下旋转角度不对

  演示游戏的时候没有全屏,鼠标在屏幕外,这时进入屏幕,旋转方法就已经跟随鼠标转了,所以会有操作奇怪的感觉。

12.(E)坦克悬挂多个音源脚本怎么判断哪个是哪个

  当一个物件上需要挂多个声音的时候GetComponent就get不到对的audioSource了。比如说坦克上既需要引擎声,还得在发射炮弹时有发射的声。对于这种问题的解决方法,之前的micro-game里是直接将audio在hierarchy中划分出来,这样想播放哪个声音直接调用就好。我觉得这种解决方式更好一些。
  书里的解决方式是不用get从inspector中获取,而是用AddComponent直接往inspector中加(事实上之前它也是这么弄的,是我自己搞得get),怎么说呢,也确实可行。

13. (E)4.3.3节有一个错误,NoTarget方法最后minHp没有更新

  你不更新minHP的值岂不是每个坦克都满足血量要求了,遍历一遍将没有任何意义,这绝对是个错误。
  而这个错误之所以不容易发现的原因是因为这种小游戏,测试坦克时坦克数量不会多,尤其是单机版。
  另外这种找目标方式还可能导致NPC间互相决斗,但倒也不是不行。

14.(E)如何进入游戏即可发射炮弹,之后才有发射间隔

  我把炮弹间隔设为3秒,但刚进游戏之后如果想发射炮弹必须得等上3秒,有点不合理。
  解决方式为设一个变量,增加一个判定条件。

15.(E)记录点书中小错误

  一些变量名错误就不谈了无伤大雅。
  1)P135,GetBrakeTorque方法中的返回值应该是返回maxBrakeTorque
  2)P137,navigation于Window->AI->navigation。
  3)Tank类的trackmove不需在循环中调用。

16.(SH)坦克车速要么过快,要么过慢,容易打滑怎么办

  要么将wheelcollider的扭矩调低,启动速度也慢,调高了速度又太快。
  目前的感觉是自己实现车辆移动逻辑会更好,但准定更麻烦,我看第二版好像是自己简单实现了下,等着再好好看看,这个先不急。
  注意模型大小,把扭矩调小点,把质量调小点,就OK.
  更新,车辆容易翻倒的原因在于ForceAppPointDistance未调至车轮中心。
   为何刹车速度会那么慢,braketorque的效果根本不理想怎么优化?
   调大wheelCollider的forwardfriction,摩擦力不够大再怎么加大brakeTorque都没用

17. (E)4.7.3节巡逻逻辑并没有编写完善

  是因为我发现书里并没有实现PatrolStart方法,可能是觉得无伤大雅吧,就给忘了。然而事实上不编写完也不是不行。书中在update方法内通过判断Status来进行状态update,如果状态变了就调用changeStatus,如果变成attack模式就调用attackStart,patrol的话就是patrolstart。Attack Start它实现了,状态改变后直接更改坦克继续行动的目标地点为敌方坦克位置,但是其实Attack update里面也是这种操作,所以确实写不写都一样。而切换成Patrol的话呢,在PatrolUpdate内会判断当前目标位置走没走完,走完的话会随机分配一个巡逻点为目标。也是可行的。
  综上所述,就目前的功能需求,如果当切换成巡逻模式时你想立即前往随机巡逻点位置的话,就完善PatrolStart,否则的话它会先到达最后更新前敌方的位置,再前往随机巡逻点。同样可行。

18.(N)prefab要慎重删除

  我把hierachy中的tank挪到了asset中的prefabs文件夹下,它有两个选项,一个是create original prefab,一个是create variant prefab。这里要注意一定要选第一个,第二个是属于引用的性质,如果原本所在的地方被删除了,引用的prefab也会删除,而且无法undo。

19.(SH)AI坦克间互相不攻击问题

  这个问题排查可费劲了,情况是从出生点出生正常,寻路不太正常等着也得排查,就算进入范围后AI类里的target一直获取不到。
  在编写Battel模式之前还是好使的,说明BattleManager这里有问题,果然排查出判断是否为同一阵营的函数的判断条件有问题,但改完之后依然不对,还是有问题。
  太奇怪了,检查了一整遍代码都没有问题。运行游戏可以观察到我之前target的debug代码并没有输出,也就是说一直没有获取到target,结果最后竟然debug到AI类连update方法都没有更新!
  啊,原来是因为代码没保存,写糊涂了糊涂了。

  终于找到问题所在,果然还是这个方法的问题,把它注释掉就好使了,那就仔细看看这个方法到底哪有问题。
  太奇怪了!代码怎么看哪里都没有问题,但是debug输出的结果异常奇怪

  这个问题真是困扰了我好久好久,最终原因你猜是怎么回事?
是构造函数问题!!!以后谨慎使用new!!!

  上面的注释内容竟然就是罪魁祸首,而我是怎么发现的呢,Unity给警告了,以后一定要注意Unity的警告!!
  更新一下,上面的解答确实是问题的原因,但不是终极的答案,事实上问题的本质还是因为BattleTank类设计错了,我把它继承与MonoBehavior了!! 继承于monobehavior的类是继承了Start()啊Update()啊之类的函数的,而我的BattleTank类并不需要实现这些方法。它只需要被正常的new就好了,所以以后要new也行,new的类别瞎继承就行

20.(N)击杀图片显示问题

  以前的操作是这样的。

  就是把这个图片对象显示后再延迟执行1秒,在那个方法里把对象关掉。当时测试时是直接把hp调成0,确实可行。
  其实问题太大了,且不谈是自己杀自己,最大的问题是这是被攻击的坦克啊,击杀图像应该加到攻击者上!
  attackTank.GetComponent<Tank>().killImage.SetActive(true);这样能够让坦克显示图片了,怎么关闭呢?没办法再用Invoke了,我想到的办法是在这个图像下面挂个脚本,让他一秒关闭。

21.(N)坦克寻路谜之走法问题

  开始游戏后坦克总会先在出生点前后退,然后再前往路标点。
  将调试代码放到getMotor可以看到,获取到的位点从头到尾都是坦克的出生点,也就是说我设置的巡逻点根本没有起到作用,前往路标点也都是碰巧的假象。准定是代码调用有问题。
  层层方法调试最后判断出是在Path的InitNavMesh中出现了奇怪之处,调用CalculatePath后,会出现从起点到目标点的正确路径,而我这路径中间没有障碍物,所以就起点和终点两个点,明显是更新有问题,一直在起点。那就是函数没有正确判断是否已经到达目标点了呗,果然, 在AI类里的update中我竟然把判断方法给注释掉了!当时可能是觉得这个判断没用了吧,结果搞出这个幺蛾子。

22.(SH)游戏开始时有半秒长的6下咯吱声

  6下咯吱声,在编写出生点之前是没有这种情况的,结合我生成6辆坦克。是可以先把错误定位在出生点范围排查。
   坦克预制件应该没问题。我将游戏生成出来运行,只有一下“吱”的声音,而且声音不大,那也不对,在unity里运行和在exe里运行为什么会不一样?而且我发现咯吱声不一定是6下,会有变化。
  mute audio之后就没声了,准定是哪个audio有问题。可audio要是有问题的话为什么之前没有咯吱声,
  重新尝试不出生,没有咯吱声。出生多个坦克,将camera放远,也没有咯吱声。出生敌我阵营各出一个坦克,没有咯吱声!敌方出3个坦克,我方只要是一个,就没事!
  所以可以怀疑原因出在我距离我方其他坦克过近了,不,依旧不对,离的远也照样有咯吱声!
  到底为什么生成敌方坦克没事,生成我方的只要多一个就会有咯吱声呢?

 public void StartTwoCampBattle(int n1, int n2){Transform bp = GameObject.Find("BornPlace").transform;Transform bpCamp1 = bp.GetChild(0);Transform bpCamp2 = bp.GetChild(1);if(bpCamp1.childCount < n1 || bpCamp2.childCount < n2){Debug.LogError("amount not enough");return;}ClearBattle();battleTanks = new BattleTank[n1 + n2];for (int i = 0; i < n1; i++){GenerateTank(1, i, bpCamp1, i);}for (int i = 0; i < n2; i++){GenerateTank(2, i, bpCamp2, n1 + i);}Tank playerTank = battleTanks[0].tank; // 我将player tank改为哪个坦克都一样有噪音,噪音声还有不同。// playerTank.ctrlType = Tank.CtrlType.player;CameraFollow cf = Camera.main.gameObject.GetComponent<CameraFollow>();cf.SetTarget(playerTank.gameObject);}public void GenerateTank(int camp, int num, Transform bpCamp, int index){Transform trans = bpCamp.GetChild(num);Vector3 pos = trans.position;Quaternion rot = trans.rotation;GameObject prefab = tankPrefabs[camp - 1];GameObject tankObj = Instantiate(prefab, pos, rot);Tank tankScript = tankObj.GetComponent<Tank>();tankScript.ctrlType = Tank.CtrlType.computer;// battleTanks[index] = gameObject.AddComponent<BattleTank>();battleTanks[index] = new BattleTank{tank = tankScript,camp = camp};Debug.Log("batcamp: " + battleTanks[index].camp);//这里证明了确实成功赋值了}

  这是生成的方法,我觉得方法是完全没有问题的。
  我先妥协了,因为camera上面挂的audio listener, 我先将audiolistener关掉,然后在camera脚本里LateUpdate中把它开开,这样最开始的咯吱声就没了。这只能是个缓兵之计,治标不治本。

23.(E)一些小tips

  1)#region的作用:可将代码折叠起来,用Ctrl+M,Ctrl+H也可以达到同样的效果。
  2)想要使用Enum类的方法需要using System
  3)transform也能GetComponent,效果跟GameObject的一样。
  4)new Color里面的参数最大为1,不是255,所以要除以255

24.(N)5.3节错误 PanelLayer并没有定义

  这是一个很大的漏洞啊。难点主要在于1.现在脑子一片浆糊,可能是累了。2.说实话这种代码和资源分离的方式确实有些厉害,我得好好消化一下。直接在UI上创脚本set active啥的实现起来很简单,但是要是用代码写出来实现,架构方面确实需要思考思考。
  具体情况是这样的,PanelManager里定义了这个为枚举,PanelBase里面没定义是啥,而它俩必须是一个东西,因为在PM中有PB对PM的赋值的,是同一个东西,那就将PanelBase继承PanelManager吧,虽然书里不是这么写的,但书也不对啊。
  试了一下代码确实不报错了,是没问题的,但是UI界面还是没有正常显示,我发现生成的Panel直接跑到了Scene底下,没有挂到canvas下面当然不会正常显示。但是这不是继承的错,应该是OpenPanel方法的问题。
  最后排查原因是hierachy中的名称大小写与方法内的没对上,导致SetParent未成功。
  更新一下,看了第二版书里对于PanelManager的处理方法是将它设为静态类,确实更好。
  再更新,由于出现问题26,我发现根本不能用继承!在BasePanel中用
public PanelManager.PanelLayer layer; 其实就好了。具体的panel类中也是同理。

25. (E)九宫格的使用


  如图所示,这是bg2图片,不要动蓝色的点,动绿色的点,会将图片分成9个格子。那这么切分之后会出现什么样的效果呢?中间区域的大小会随着拉伸缩小而拉伸缩小,四个角的格子不会变,四条边的格子上下边横向拉伸,左右边纵向拉伸。然而让我百思不得其解的是为什么我这么划的线而切出来的是这样的效果?

  真相只有一个,我觉得应该是因为这个图片太大了,panel会首先显示中间区域的图片,然后基本就填满了。

26.(H)UI界面关闭不了,显示错误The given key was not present in the dictionary.

  类千万不要瞎继承!!!要注意顺序,关不了按理说是close方法的事,我调试半天发现dict明明之前add成功了,一到close里dict中的数据就没了。关键是close方法怎么看怎么对。
  最后发现dict的key是string,但是value是PanelBase,而我让PanelBase继承了PanelManager! 我成功的在基类声明了子类的成员变量,成功的导致了未定义行为。

27. (E)P186 OptionPanel类OnStartClick方法有错误

  我发现选完数量后按开始游戏又报了26问的错误。那准定是OptionPanel里的这个OnStartClick方法有问题了,果然,没事闲的close TitlePanel干啥,人家都已经close过一次了。把那句去掉就好了。
  这本书的问题还是有不少的。
  更新一下,确实是有问题,但有更好的解决办法。用之前的办法的话点开始游戏再关掉的话界面就没了,正确的做法是去TitlePanel里把OnStartClick里面的close去掉

28. (ENHSH)一些增加与修改

(时间顺序,非难度顺序)
  1)将clearBattle放到win方法中,避免游戏结束后还能开炮、感受到坦克移动等。
  2)在GenerateTank中通过判断阵营,将不同阵营的坦克旋转180度(rotate),免得生成的都是同一方向的还得转回去干仗。
  3)更改cameraPos,使相机对着坦克屁股,而不是一开始对着侧面。
  4)更改shell射速为300m/s,说实话,百度上说炮弹得1700m/s,但那太快了都看不着炮弹了,就不追求真实性了。
  5)生命条使用UGUI。
  6)游戏运行时右上角添加设置按钮,可返回主菜单或退出游戏。
  7)修复设置按钮点击后按钮没有隐藏问题
  8)增加敌人与友军的hp条显示
  9)自身血条增加百分进度。
  10)坦克速度优化
  11)障碍物检测逻辑编写
  12)路标点优化
  13)添加退出游戏按钮,添加自身死亡时相机转到队友身上功能。
  14)增加坦克重置功能,坦克翻了的时候会掉20滴血,然后重置到随机的出生点。
  15)增加了状态更新功能,自身死亡后可看到友军的AI逻辑状态。
  16)实现摇杆功能,手游整体UI实现
  17)修复死亡后开炮按钮与HP条依然存在
  18)修复坦克自杀(翻倒)后无法判断队伍是否胜利问题。
  19)修复友军或敌人的血量条与血量不对应问题。
  20)将躲避模式的判定条件放入attackupdate中,而不是onattack里,被没被打我的血量要是小于敌人的,并且小于百分之50,都进入躲避反击模式。
  21)修复血量掉至0.几%时显示为百分之0。
  22)修改坦克翻车判定为靠rotation而不是四轮离地,避免腾空时间长也重置
  23)增加自身血量设置,因此我还得修改血量条的逻辑,之前都是按100搞的,以后这种东西都该提前就想好。
  24)增加敌我数量显示
  25)增加小地图显示,自身为白色,我方为红,敌方为蓝,将minimapcamera挂到maincamera下,别挂到tank下。
  26)增加新的小口径炮弹,增加瞄准功能。

29.(E)Terrain如何变好看,怎么添加多层材质?

  这个问题本来想放到28问里头,但后来因为一个问题,所以特意单独列出来了。首先,Terrain的paintTexture在这里。我之前在paint details上add的Texture,搞得不堪入目,当时还很奇怪怎么会这样。paint details paint的是一些小物件,是竖着来的,不是paintTexture。

  本来问题应该就圆满解决了,但是我发现add的texture怎么都paint不上去,这又是怎么回事??原来Terrain的材质一定要用default的,我当时换成了自己设的材质,所以不行。

30.(H)ToLua的使用问题

  之前没学过,感觉会遇到些问题,我会新开一篇博客专门写写。

31. (SH)AI坦克间会相撞,如何避免,以及如何实现躲避逻辑问题

  书上讲说使用NavMeshObstacle避免相撞,我在AI类增添这个组件,让tank obj上挂上这个组件,size调整这个障碍物的大小,试了半天发现根本不好使,仔细看文档感觉这个东西是配合NavMeshAgent来使用的。而关键是书里根本就没用它,NavMeshAgent有一套自己的运行逻辑,包括速度调整,甚至能保证agent间不会相撞。也就是说书上说的根本就是错的,NavMeshObstacle是加到障碍物上的,有那种运行的障碍物,或者静态的,都可以加,NMA和NMO根本不能加到同一个物体上,应用类型就不一样。
  我想这种避免碰撞的逻辑先自己实现一下吧,先不用NMA了。这应该会很麻烦,目前的想法是写一个判断方法实时判断前方一定范围内有没有障碍物,有的话就踩刹车往后撤,这样就能保持一定的范围距离不相撞了。
  我使用了射线检测的方式
  调的太艰辛了,用了两个协程嵌套来实现遇到障碍物后撤,要注意有些bool在协程内进行判断,在外面的话,人家是直接顺序执行的不会等几秒,
  新增avoid状态,判断当前血量小于50%且比敌人血量小时进入avoid状态,进入状态后会寻找距离当前位置最近的障碍物,找到躲避点,直到敌人目标消失退回patrol状态

   void AvoidStart(){GameObject[] obs = GameObject.FindGameObjectsWithTag("obstacle");float minDistance = float.MaxValue;Transform tar = null;foreach (var ob in obs){float distance = Vector3.Distance(ob.transform.position, transform.position);if(distance < minDistance){minDistance = distance;tar = ob.transform;}}float maxDistance = float.MinValue;int count = tar.childCount;Vector3 targetPos = transform.position;for (int i = 0; i < count; i++){float distance = Vector3.Distance(tar.GetChild(i).position, transform.position);if(distance > maxDistance){maxDistance = distance;targetPos = tar.GetChild(i).position;}}path.InitByNavMeshPath(transform.position, targetPos);ShowOrder("干不过干不过,进入躲避反击模式");Debug.Log("Avoid Start");Debug.Log("AvoidPos:" + targetPos);}void AvoidUpdate(){if (target == null) //AvoidUpdate会一直持续到target = null再结束{avoidFire = true;ChangeStatus(Status.Patrol);return; //这里得return啊,否则待会要调用target。}Debug.Log("Avoid Update");float fireInterval = target.GetComponent<Tank>().fi;GameObject[] obs = GameObject.FindGameObjectsWithTag("obstacle");float minDistance = float.MaxValue;Transform tar = null;   //找到最近的障碍物foreach (var ob in obs){float distance = Vector3.Distance(ob.transform.position, transform.position);if (distance < minDistance){minDistance = distance;tar = ob.transform;}}if (path.isFinished){Debug.Log("到达Avoid点");ShowOrder("到达躲避点");Vector3 dir = target.transform.position - transform.position;if(Physics.Raycast(transform.position,dir,out RaycastHit hit, 10)) {if(hit.collider.CompareTag("obstacle")){if(fireInterval < 2 || fireInterval > 10)  //如果敌方刚发射完不足2秒,或者长时间不发射{path.InitByNavMeshPath(transform.position, target.transform.position);  //出来攻击Debug.Log("出来攻击");avoidFire = false;}}}else//如果走过油了,坦克速度快,极有可能{Vector3 targetPos = FindAvoidPos(tar);path.InitByNavMeshPath(transform.position, targetPos);}}else{if(avoidFire == false)//如果还没有到目标点,且目标点是敌方坦克(反击状态){if((fireInterval > 4 && fireInterval < 7)||tank.fi < 2)//该躲了{Vector3 targetPos = FindAvoidPos(tar);path.InitByNavMeshPath(transform.position, targetPos);}avoidFire = true;}}}

32. (SH)血条并没有成功减少

  非常奇怪,当时做出来时明明是成功了的,现在突然发现被打了血条不会往下掉。关键是看不出代码哪里有问题。

  我就是写了个这个脚本挂到了slider图片底下。关键是debug出来fillamount确实变对了,但是图片就是不减。这是为什么?

  这个问题真是排查了好久。以至于我都懒得写过程了。当你不知道问题出在哪时会从各个方面做比较,真是各个方面反复测试。有些自认为不可能的事都会试上一试以防万一。最后我突然惊觉是图片渲染顺序问题。我生成了好几个坦克,第一个坦克是我操纵的,其他坦克也有canvas,因为是用的一个模型啊!,每个canvas都是overlay模式,这样最后一个坦克的hp条会被渲染上!在脚本里把AI坦克的canvas去掉就好了。这个问题真的是不大,但是找到底错哪很费解,以后一定要注意图片渲染顺序。
  另外没必要在hp条下挂个脚本,在坦克类的beattacked方法里更新其实就好了,我想实现那种血条平滑掉的效果,所以就放到了playerCtrl方法里实现。
  更新一下,不能放到playerCtrl里,这样多人战斗时你死了你的血条不会往下掉,因为你的状态已经变成了none,老老实实放到update里吧。

33.(H)P129页错误

  这个错误比较严重,但是也比较好发现。 NextWayPoint方法中isfinish后需要返回如果不返回的话index会继续往上加,再索引就错了。这个错误也是我现在遇到了null reference错误才发现的。
  但奇怪的是依旧还是会出现null reference的情况,查了半天查不出来为什么,明明就是调用了两个函数,怎么回事。
  更新一下, AI坦克击杀目标后我只将状态更新为Patrol,并没有将target清除掉,所以

34.(H)实现手游摇杆功能

  在网上找了好几个教程都不尽人意,但是读其中一篇却让我发现了另一绝佳途径,assetStore里面下载一个,我下载了个JoyStick,发现很棒啊,这样啥都有了,关键是能看它是怎么实现的,非常方便学习。

35.(SH)实现滑动屏幕右半边旋转相机功能

  说两个耗费大量时间搞出来的点1.得用Touch进行判断了,用mouse的话是不行的。 2.用Screen.width直接获取屏幕的宽度
  细节如图

  更新一下,依旧没有完美实现,当屏幕先按左半边(控制摇杆),再按右半边时,没有办法旋转相机。先按右半边的话,两边就可以同时操作了。
  我竟然没有注意到用的是touches[0],硬生生尝试了快俩点。把那个换成touch啊啊啊啊。
  再次更新,我注意到电脑上与手机上滑动的速度不一样,突然让我意识到了不同分辨率的手机使用相同的相机转速的话是不行的!,分辨率大的移动一小点就会转很多啊。将转速设为与分辨率成负相关就好了。

36.(H)第四章重大问题:changestatus()并没有更新AI的status状态

  这么一个明显的错误一直没有发现,直到我自己写躲避逻辑,我发现AvoidUpdate一直也没调用啊,再一仔细看,我服了,这么重大的明显错误竟然一直没有注意到,changestatus里就只是调用了个start好不好,其实ai的status一直都是patrol没有变!,艾玛,估计连作者都没意识到。因为游戏运行起来确实OK,因为他的AI逻辑太简单了,遇到敌人之后就往敌人那走,干,敌人没死patrolupdate就会一直返回,所以运行起来有正确的假象。

37.(E)翻车逻辑判定更新

  之前的四轮着地判定不太科学,如果腾空时间超过3秒就会重置,所以我把3秒后的检测换成了靠rotation,有一个需要注意的点啊,rotation的xyz不是inpector中的xyz,另外我写的这个实在太啰嗦了,目前没想到更好的招。

38.(E)书上PanelManager的closePanel方法存在漏洞

  这也是遇到问题了才发现的,一定要注意字典类型如果获取不到key是会直接报错的,不会返回null,如图所示,必须用containskey方法先判断一下

  更新一下,使用TryGetValue更方便还减少消耗

网络游戏开发实战-坦克大战学习问题记录相关推荐

  1. 《崔庆才Python3网络爬虫开发实战教程》学习笔记(5):将爬虫爬取到的数据存储到TXT,Word,Excel,Json等文件中

    本篇博文是自己在学习崔庆才的<Python3网络爬虫开发实战教程>的学习笔记系列,此套教程共5章,加起来共有34节课,内容非常详细丰富!如果你也要这套视频教程的话,关注我公众号[小众技术] ...

  2. python坦克大战游戏_Python开发的坦克大战游戏

    python开发的坦克大战游戏importpygamefrom pygame.sprite importSpriteimportsysimporttimeimportrandom SCREEN_WID ...

  3. 微信小游戏开发之坦克大战(比羊了个羊还好玩系列)

    现在很多公司开始使用游戏化的方式去做产品,让产品呈现给用户时更好玩,以达到增加用户粘性,提升DAU的效果. 同时随着硬件与底层系统的发展,用户的终端对动画的表现能力也越来越强,很多APP以引导用户互动 ...

  4. 马士兵坦克大战学习笔记(一)

    java初学者对于马士兵坦克大战的个人学习笔记及代码问题总结(第一阶段), 1.系统自动初始化了Graphics g参数 2.设计原则:高内聚,低耦合: 一个模块中的各元素之间的紧密程度越高,内聚性越 ...

  5. 《崔庆才Python3网络爬虫开发实战教程》学习笔记(3):抓取猫眼电影榜单TOP100电影,并存入Excel表格

    本篇博文是自己在学习崔庆才的<Python3网络爬虫开发实战教程>的学习笔记系列,如果你也要这套视频教程的话,关注我公众号[小众技术],关注后回复[PYTHON],无套路免费送你一个学习大 ...

  6. 《崔庆才Python3网络爬虫开发实战教程》学习笔记(4):解析库Xpath的使用方法总结

    本篇博文是自己在学习崔庆才的<Python3网络爬虫开发实战教程>的学习笔记系列,如果你也要这套视频教程的话,关注我公众号[小众技术],关注后回复[PYTHON],无套路免费送你一个学习大 ...

  7. 【Java游戏开发】坦克大战(附源码+课件+资料)

    本课程讲解了一个坦克大战游戏的详细编写流程,即使你是刚入门java的新手,只要你简单掌握了该游戏所需要的javase基础知识,便可以跟随教程视频完成属于你自己的坦克大战游戏!同时还可以加深和巩固你对面 ...

  8. android网络游戏开发实战pdf_Python项目开发实战+第2版PDF高清文档下载

    本书来自真正的开发现场,是BePROUD公司众多极客在真实项目中的经验总结和智慧结晶.作者从Python的环境搭建开始讲起,介绍了Web应用的开发方法.项目管理及审查.测试与高效部署.服务器调试等内容 ...

  9. 01-2016.07-小学期游戏开发《坦克大战》

    <坦克大战>游戏整体设计及框架 1.游戏功能描述 按下空格键后游戏开始,"空格开始"消失,载入地图,并把玩家坦克设置在指挥部左侧. 在游戏进入之前,可选单人对战or双人 ...

  10. 微信小程序之坦克大战学习

    1.问题一:在menu.js中需要使用到const.js文件中的变量,怎么办?如下图: 解决:在const.js文件中写上module.exports={},大括号里面写对应的变量对,如下图: 然后在 ...

最新文章

  1. Spring Boot与Redis的集成
  2. java冒泡函数解释,JS DOM操作 函数 事件 阻止事件冒泡
  3. 【bzoj2724】[Violet 6]蒲公英 分块+STL-vector
  4. 产后抑郁症的食疗方法有什么
  5. leetcode练习(简单总结做过的题)
  6. webpack4.x版本与webpack-cli高版本之间存在的bug
  7. python3循环一直到一个值结束_一步一步学Python3(小学生也适用) 第十七篇:循环语句for in循环...
  8. python之模块calendar(汇集了日历相关的操作)
  9. 5G关键技术研究方向
  10. GCC帧指针的开启与关闭以及反汇编测试
  11. HTTPS那些事(三)攻击实例与防御(转载)
  12. 通过输入方式在Android上进行微博OAuth登录
  13. Guava学习笔记(一):Guava新增集合类型-Multimap
  14. 计算机组成与体系结构(软件设计师备考笔记)
  15. vs自拉软件全名_vs全新操作软件说明书
  16. Cognos函数(二十二) - ancestor
  17. 单样本t检验之汽车引擎排放是否达标
  18. 12.1 hashlib--安全的哈希计算和签名库
  19. 回车换行问题0x0D和0x0A
  20. Fastboot enhance flash

热门文章

  1. 阿里云服务器租用费用
  2. RTP传输JPEG图片到VLC实时播放(代码)
  3. 35个优秀的电子商务网站设计案例
  4. gif在线转换html,在线mp4转换gif
  5. Mary_Morton [XCTF-PWN][高手进阶区]CTF writeup攻防世界题解系列17
  6. 在Foxmail邮件客户端登录263企业邮箱
  7. HttpWatch使用教程
  8. 如何检测android手机是否支持3g网络或者4g网络 源码,iOS中怎么判断当前网络环境是2G/3G/4G/5G/WiFi...
  9. POJ3658Matrix( 双重二分+负数+死循环)
  10. Electron无边框模式下禁止双击最大化窗口