오늘은 Random Seed 생성 도구를 만들어 보았다.
"Random seed" 또는 "seed value"란?
난수 생성 알고리즘에서 초기 시작점을 설정하는 데 사용되는 초기 값이다.
"Random Seed Generator"는 Unity 에디터용으로 설계된 다용도 도구로,
최소값과 최대값 사이의 범위에서 난수를 생성할 수 있도록 사용자에게 인터페이스를 제공하고,
원하는 반복 횟수만큼 난수를 생성할 수 있다.
생성된 난수들은 리스트에 저장되고, 에디터 창에서 직접적으로 조회할 수 있다.
선형 합동 생성기(LCG) 알고리즘을 사용하여 가상의 난수를 생성하는데,
LCG(선형 합동 생성기) 알고리즘은 간단하면서도 널리 사용되는 난수 생성 방법 중 하나다.
LCG 알고리즘은 다음과 같은 수학적 공식을 사용하여 난수 시퀀스를 생성한다.
Xn+1=(aXn+c)mod m
Xn+1 = 다음 난수
Xn = 현재 난수
a = 곱셈 상수
c = 증가 상수
m = 모듈(나눗셈의 나머지를 구할때 사용되는 값)
mod = 나머지
using UnityEditor;
using System.Collections.Generic;
using UnityEditor.PackageManager.UI;
using UnityEngine;
public class RandomSeedGenerator : EditorWindow
{
private int minNumber = 0;
private int maxNumber = 0;
private int iterations = 0;
private List<int> results = new List<int>();
// LCG Parameters
private const long a = 1103515245;
private const long c = 12345;
private const long m = 2147483647;
private long seed = 123456789; // Initial seed
private bool showResults = true;
private Vector2 scrollPosition;
[MenuItem("Tools/Random Seed Generator")]
public static void ShowWindow()
{
var window = GetWindow<RandomSeedGenerator>("Random Seed Generator");
window.maxSize = new Vector2(window.maxSize.x, window.maxSize.y);
window.minSize = new Vector2(300, 400);
window.LoadNumberValues();
}
void OnGUI()
{
GUIStyle centeredStyle = new GUIStyle(GUI.skin.label);
centeredStyle.alignment = TextAnchor.MiddleCenter;
GUILayout.Label("Ver. 1.0.0", EditorStyles.boldLabel);
DrawLine();
minNumber = EditorGUILayout.IntField("Min Number", minNumber);
maxNumber = EditorGUILayout.IntField("Max Number", maxNumber);
iterations = EditorGUILayout.IntSlider("Iterations", iterations, 0, 99);
if (GUILayout.Button("Generate"))
{
GenerateRandomNumbers();
showResults = true;
SaveNumberValues();
}
GUILayout.BeginHorizontal();
if (GUILayout.Button("Clear"))
{
showResults = false;
}
if (GUILayout.Button("Init"))
{
// 초기화 재 확인 다이알로그
bool confirm = EditorUtility.DisplayDialog(
"Initialize Random Numbers",
"Are you sure you want to initialize and generate new random numbers? This will clear all existing numbers.",
"Yes",
"No"
);
if (confirm)
{
showResults = false; // 화면 초기화
results.Clear(); // 난수 초기화
GenerateRandomNumbers(); // 새로운 난수 생성
}
}
GUILayout.EndHorizontal();
DrawLine();
GUILayout.BeginHorizontal();
GUILayout.Label("Iteration", centeredStyle, GUILayout.ExpandWidth(false));
Rect lastRect = GUILayoutUtility.GetLastRect();
GUILayout.Space(10); // 레이블과 세로선 사이의 공간
GUILayout.Label("Seed", centeredStyle, GUILayout.ExpandWidth(true));
GUILayout.EndHorizontal();
DrawVerticalLine(lastRect.xMax + 5, lastRect.y); // 세로 선
DrawLine();
if (showResults)
{
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
for (int i = 0; i < results.Count; i++)
{
GUILayout.BeginHorizontal();
GUILayout.Label($"{i + 1}", centeredStyle, GUILayout.Width(50));
GUILayout.Space(20);
GUILayout.Label($"{results[i]}", centeredStyle, GUILayout.ExpandWidth(true));
GUILayout.EndHorizontal();
}
EditorGUILayout.EndScrollView();
}
}
void GenerateRandomNumbers()
{
int currentCount = results.Count;
if (iterations > currentCount)
{
// iterations 값이 현재 결과보다 크다면, 추가로 생성
int additionalIterations = iterations - currentCount;
for (int i = 0; i < additionalIterations; i++)
{
seed = (a * seed + c) % m;
int randomNumber = minNumber + (int)(seed % (maxNumber - minNumber + 1));
results.Add(randomNumber);
}
}
else
{
// iterations 값이 현재 결과보다 작거나 같다면, 리스트를 잘라서 사용
results = results.GetRange(0, iterations);
}
}
// Number값 EditorPrefs에 저장
void SaveNumberValues()
{
EditorPrefs.SetInt("MinNumber", minNumber);
EditorPrefs.SetInt("MaxNumber", maxNumber);
EditorPrefs.SetInt("iterations", iterations);
}
// Number값 EditorPrefs에서 불러오기
void LoadNumberValues()
{
minNumber = EditorPrefs.GetInt("MinNumber", 0);
maxNumber = EditorPrefs.GetInt("MaxNumber", 0);
iterations = EditorPrefs.GetInt("iterations", 0);
}
private void DrawLine()
{
var rect = GUILayoutUtility.GetRect(1, 1, GUILayout.ExpandWidth(true));
EditorGUI.DrawRect(rect, Color.gray);
}
private void DrawVerticalLine(float xPosition, float yPosition)
{
EditorGUI.DrawRect(new Rect(xPosition, yPosition, 1, this.position.height), Color.gray);
}
}
반응형
'UnityDataTools' 카테고리의 다른 글
[LocalizationEditor] 엑셀 데이터를 받아 상수 Key 클래스 생성 및 해당 하는 값(Value) 관리 도구 + 언어 지원 (0) | 2024.04.02 |
---|---|
Coroutine Manager (0) | 2024.03.25 |
MoveToFileEditor (0) | 2024.03.21 |
PlayerPrefs Viewer 수정 (+float type) (0) | 2024.03.19 |
[UnityDataTools] Big Number Converter - 리얼 숫자 변환/역변환 + 계산기 (0) | 2024.02.22 |