unity3D魔方
在最开始想要写魔方的时候,考虑的第一件事就是怎么让魔方一面的方块跟着轴心旋转。
网上有一个工程是用按钮,来控制魔方的转动,而我想要实现的是透过手指的触碰魔方来使的魔方旋转
核心想法
使用向量的点乘和叉乘来获取方块并控制方块的旋转,在鼠标点击方块的首先在鼠标点击魔方时,获取点击点的信息,包括点击的点和此处的法线,之后在鼠标拖拽后获取鼠标运行的方向,它叉乘法线得到垂直于二者的一条法线,然后用得到的法线点乘六个原始轴,取值为45度以内的轴为转动轴,则能得到所要转动的层和转动方向,最后这一层开始转动。(六个原始轴代表unity中的上,下,左,右,前,后)
鼠标点击到魔方时,我们要获取手指点击的点和手指点击的物体
附上鼠标点击到魔方时所进行操作的代码
if (Input.GetMouseButtonDown(0) && isRun)
{
//从屏幕发出一条射线到鼠标的位置
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
//定义一个获取射线目标点物体的变量
RaycastHit hitStart;
//从刚才点击屏幕的射线的初始点,发射一条跟刚才射线方向一样的射线,并返回射线目标体的属性
if (Physics.Raycast(ray.origin, ray.direction, out hitStart))
{
//鼠标点到的物体就是射线碰触到的目标物体
cubeObject = hitStart.transform.gameObject;
//获得当前物体的法线
normal = hitStart.normal;
//鼠标点击的点就是射线碰触到物体的point
mouseStart = hitStart.point;
}
}
手指在移动,而射线每时每刻都会射出,鼠标点击的位置就会发生偏移,点击的点就会发生偏移,我们需要记下一开始手指点击的点
在手指按在方块上时,我们需要判断手指是在点击还是滑动,从而来判断我们要旋转的方向以及是哪一个面要旋转。
附上判断手指是否滑动,求旋转初始轴的代码
//如果鼠标左键按下,并且鼠标点击到魔方上的物体
if (Input.GetMouseButton(0) && cubeObject != null)
{
//从屏幕发出一条射线到鼠标的位置
Ray rayRun = Camera.main.ScreenPointToRay(Input.mousePosition);
//定义一个获取射线目标点物体的变量
RaycastHit hitRun;
//从刚才点击屏幕的射线的初始点,发射一条跟刚才射线方向一样的射线,并返回射线目标体的属性
if (Physics.Raycast(rayRun.origin, rayRun.direction, out hitRun))
{
//鼠标拖动的方向=射线发出碰触到物体的点-鼠标最初点到物体上的点
mouseRun = hitRun.point - mouseStart;
//判断鼠标拖动的方向的长度是否大于0.2f,以此判断鼠标在魔方方体上滑动还是点击
if (mouseRun.sqrMagnitude > 0.2f)
{
//求得触碰到的物体的法线与鼠标拖动的方向来判断旋转的轴向
mouseCross = Vector3.Cross(normal, mouseRun).normalized;
//调用旋转函数,求得旋转轴
RotatePoint(mouseCross);
//滑动过后,将触碰到的物体置空,为下次滑动做准备
cubeObject = null;
}
}
}
最开始用一个标志来判断是否可以旋转。
if (isRotate)
{ //旋转的偏移量,每次旋转都会增加,用来判断旋转的进程
t += Time.deltaTime * rotateSpeed;
//旋转的角度,每次旋转90度的t份,直到t=1时,旋转完成
Vector3 rotate = vecZhou * Mathf.Clamp01(t) * 90;
//物体旋转当前角度
transform.eulerAngles = rotate;
//每次偏移,当t的值大于等于1,旋转了90度,旋转结束
if (t >= 1f)
{ //将旋转偏移量t置零为下一次旋转做准备
t = 0;
//遍历所有的cube,将所有魔方方体的父物体置空,为下次旋转做准备
foreach (GameObject cube in cubes)
cube.transform.parent =GameObject.FindGameObjectWithTag("par").transform;
//将旋转轴的旋转角度置为初始,不然下次旋转会发生偏移,一定要在将
//旋转轴中的子物体剥离之后实行,不然,会将魔方方体带回原来位置
transform.rotation = Quaternion.identity;
//旋转结束,旋转标志置否,等待下次旋转
isRotate = false;
//旋转结束,鼠标可以再次点击方体移动
isRun = true;
}
// dataSave.CreatJson();
}
在方块可以转动之后,要进行摄像机的旋转,用一个中心物体,跟魔方轴心重合,将摄像机设置为中心物体子物体,让中心物体自身旋转从而带动摄像机旋转。unity中虽然input.getmousedown可以在手机屏上触碰,但是会导致摄像机的旋转产生偏移,所以最好使用input.touch。
源代码算法思路来自互联网