103
社区成员




在Unity当中的GridLayout组件进行一些动态的排布,首先要对于当前的排布方式进行选择,其次在对于每一张卡牌的位置进行计算,并且在Update当中进行更新。
使用原因:预制的GridLayout会导致卡牌排布出现BUG,所以需要对于手牌的位置进行计算。
此次的设计为手牌数目大于三的时候为扇形排布,手牌数小于三的时候为直线排布,所以首先需要编写相关判断函数,此处仅作判断功能。
同时我们需要在手牌数变化的时候调用该函数,即需要在抽卡以及手牌打出的时候调用该函数。
(此处为抽卡调用)
(此处为卡牌打出时调用)
线性排布相关函数说明:
使用一个Vector3链表来记录每一个卡牌的位置,此处,对应每一张手牌,在链表当中添加对应的Vector3,也就是位置,此处具体数值需要根据项目相关的分辨率进行计算,此处仅展示计算方法,为根据当前预设的宽度,除以当前手牌数-1,来计算卡牌的水平位置,至于垂直位置不需要调整,生成一个新的Vector3变量,并添加到链表当中。
(具体展示)
扇形排布:同上方,不过此处还需要设置开始的角度以及结束的角度(总不能360度排布吧),此处StartAngle以及EndAngle来储存两个角度。此处同样通过计算手牌的数量,来平分角度,此处为Mathf.Cos(angle)*radius,Mathf.Sin(angle)*radius - radius来计算。从而得到相关的旋转角度。
(效果展示)
展示函数
展示函数为放在Update()当中,其中Vector3.Lerp为生成所给出的两个变量中的一个中间变量,而参数值为第三个变量,此处使用的是Time.deltaTime其实现的效果是让卡牌打出时,能够 有一个过度动画,使得卡牌可以平滑移动到目标位置,而不是瞬移过去。
此处出现的最大的问题并不是这个算法本身,而是与卡牌打出这个效果联动。可以看到,在卡片打出的时候是有一个GameObject.destroy的函数,该函数的效果是说消除当前的游戏体,从而实现卡牌打出。
但是Unity有一个机制的问题,当GameObject被销毁的时候,在该帧当中其实还是没有销毁的,从而导致在计算手牌数的时候,计算的手牌数其实还是打出前的手牌数,然而在手牌展示的时候,按照对应的手牌数调用实体的时候,这个时候已经到了下一帧,此时Gameobject已经销毁了,就会找不到对应的游戏物体,从而触发BUG,会直接导致游戏卡死。
解决的办法是说,在调用的时候,需要判断当前Gameobject是否存在,即下方HandCardList[i]!=null这一函数
此函数仍为Update当中的判断语句。
其实也是个人第一次使用动态排布,在Update()当中编写的时候其实会很容易出现一些BUG,以及提升一些资源的消耗,但是鉴于该功能需要每一帧更新,所以不得不去放在Update当中,也就是对于一些位置的判定,不再是默认的GridLayout预制,而是令其通过函数计算来得到位置。