原文:http://qinyuanpei.com/2015/03/12/create-luckyroll-game-with-Unity3D/
首先我們來看看在unity3d中如何實現轉盤抽獎:
從這張圖片我們可以看出,轉盤抽獎有兩部分組成:轉盤是可以旋轉的、轉盤指針是固定不動的。那麼,好了,抽獎無非就是讓轉盤轉起來然後再停下來嘛,直接給出代碼:
1
|
using UnityEngine;
using System.Collections;
public class LuckyRoll : MonoBehaviour {
//幸運轉盤
private Transform mRoolPanel;
//初始旋轉速度
private float mInitSpeed;
//速度變化值
private float mDelta=0.5f;
//轉盤是否暫停
private bool isPause=true;
void Start ()
{
//獲取轉盤
mRoolPanel=this.transform.FindChild("Background");
}
//開始抽獎
public void OnClick()
{
if(isPause)
{
//隨機生成一個初始速度
mInitSpeed=Random.Range(100,500);
//開始旋轉
isPause=false;
}
}
void Update()
{
if(!isPause)
{
//轉動轉盤(-1爲順時針,1爲逆時針)
mRoolPanel.Rotate(new Vector3(0,0,-1) * mInitSpeed * Time.deltaTime);
//讓轉動的速度緩緩降低
mInitSpeed-=mDelta;
//當轉動的速度爲0時轉盤停止轉動
if(mInitSpeed<=0)
{
//轉動停止
isPause=true;
}
}
}
}
|
這裏我們隨機給出一個速度mInitSpeed,然後讓它按照mDelta的速率緩慢的減少,當mInitSpeed的數值爲0時表示轉盤停止轉動。好了,我們來看看最後的效果:
從現在的效果來看,這個案例基本上成功了,所以以後如果碰到需要這種抽獎活動的場合,大家就可以跟美術協調好,快速地製作出這樣一個幸運轉盤來向身邊的人們炫耀了。不過這個案例同樣存在問題:
- 基於隨機數的轉盤轉動不受玩家控制,玩家無法參與到互動當中,可以考慮觸摸操作,這樣可以根據玩家的操作來模擬轉動,提高遊戲的真實性和可玩性。
- 因爲抽獎的結果是由美術設計在轉盤上的,所以程序無法根據轉盤停止後指針的位置直接判斷出玩家抽獎的結果以及本次抽獎是否爲有效的抽獎(指針恰好停留在兩個扇形區域的分界線上)。
- 因爲這裏轉盤的旋轉並沒有嚴格地按照實際情況下轉盤的受力情況來設計,因此可以說這個遊戲中的概率分佈可能不是均勻的,因此計算機裏使用的隨機數是僞隨機數。
好了,暫時就發現這些問題,如果有朋友知道如何模擬觸屏操作和阻尼運動,可以在這篇文章後面給我留言,今天的內容就是這樣了,希望大家會喜歡!
2015年3月31日更新:
今天找到了關於轉盤遊戲概率設計的相關內容,所以經過整理後補充在這裏:
首先這種轉盤遊戲概率設計的前提是轉盤固定不動,轉盤指針繞中心位置旋轉,與這篇文章中的恰好相反。如下圖所示,在這個轉盤遊戲的設計中主要遵循基本的三角函數,這裏以指針默認位置朝上來講解該原理。如果指針的默認位置在其它位置上的,可以此類推。
x+=xcosᶱ
y+=ycosᶱ
好了,現在我們就可以通過調整指針的角度來實現抽獎遊戲了。比如我們將轉盤平均分成8份,指針角度爲0表示獎品A,指針角度爲45度表示獎品B等等,以此類推。這樣的話,我們只要調整指針的角度就可以控制抽獎的結果。可是在實際生活中,指針不可能一次就指到對應的獎品上去,通常會在旋轉若干圈後慢慢地停下來。因此我們可以使用下列公式:
指針角度=360*圈數+(目標角度與初始角度的差值)
這裏的圈數可以通過隨機數來生成,這樣可以讓每次抽獎更加隨機些,當然爲了增加抽獎的真實感,我們可以採用這篇文章中提到的減速的方法來實現一個緩停的效果。那麼問題來了,如果轉盤上的獎項不是均勻分佈的怎麼呢?這種情況可以根據轉盤上圓心角的大小爲每一個獎項設定一個範圍,然後在這個範圍內隨機生成一個角度來計算指針的角度,好了,下面給出代碼實現:
1
|
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class LuckyRoll2 : MonoBehaviour {
//對獎項進行封裝
private class WrapItem
{
public WrapItem(string name,float rank,float ang1,float ang2)
{
this.ItemName=name;
this.ItemRank=rank;
this.MinAngle=ang1;
this.MaxAngle=ang2;
}
//獎項名稱
public string ItemName{get;set;}
//獎項概率
public float ItemRank{get;set;}
//最大角度
public float MaxAngle{get;set;}
//最小角度
public float MinAngle{get;set;}
}
//全部的獎項
private List<WrapItem> allItems;
void Start ()
{
//初始化獎品
allItems=new List<WrapItem>()
{
//圓心角爲5°,概率爲10%,以此類推
new WrapItem("獎品1",10,0,30),
new WrapItem("獎品2",15,30,90),
new WrapItem("獎品3",20,90,165),
new WrapItem("獎品4",25,165,255),
new WrapItem("獎品5",30,255,360),
};
//模擬抽獎10次
for(int i=0;i<10;i++)
{
Debug.Log(Roll());
}
}
/// <summary>
/// 抽獎方法
/// </summary>
private string Roll()
{
//抽獎結果
string result="";
//概率總精度爲100
float totalRank=100;
foreach(WrapItem item in allItems)
{
//產生一個0到100之間的隨機數
float random =Random.Range(0,totalRank);
//將該隨機數和獎品的概率比較
if(random<=item.ItemRank)
{
//抽獎結果
result=item.ItemName;
//爲轉盤指針隨機生成旋轉角度
float angle=Random.Range(item.MinAngle,item.MaxAngle);
//旋轉轉盤指針,此處略
break;
}else
{
totalRank-=item.ItemRank;
}
}
return "抽獎結果爲:"+result;
}
}
|
好了,這裏我們沒有寫轉盤旋轉的功能,這部分內容大家自己去實現好了,因爲在Unity3D裏面實現這樣一個功能實在是太簡單了。今天我們主要關注的內容是概率,所以我們重點對概率做了些研究,這裏我們來討論下算法中的概率計算問題,首先獎品1、獎品2、獎品2、獎品4、獎品5的概率分別爲10%、15%、20%、25%、30%,其概率之和爲100。因此
獎品1:從0~100中隨機抽取一個數,這個數值小於10的概率顯然是10%,這是第一輪數組遍歷。
獎品2:在第一輪數組遍歷沒有返回的情況下,進入第二輪遍歷,此時從0~90中隨機抽取一個數,其概率爲(1-(10/100)(15/(100-10))=15%。同樣的,抽到獎品3的概率爲(1-(25/100))(20/(100-25))=20%,以此類推。
好了,這部分內容終於補充到這篇文章裏了,對於這個問題的研究基本上可以告一段落,不得不說概率對於遊戲開發來說還是蠻重要的啊,有時間學習下數學吧,反正咱底子不弱啊,哈哈。
下面給出程序演示效果: