Unity
[Unity]룰렛 돌리기
촙촙쓰
2020. 2. 1. 00:40
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class rouletteMgr : MonoBehaviour
{
public RectTransform wheel;
public Image finalImage;
List<Image> contents = new List<Image>();
// Start is called before the first frame update
float initSpeed =1000;
float breakSpeed = 800;
float keepSpeedTimeMin = 1, keepSpeedTimeMax = 3;
float currentTime;
float currentSpeed;
public void Initialize()
{
int length = wheel.childCount;
for (int i = 0; i < length; i++)
{
contents.Add(wheel.GetChild(i).GetComponent<Image>());
}
}
//call when you want to roll the roulette
public void Roll()
{
currentSpeed = initSpeed;
currentTime = Random.Range(keepSpeedTimeMin, keepSpeedTimeMax);
StartCoroutine(Rolling());
}
//rolling coroutine
IEnumerator Rolling()
{
Time.timeScale = 0;
while (true)
{
currentTime -= Time.unscaledDeltaTime;
//currentTime -= Time.DeltaTime;
if(currentTime <= 0)
{
currentSpeed -= breakSpeed * Time.unscaledDeltaTime;
}
wheel.Rotate(0, 0, -currentSpeed * Time.unscaledDeltaTime);
if(currentSpeed <= 0)
{
float halfAng = 360 / contents.Count *0.5f;
float minAng = 360;
Image targetImage = null;
int length = contents.Count;
for (int i = 0; i < length; i++)
{
Vector3 localDir = Quaternion.Euler(0, 0, halfAng + (i * 360 / length)) * Vector3.up;
float angle = Vector3.Angle(wheel.TransformDirection(localDir), Vector3.up);
if(angle <= minAng)
{
minAng = angle;
targetImage = contents[i]; //get target
}
}
break;
}
yield return null;
}
yield return null;
}
}
원래는 코루틴 말고 update문에 사용해도 되지만, 보통 룰렛을 돌릴 때 다른 코루틴들의 동작을 멈추고 룰렛을 돌려야 할 상황이 온다. 이럴때는 룰렛을 돌리기 시작할때 timescale을 0으로 변경하면된다.
하지만 Rolling() 에서 Time.DeltaTime 을 사용한다면 이 코루틴도 멈춰버리기때문에 Time.unscaledDeltaTime을 사용한다. 이러면 timescale에 영향을 받지않고 계속 코루틴이 돌아간다!!
선택된 아이템을 찾는 방법은, 아이템들과 선택화살표사이의 각도를 구해서 각도가 가장 작은 것이 선택된 아이템이라는 원리를 이용해서 구한다.