Random이란?
Random은 무작위 숫자를 생성하는 클래스(class)입니다. 게임에서 적의 위치를 랜덤하게 배치하거나, 아이템을 랜덤하게 드롭하거나, 데미지를 랜덤하게 계산할 때 사용합니다.
기본 개념
- 시드(Seed): 랜덤 숫자 생성의 시작점 (같은 시드면 같은 결과)
- 범위 지정: 최소값과 최대값 사이의 숫자 생성
- Unity Random: Unity는 자체 Random 클래스(class)를 제공 (UnityEngine.Random)
Random 클래스(class) 사용하기
System.Random 사용
using System;
// Random 인스턴스 생성
Random random = new Random();
// 0 이상 10 미만의 정수 생성 (0~9)
int number = random.Next(10);
Debug.Log($"랜덤 숫자: {number}");
// 1 이상 11 미만의 정수 생성 (1~10)
int dice = random.Next(1, 11);
Debug.Log($"주사위: {dice}");
// 0.0 이상 1.0 미만의 실수 생성
double value = random.NextDouble();
Debug.Log($"실수: {value}");
UnityEngine.Random 사용 (Unity 전용)
using UnityEngine;
// 0 이상 10 미만의 정수 생성 (0~9)
int number = Random.Range(0, 10);
Debug.Log($"랜덤 숫자: {number}");
// 1 이상 11 미만의 정수 생성 (1~10)
int dice = Random.Range(1, 11);
Debug.Log($"주사위: {dice}");
// 0.0 이상 1.0 미만의 실수 생성
float value = Random.value;
Debug.Log($"실수: {value}");
// 0.0 이상 10.0 미만의 실수 생성
float floatValue = Random.Range(0f, 10f);
Debug.Log($"실수 범위: {floatValue}");
주요 메서드(method)
Next() - 정수(integer) 생성
using System;
Random random = new Random();
// 0 이상 지정값 미만의 정수
int num1 = random.Next(10); // 0~9
// 최소값 이상 최대값 미만의 정수
int num2 = random.Next(1, 11); // 1~10
// 음수도 가능
int num3 = random.Next(-10, 10); // -10~9
NextDouble() - 실수(float) 생성
using System;
Random random = new Random();
// 0.0 이상 1.0 미만의 실수
double value = random.NextDouble();
Debug.Log($"0~1 사이 값: {value}");
// 범위 변환 (예: 0~100)
double scaled = value * 100;
Debug.Log($"0~100 사이 값: {scaled}");
Random.Range() - Unity 전용
using UnityEngine;
// 정수 범위 (최대값 제외)
int intValue = Random.Range(0, 10); // 0~9
// 실수 범위 (최대값 포함)
float floatValue = Random.Range(0f, 10f); // 0.0~10.0
// 음수 범위
int negative = Random.Range(-5, 5); // -5~4
Random.value - 0~1 실수(float)
using UnityEngine;
// 0.0 이상 1.0 미만의 실수
float value = Random.value;
Debug.Log($"랜덤 값: {value}");
Random 사용 예시
예시 1: 주사위 굴리기
using UnityEngine;
public class DiceRoller : MonoBehaviour
{
void Start()
{
// 6면 주사위 굴리기
int dice = Random.Range(1, 7);
Debug.Log($"주사위 결과: {dice}");
// 여러 번 굴리기
for (int i = 0; i < 5; i++)
{
int result = Random.Range(1, 7);
Debug.Log($"{i + 1}번째: {result}");
}
}
}
예시 2: 랜덤 위치에 오브젝트 생성
using UnityEngine;
public class RandomSpawner : MonoBehaviour
{
public GameObject prefab;
void Start()
{
// 랜덤 위치 생성
for (int i = 0; i < 10; i++)
{
float x = Random.Range(-10f, 10f);
float y = Random.Range(0f, 5f);
float z = Random.Range(-10f, 10f);
Vector3 position = new Vector3(x, y, z);
Instantiate(prefab, position, Quaternion.identity);
}
}
}
예시 3: 랜덤 데미지 계산
using UnityEngine;
public class CombatSystem : MonoBehaviour
{
public int baseDamage = 50;
public float damageVariation = 0.2f; // 20% 변동
int CalculateDamage()
{
// 기본 데미지의 80%~120% 사이
float minDamage = baseDamage * (1f - damageVariation);
float maxDamage = baseDamage * (1f + damageVariation);
int damage = Mathf.RoundToInt(Random.Range(minDamage, maxDamage));
return damage;
}
void Attack()
{
int damage = CalculateDamage();
Debug.Log($"데미지: {damage}");
}
}
예시 4: 랜덤 색상 생성
using UnityEngine;
public class RandomColor : MonoBehaviour
{
void Start()
{
// 랜덤 색상 생성
Color randomColor = new Color(
Random.value,
Random.value,
Random.value,
1f
);
GetComponent<Renderer>().material.color = randomColor;
}
}
예시 5: 랜덤 아이템 드롭
using UnityEngine;
using System.Collections.Generic;
public class ItemDrop : MonoBehaviour
{
public List<GameObject> items = new List<GameObject>();
public float dropChance = 0.3f; // 30% 확률
void OnDestroy()
{
// 30% 확률로 아이템 드롭
if (Random.value < dropChance)
{
// 랜덤 아이템 선택
int randomIndex = Random.Range(0, items.Count);
GameObject item = items[randomIndex];
Instantiate(item, transform.position, Quaternion.identity);
Debug.Log("아이템 드롭!");
}
}
}
시드(Seed) 사용하기
같은 시드로 재현 가능한 랜덤
using System;
using UnityEngine;
public class SeededRandom : MonoBehaviour
{
void Start()
{
// 시드 설정 (같은 시드면 같은 결과)
Random.InitState(12345);
// 항상 같은 순서로 랜덤 숫자 생성
Debug.Log(Random.Range(0, 100)); // 항상 같은 값
Debug.Log(Random.Range(0, 100)); // 항상 같은 값
// 시드를 시간으로 설정 (매번 다름)
Random.InitState((int)System.DateTime.Now.Ticks);
}
}
System.Random 시드 사용
using System;
// 시드 지정
Random random1 = new Random(12345);
Random random2 = new Random(12345);
// 같은 시드면 같은 결과
int num1 = random1.Next(100);
int num2 = random2.Next(100);
// num1과 num2는 같은 값
랜덤 배열(array)/리스트(list) 요소 선택
배열(array)에서 랜덤 선택
using UnityEngine;
public class RandomArray : MonoBehaviour
{
public string[] names = { "홍길동", "김철수", "이영희", "박민수" };
void Start()
{
// 랜덤 인덱스
int randomIndex = Random.Range(0, names.Length);
string randomName = names[randomIndex];
Debug.Log($"선택된 이름: {randomName}");
}
}
리스트(list)에서 랜덤 선택
using UnityEngine;
using System.Collections.Generic;
public class RandomList : MonoBehaviour
{
public List<GameObject> enemies = new List<GameObject>();
void SpawnRandomEnemy()
{
if (enemies.Count > 0)
{
int randomIndex = Random.Range(0, enemies.Count);
GameObject enemy = enemies[randomIndex];
Instantiate(enemy, transform.position, Quaternion.identity);
}
}
}
확률 기반 선택
확률에 따른 선택
using UnityEngine;
public class ProbabilitySystem : MonoBehaviour
{
void Start()
{
float randomValue = Random.value;
if (randomValue < 0.5f) // 50% 확률
{
Debug.Log("일반 아이템");
}
else if (randomValue < 0.8f) // 30% 확률
{
Debug.Log("레어 아이템");
}
else // 20% 확률
{
Debug.Log("전설 아이템");
}
}
}
가중치 기반 선택
using UnityEngine;
using System.Collections.Generic;
public class WeightedRandom : MonoBehaviour
{
void Start()
{
// 아이템과 확률
Dictionary<string, float> items = new Dictionary<string, float>
{
{ "일반", 50f },
{ "레어", 30f },
{ "전설", 20f }
};
string selected = SelectWeightedItem(items);
Debug.Log($"선택된 아이템: {selected}");
}
string SelectWeightedItem(Dictionary<string, float> items)
{
float totalWeight = 0f;
foreach (float weight in items.Values)
{
totalWeight += weight;
}
float randomValue = Random.Range(0f, totalWeight);
float currentWeight = 0f;
foreach (var item in items)
{
currentWeight += item.Value;
if (randomValue <= currentWeight)
{
return item.Key;
}
}
return "";
}
}
실전 활용 예시
예시 1: 랜덤 적 스폰
using UnityEngine;
using System.Collections.Generic;
public class EnemySpawner : MonoBehaviour
{
public List<GameObject> enemyPrefabs = new List<GameObject>();
public float spawnInterval = 2f;
public float spawnRadius = 10f;
void Start()
{
InvokeRepeating("SpawnEnemy", 0f, spawnInterval);
}
void SpawnEnemy()
{
// 랜덤 적 선택
int randomIndex = Random.Range(0, enemyPrefabs.Count);
GameObject enemy = enemyPrefabs[randomIndex];
// 랜덤 위치 계산
Vector2 randomCircle = Random.insideUnitCircle * spawnRadius;
Vector3 spawnPosition = transform.position + new Vector3(randomCircle.x, 0f, randomCircle.y);
Instantiate(enemy, spawnPosition, Quaternion.identity);
}
}
예시 2: 랜덤 퀘스트 생성
using UnityEngine;
using System.Collections.Generic;
public class QuestGenerator : MonoBehaviour
{
public List<string> questTypes = new List<string> { "사냥", "수집", "탐험" };
public List<string> targets = new List<string> { "고블린", "늑대", "곰" };
string GenerateQuest()
{
string type = questTypes[Random.Range(0, questTypes.Count)];
string target = targets[Random.Range(0, targets.Count)];
int count = Random.Range(5, 15);
return $"{type} 퀘스트: {target} {count}마리 처치";
}
}
예시 3: 랜덤 보상 시스템
using UnityEngine;
public class RewardSystem : MonoBehaviour
{
public int minGold = 10;
public int maxGold = 100;
public float itemDropChance = 0.3f;
void GiveReward()
{
// 골드 보상
int gold = Random.Range(minGold, maxGold + 1);
Debug.Log($"골드 획득: {gold}");
// 아이템 드롭 확률
if (Random.value < itemDropChance)
{
Debug.Log("아이템 획득!");
// 아이템 드롭 로직...
}
}
}
주의사항
- 범위 차이:
Random.Range(0, 10)은 09 (최대값 제외),10.0 (최대값 포함)Random.Range(0f, 10f)는 0.0 - 시드 재사용: 같은 시드를 사용하면 같은 결과가 나옴 (디버깅에는 유용, 게임에는 부적합)
- 성능: UnityEngine.Random이 System.Random보다 Unity에서 더 최적화됨
- 스레드(thread) 안전성: UnityEngine.Random은 메인 스레드(thread)에서만 사용 가능
실전 활용 팁
팁 1: 범위 기억하기
// 정수: 최대값 제외
int intValue = Random.Range(0, 10); // 0~9
// 실수: 최대값 포함
float floatValue = Random.Range(0f, 10f); // 0.0~10.0
팁 2: 확률 계산
// 30% 확률
if (Random.value < 0.3f)
{
// 실행
}
// 1% 확률
if (Random.value < 0.01f)
{
// 실행
}
팁 3: 랜덤 방향 벡터
// 2D 랜덤 방향
Vector2 randomDirection2D = Random.insideUnitCircle;
// 3D 랜덤 방향
Vector3 randomDirection3D = Random.onUnitSphere;
// 랜덤 회전
Quaternion randomRotation = Random.rotation;
팁 4: 중복 제거
using UnityEngine;
using System.Collections.Generic;
public class UniqueRandom : MonoBehaviour
{
List<int> usedNumbers = new List<int>();
int GetUniqueRandom(int min, int max)
{
if (usedNumbers.Count >= (max - min))
{
usedNumbers.Clear(); // 모두 사용했으면 초기화
}
int randomNum;
do
{
randomNum = Random.Range(min, max);
} while (usedNumbers.Contains(randomNum));
usedNumbers.Add(randomNum);
return randomNum;
}
}