如上图我们要实现以上效果,即让生成的一圈图是斜着的!
至于怎么生成一圈物体,这里不做过多解释,详情请看上一篇:https://www.jianshu.com/p/829f990d81b0(传送门)
1.实现一圈图片斜着的效果:
首先,我们设置相机到合适的位置,然后调整角度即可。如图:
小提示:如果需要在ui或者别的地方上显示这样的效果,但是主摄像机又要拍摄场景,可以考虑用创建多一个摄像机来渲染!然后设置第二个摄像机的里面的参数即可!
不过需要注意的是,Culling Mask是拍摄选中的Layer的物体,所以需要拍摄的物体也需要设置对应的Layer(如下图)。
前面的只是开胃小菜,接下来,我们进入主题:
需求:实现一个转动抽奖的效果,按下按键后开始转动,按下停止按键后开始减速停下。
具体上代码吧,感觉不需要过多解释了:
不过需要注意的是,这个脚本是挂在要转动的物体上,然后围绕这个物体生成一圈子物体!
using System.Collections.Generic;
using UnityEngine;
///
/// 转动的状态控制
///
public enum RotationState
{
None = 0,
Trun,
Stop,
Stoped,
}
public class MyTest : MonoBehaviour
{
//一个无关代码的注释:重点,我生成的物体起点是从靠近屏幕这边开始的起点,具体用的操作是设置挂载此脚本的Scale的Z为-1
public GameObject go_Prefab; //生成的prefab
public float fRadius = 500; //圆的半径
private int m_MaxRotNumber = 20;
private float m_IntervalAngle = 18f;//间隔角度
private List IconObj = new List();
private List m_RectTrans = new List();
private List IconObjYpos = new List();
private RotationState enumRotationState = RotationState.None;//当前状态
float fStopTargetAngle = 0; //停止的目标角度
float fAngle = 0; //旋转的角度
public float fRotationSpeed = 200; //旋转速度
float fOriginRotationSpeed = 0; //用来记录旋转速度,用来重置数据
float fSlowDownRotationSpeed = 50;//最慢旋转速度
private struct RotTran
{
public Vector3 r_Pos;
public Vector3 r_Eul;
public RotTran(Vector3 pos, Vector3 eul)
{
r_Pos = pos;
r_Eul = eul;
}
}
private RotTran NewRot;
// Use this for initialization
void Start()
{
fOriginRotationSpeed = fRotationSpeed;
for (int a = 0; a < m_MaxRotNumber; a++)
{
GameObject newTemp = GameObject.Instantiate(go_Prefab);
newTemp.name = a.ToString();
newTemp.transform.parent = this.transform;
IconObj.Add(newTemp);
//生成位置信息,圆形的公式
// x = 原点x + 半径 * 邻边除以斜边的比例, 邻边除以斜边的比例 = cos(弧度) , 弧度 = 角度 *3.14f / 180f(大致的参考公式)
NewRot = new RotTran(new Vector3((Mathf.Sin((m_IntervalAngle * a) / 180 * Mathf.PI) * fRadius), 0, fRadius * Mathf.Cos((m_IntervalAngle * a) / 180 * Mathf.PI)), new Vector3(0, m_IntervalAngle * a, 0));
m_RectTrans.Add(NewRot);
IconObjYpos.Add(NewRot.r_Pos.y);
}
//设置位置和旋转
for (int i = 0; i < IconObj.Count; i++)
{
//IconObj[i].transform.localScale = Vector3.one;
IconObj[i].transform.localPosition = m_RectTrans[i % IconObj.Count].r_Pos;
IconObj[i].transform.localEulerAngles = m_RectTrans[i % IconObj.Count].r_Eul;
}
}
// Update is called once per frame
void Update()
{
switch (enumRotationState)
{
case RotationState.None:
break;
case RotationState.Trun:
TurnChild();
break;
case RotationState.Stop:
StopRotation();
break;
case RotationState.Stoped:
ReSetAllData();
break;
}
if (Input.GetKeyDown(KeyCode.A) && enumRotationState == RotationState.Trun)
{
SetStop();
}
if (Input.GetKeyDown(KeyCode.S) && enumRotationState == RotationState.None)
{
enumRotationState = RotationState.Trun;
}
}
///
/// 旋转
///
void TurnChild()
{
fAngle += fRotationSpeed * Time.deltaTime;
transform.rotation = Quaternion.Euler(new Vector3(0, fAngle, 0));
if (IconObj[0].transform.position.x < 0)//<0为顺时针旋转,判断子物体的x轴世界坐标是否小于0,小于0则进入处理,
{
GameObject tempGo = IconObj[0];
tempGo.transform.SetSiblingIndex(transform.childCount - 1);//将此物体的层级设置到最后一个
IconObj.RemoveAt(0);
IconObj.Add(tempGo);
}
}
///
/// 设置停止信号
///
void SetStop()
{
fAngle = 0;
fStopTargetAngle = 360 + IconObj[0].transform.localEulerAngles.y;
Debug.Log(IconObj[0].name);
enumRotationState = RotationState.Stop;
}
///
/// 停止旋转
///
void StopRotation()
{
fAngle += fRotationSpeed * Time.deltaTime;
fRotationSpeed -= 50 * Time.deltaTime;
fRotationSpeed = Mathf.Clamp(fRotationSpeed, fSlowDownRotationSpeed, 200);
if (fAngle >= fStopTargetAngle)
{
fAngle = fStopTargetAngle;
enumRotationState = RotationState.Stoped;
}
transform.rotation = Quaternion.Euler(new Vector3(0, fAngle, 0));
if (IconObj[0].transform.position.x < 0)//<0为顺时针旋转
{
GameObject tempGo = IconObj[0];
tempGo.transform.SetSiblingIndex(transform.childCount - 1);
IconObj.RemoveAt(0);
IconObj.Add(tempGo);
}
}
///
/// 重置数据
///
void ReSetAllData()
{
fAngle = 0;
fStopTargetAngle = 0;
fRotationSpeed = fOriginRotationSpeed;
enumRotationState = RotationState.None;
}
}