克隆Wheekling——有些细节问题

正式的2d版本开始了。

仿照之前的3d版,先将一些对象进行设置。

小球设置:

1-添加Collider

用Circle Collider合适,并且可以设置Radius,控制碰撞体大小

同样赋予一个PhysicMaterial,2d版中参数较少,没有Friction和Bounciness的混合,也没有各向异性。

克隆Wheekling——有些细节问题

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对象的事件。

克隆Wheekling——有些细节问题

比较方便的是,这个事件可以调用脚本中的方法。给豆子挂上脚本,其中增加

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-顺时针还是逆时针

原版中,齿轮的转动分顺时针和逆时针,体现的效果,类似小球以不同方向入射,带动齿轮以不同方向旋转。

做一个图看看:

克隆Wheekling——有些细节问题

上方的A球,会使得齿轮顺时针转动;下方的B球,会使得齿轮逆时针转动。

回想啊,回想高中物理。将小球速度分解为径向和切向,切向的速度冲量,将给与齿轮一个力矩。那么V(未分解)与Vr(径向)的相互关系,也就是二者的空间顺逆关系,就决定了齿轮的转动方向。

之前一直不知道Vector.Cross(Vector3 a,Vector3 b);有啥用,这里就用上了。

向量的X乘,得到一个向量,这个向量在Unity中符合左手定律。

克隆Wheekling——有些细节问题

于是,在目前我的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个单位  

这两者共同决定了游戏比例

克隆Wheekling——有些细节问题

克隆Wheekling——有些细节问题

这两个默认值下,一个屏幕大小比例就确定下来了

细节问题解决了之后,游戏慢慢成型。