奖励物品的时候,需要根据策划配表的权重,来随机获得物品。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/**
*
* 权重随机
*
*
*/
namespace GameWish.Game
{
public class RandomRange
{
public int Start { set; get; }
public int End { set; get; }
public RandomRange(int start, int end) { Start = start; End = end; }
}
public class RandomWeightHelper<T>
{
private Dictionary<T, int> m_WeightItemDic = new Dictionary<T, int>();
private Dictionary<T, RandomRange> m_WeightItemSectionDic = new Dictionary<T, RandomRange>();
private Dictionary<T,int> m_Cache = new Dictionary<T, int>();
private int m_AllWeight = 0;
public RandomWeightHelper()
{
}
#region Public
///
/// 添加权重子项
///
///
///
public void AddWeightItem(T id, int weight = 1)
{
if (!m_WeightItemDic.ContainsKey(id))
{
m_WeightItemDic.Add(id, weight);
}
}
///
/// 获取随机key,不删除
///
///
public T GetRandomWeightValue()
{
if (m_WeightItemDic.Count > 0)
{
GetWeightItemSectionDic();
int randomNumber = Random.Range(0, GetAllWeight());
return GetRandomKey(randomNumber);
}
else
{
Debug.Log("随机池中无种子");
return default;
}
}
///
/// 获取随机值(删除,可恢复)
///
///
public T GetRandomWeightDeleteValueRecoverable()
{
if (m_WeightItemDic.Count > 0)
{
GetWeightItemSectionDic();
int randomNumber = Random.Range(0, GetAllWeight());
T cont = GetRandomKey(randomNumber);
if (m_WeightItemDic.ContainsKey(cont))
{
m_WeightItemDic.Remove(cont);
m_Cache.Add(cont, m_WeightItemDic[cont]);
}
else
Debug.LogError("未找到值,cont = " + cont);
return cont;
}
else
{
Debug.Log("随机池中无种子");
return default;
}
}
///
/// 获取随机值(删除,不可恢复)
///
///
public T GetRandomWeightDeleteValueIrrecoverable()
{
if (m_WeightItemDic.Count > 0)
{
GetWeightItemSectionDic();
int randomNumber = Random.Range(0, GetAllWeight());
T cont = GetRandomKey(randomNumber);
if (m_WeightItemDic.ContainsKey(cont))
m_WeightItemDic.Remove(cont);
else
Debug.LogError("未找到值,cont = " + cont);
return cont;
}
else
{
Debug.Log("随机池中无种子");
return default;
}
}
///
/// 恢复已经使用过的种子
///
public void Recovery()
{
foreach (var item in m_Cache)
{
m_WeightItemDic.Add(item.Key, item.Value);
}
}
public void ClearAll()
{
m_WeightItemDic.Clear();
m_WeightItemSectionDic.Clear();
m_Cache.Clear();
}
#endregion
#region Private
private int GetAllWeight()
{
int allWeight = 0;
if (m_WeightItemDic.Count <= 0)
{
return 1;
}
foreach (var item in m_WeightItemDic)
{
allWeight += item.Value;
}
return allWeight;
}
private T GetRandomKey(int randomNumber)
{
T key = default;
if (m_WeightItemSectionDic.Count <= 0)
{
Debug.Log("随机区域未空");
return key;
}
foreach (var item in m_WeightItemSectionDic)
{
if (item.Value.Start <= randomNumber && item.Value.End > randomNumber)
{
key = item.Key;
}
}
return key;
}
///
/// 获取权重区域
///
private void GetWeightItemSectionDic()
{
m_WeightItemSectionDic.Clear();
List<T> keys = new List<T>();
keys.AddRange(m_WeightItemDic.Keys);
List<int> values = new List<int>();
values.AddRange(m_WeightItemDic.Values);
for (int i = 0; i < keys.Count; i++)
{
int preWight = 0;
int curWight = 0;
for (int j = 0; j < values.Count; j++)
{
curWight += values[j];
preWight += values[j];
if (i <= j)
{
preWight -= values[j];
break;
}
}
if (!m_WeightItemSectionDic.ContainsKey(keys[i]))
m_WeightItemSectionDic.Add(keys[i], new RandomRange(preWight, curWight));
}
}
#endregion
}
}
第一个参数为随机的对象,将来做返回使用,第二个是权重信息
随机获得一个上一个函数添加进去的类对象(获取后删除,不可以恢复)
随机获得一个上一个函数添加进去的类对象(获取后删除,可以恢复)
恢复已经使用过的种子
随机获得一个上一个函数添加进去的类对象(获取后不删除)
public class Text : MonoBehaviour
{
public class TestModdule
{
public int value;
public int weight;
public TestModdule(int value, int weight)
{
this.value = value;
this.weight = weight;
}
}
private List testModdules = new List();
// Start is called before the first frame update
void Start()
{
testModdules.Add(new TestModdule (0,60));
testModdules.Add(new TestModdule (1,30));
testModdules.Add(new TestModdule (2,10));
RandomWeightHelper randomWeightHelper = new GameWish.Game.RandomWeightHelper();
foreach (var item in testModdules)
{
randomWeightHelper.AddWeightItem(item, item.weight);
}
for (int i = 0; i < 1000; i++)
{
TestModdule test1Moddule = randomWeightHelper.GetRandomWeightValue();
Debug.LogError(test1Moddule.value);
//Debug.LogError("第"+i+"次权重随机:" + test1Moddule.value);
//TestModdule test2Moddule = randomWeightHelper.GetRandomWeightValue();
//Debug.LogError(test2Moddule.value);
Debug.LogError("第" + i + "次权重随机:" + test2Moddule.value);
//TestModdule test3Moddule = randomWeightHelper.GetRandomWeightValue();
//Debug.LogError(test3Moddule.value);
Debug.LogError("第" + i + "次权重随机:" + test3Moddule.value);
}
}
// Update is called once per frame
void Update()
{
}
}
百度搜索不到相应的直接能用的代码,故自己写一个公使用,有更好的请私信联系。