2013年9月16日 星期一

Unity3D研究院之高尔夫球推杆游戏Demo(三十四)

http://www.xuanyusong.com/archives/1699

          MOMO虽然要告别Unity3D开发一段时间,可是我的博客永远不会停止对技术的渴望。前两天用了两个小时帮公司做了一个简单的小DEMO,今天我把它分享出来。如下图所示,游戏的操作很简单,控制旋转的方向,保持小球朝向着改方向发射,知道小球被球杆打进洞,表示推杆完成。


我说明一下这个DEMO中使用到的一些技术难点。
游戏场景中的这支球杆模型是没有动画,为了让球杆有击打小球的动画,我们可以使用旋转球杆的中心来完成。我把球杆旋转分为两部分,第一部分是球杆从起始点向上旋转,第二部分是球杆从最高点向下旋转击球。
有一个重要的方法可以很轻易的帮我们完成旋转插值的计算。
Quaternion.Lerp()方法,参数1表示改模型其实的旋转角度,参数2表示该模型结束的旋转角度,参数3表示该模型从起始角度旋转至结束角度所使用的时间。把这个方法放在Update方法中,就好比每一帧都会计算当前模型旋转中的角度,只到它旋转结束。

void Update()
{
           transform.rotation = Quaternion.Lerp(transform.rotation,upPoint,Time.deltaTime * 2.8f);
}


如此一来我们就可以使用纯代码完成球杆击球的一个完成动画。
通过按下“向左”、“向右”来调整击球的角度。
使用RotateAround()方法,让球杆始终围绕着小球在Y轴方向旋转。参数1表示围绕旋转参照点的位置(小球的位置)参数2表示围绕旋转的角度,Vector3.up就是表示Y轴旋转,参数3表示一次旋转的速度。
gan.transform.RotateAround(qiu.transform.position,Vector3.up,2 * Time.deltaTime);


然后是绘制球杆击打小球的目标方向线,也就是图中绿色半透明的线,他会始终计算小球击打的方向。其实它就是一道简单的数学题,忽略Y轴,已知平面中的一个点、 一个角度、一段距离,求另一个点的位置,我的做法是这样的,100就表示距离,把线画出来即可。


void DrawHitLine()
{
 hitPoint = gan.transform.localRotation * (-Vector3.forward);
 hitPoint = (hitPoint.normalized *100) + qiu.transform.localPosition;
 lineRenderer.SetVertexCount(2);
 lineRenderer.SetPosition(1,qiu.transform.localPosition);
 lineRenderer.SetPosition(0,hitPoint);
}

最后是将小球打出,计算一个角度,施加一个力就可以。

Vector3 vecsphere = gan.transform.localRotation * (-Vector3.forward);
qiu.rigidbody.AddForce(vecsphere * 5000,ForceMode.Force);



这里说一下localPosition localRotation localScale  与 Position Rotation 的区别。 在U3D中我们可以在游戏对象下面绑定子对象,加local的表示这个位置与旋转是相对父对象的位置,开发中只该对象是某对象的子对象时尽量使用 localPosition localRotation localScale 否则你会发现你的坐标非常混乱。因为如果使用Position Rotation 它和监测面板视图中的位置是不一样的,因为目前你的对象是在子对象中、自对象的坐标永远是相对父对象的坐标。

最后是这个高尔夫球游戏的DEMO,欢迎大家下载。 今天非常高兴,因为MOMO的博客备案经历了5次备案,终于通过拉,高兴,哇咔咔~