正式的2d版本开始了。
仿照之前的3d版,先将一些对象进行设置。
小球设置:
1-添加Collider
用Circle Collider合适,并且可以设置Radius,控制碰撞体大小
同样赋予一个PhysicMaterial,2d版中参数较少,没有Friction和Bounciness的混合,也没有各向异性。
2-脚本:
其中小球是有一个朝向的,小红点示意其方向,这个方向在空中运动时,与速度方向一致;在齿轮上时,径向朝外。
void HeadControl(){ heroV = rigidbody2D.velocity; if(heroV != Vector3.zero){ transform.rotation = Quaternion.FromToRotation(heroDir,heroV.normalized); } else{ if(transform.parent.gameObject){ Vector3 wheelCenter = transform.parent.gameObject.transform.position; Vector3 dir = transform.position - wheelCenter; transform.rotation = Quaternion.FromToRotation(heroDir,dir.normalized); } } }
豆子设置:
直接消失不够有视觉效果,需要有一个消失的过程动画:逐渐变大,逐渐透明。这个就直接用Unity的自带动画系统实现。
一个Curve来实现Scale,另一个Curve来实现alpha透明。当动画播完,在关键帧上增加Destroy对象的事件。
比较方便的是,这个事件可以调用脚本中的方法。给豆子挂上脚本,其中增加
void DestroyBean(){//destroy itself when the animation is over Destroy(gameObject); }
齿轮设置:
1-Collider
同小球
2-脚本
把之前3d版本的代码直接搬了过来,果然,出现了问题:
小球与齿轮碰撞,没有转动表现了。
是碰撞出问题?还是二者的layer不同造成的?搜索了一下,果然很多说trigger没有用了,再一看,原来3d版本中的
void OnTriggerEnter(Collider collider){
}
2d中方法函数并不是同一个,而是:
void OnTriggerEnter2D(Collider collider){
}
原来懒惰如我者,比较多。基本的原理是一样的,而方法有差别,之后2d开发中,首先要看一下API。
3-顺时针还是逆时针
原版中,齿轮的转动分顺时针和逆时针,体现的效果,类似小球以不同方向入射,带动齿轮以不同方向旋转。
做一个图看看:
上方的A球,会使得齿轮顺时针转动;下方的B球,会使得齿轮逆时针转动。
回想啊,回想高中物理。将小球速度分解为径向和切向,切向的速度冲量,将给与齿轮一个力矩。那么V(未分解)与Vr(径向)的相互关系,也就是二者的空间顺逆关系,就决定了齿轮的转动方向。
之前一直不知道Vector.Cross(Vector3 a,Vector3 b);有啥用,这里就用上了。
向量的X乘,得到一个向量,这个向量在Unity中符合左手定律。
于是,在目前我的2d游戏中,默认的平面是x-y平面,这个Cross得到的向量将垂直于x-y平面,根据其z值的正负判断其垂直向上还是垂直向下,也就得到了V(未分解)与Vr(径向)空间顺逆关系。
void OnTriggerEnter2D(Collider2D hero){ Vector3 heroV = hero.rigidbody2D.velocity; Vector3 dir = transform.position - hero.transform.position; Vector3 project = Vector3.Project(heroV,dir); Vector3 cross = Vector3.Cross(heroV,project); if(cross.z <0f){ isClockWise = true; } else{ isClockWise = false; } }
4-再有一个细节,小球在齿轮最外沿
当小球速度过高的时候,碰撞检测发生时,小球可能已经在齿轮内部,需要将它拉到最外沿,使得两园相切。
算法比较简单:小球position = 用于确定方向的向量*模长 + 父级position
hero.transform.position = transform.position + (wheelSize+heroSize)*((hero.transform.position-transform.position).normalized);
因为齿轮与小球都是正圆,也就是要得到两个Sprite的尺寸
在unity 2d中,得到这个值,可以用SpriteRenderer.bounds.extends.x,SpriteRenderer.bounds.extends.y的方法来获得
wheelSize = GetComponent<SpriteRenderer>().bounds.extents.x;
顺便记录一下unity 2d 中,关于单位的设置方法:
摄像机远近 + 多少像素=1个单位
这两者共同决定了游戏比例
这两个默认值下,一个屏幕大小比例就确定下来了
细节问题解决了之后,游戏慢慢成型。
原文:http://www.cnblogs.com/tianiao/p/3538720.html