ランダムイベントは、ゲームに変化をもたらします。
確率テーブルと重み付け抽選は、ランダムイベント実装の中核です。
たとえば育成ゲームでは、
- 突然キャラクターの好感度が上がる特別イベント
- トレーニング中に発生する小さな成功・失敗
- 特定の条件を満たしたときだけ発生するレアイベント
こうした出来事がランダムに起こることで、プレイ体験に変化とワクワク感が生まれます。
一方で実装を誤ると、「同じイベントばかり発生する」「レアイベントが頻発してバランスが崩れる」といった問題が起こりがちです。
この記事では、そうした失敗を避けるために、確率テーブルと重み付け抽選を使った実践的な実装方法を詳しく解説します。
✨ この記事でわかること
- 育成ゲーム向けの確率テーブルの実装方法
- イベント発生率を制御する重み付け抽選のロジック
- 同じイベントが続かないためのマンネリ防止策
- ゲームバランスを崩さない設計の考え方
- そのまま使える実装例とUnityコード

ランダムイベントは、まず確率テーブルを設計することが重要です。
重み付け抽選を使えば、意図したバランスを保ったまま変化を演出できます。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
あなたのオリジナルゲーム、今年こそ完成させませんか?
RPG・アクション・ホラー…Unityで本格ゲームを作りたい人のための学習サイトです。
実際に完成するゲームを題材に、
ソースコード・素材・プロジェクト一式をすべて公開。
仕事や学校の合間の1〜2時間でも、
「写経→改造」で自分のゲームまで作りきれる環境です。
確率テーブルの実装

単にランダムでイベントを選ぶのではなく、「どのイベントが、どれくらいの頻度で起こるか」を数値として定義することで、ゲーム体験を意図的にコントロールできます。
たとえば育成ゲームでは、日常的に起こる小さなイベントと、めったに発生しない特別なイベントを同じ抽選に混ぜることが多くなります。
このとき、確率テーブルがないと、レアイベントが出すぎたり、逆にまったく発生しなかったりします。
確率テーブルを使えば、イベントごとに「重み」を持たせることができ、ランダム性を保ちながらも、狙ったバランスでイベントを発生させることが可能になります。

まずは、もっとも基本となるシンプルな確率テーブルの実装から見ていきましょう。
基本的な確率テーブル
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
using UnityEngine; using System.Collections.Generic; [System.Serializable] public class ProbabilityTable { public List<EventEntry> entries = new List<EventEntry>(); public GameEvent SelectRandomEvent() { // 重みの合計を計算 int totalWeight = 0; foreach (var entry in entries) { totalWeight += entry.weight; } // ランダム値を生成 int randomValue = Random.Range(0, totalWeight); // 重みに応じて選択 int currentWeight = 0; foreach (var entry in entries) { currentWeight += entry.weight; if (randomValue < currentWeight) { return entry.eventData; } } return null; } } [System.Serializable] public class EventEntry { public GameEvent eventData; public int weight = 1; // 重み(大きいほど出現しやすい) public EventCondition condition; } |
このコードで、基本的な確率テーブルが実装できます。
重みに応じて、イベントが選択されます。
条件付き確率テーブル
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
public class ConditionalProbabilityTable : MonoBehaviour { public FlagManager flagManager; public CharacterTraining characterTraining; public ProbabilityTable baseTable; public GameEvent SelectRandomEvent() { // 条件を満たすエントリのみを抽出 List<EventEntry> availableEntries = new List<EventEntry>(); foreach (var entry in baseTable.entries) { if (CheckEventCondition(entry.condition)) { availableEntries.Add(entry); } } if (availableEntries.Count == 0) { return null; } // 重みの合計を計算 int totalWeight = 0; foreach (var entry in availableEntries) { totalWeight += entry.weight; } // ランダム値を生成 int randomValue = Random.Range(0, totalWeight); // 重みに応じて選択 int currentWeight = 0; foreach (var entry in availableEntries) { currentWeight += entry.weight; if (randomValue < currentWeight) { return entry.eventData; } } return null; } bool CheckEventCondition(EventCondition condition) { if (condition == null) return true; // フラグ条件をチェック foreach (var flagCondition in condition.flagConditions) { if (!flagManager.CheckFlagCondition(flagCondition)) { return false; } } // ステータス条件をチェック foreach (var statCondition in condition.statConditions) { if (!CheckStatCondition(statCondition)) { return false; } } return true; } bool CheckStatCondition(StatCondition condition) { CharacterStats stats = characterTraining.stats; int statValue = GetStatValue(stats, condition.statType); switch (condition.comparison) { case ComparisonType.GreaterThan: return statValue > condition.requiredValue; case ComparisonType.LessThan: return statValue < condition.requiredValue; default: return false; } } int GetStatValue(CharacterStats stats, StatType statType) { switch (statType) { case StatType.Strength: return stats.strength; case StatType.Intelligence: return stats.intelligence; case StatType.Charm: return stats.charm; default: return 0; } } } |
このコードで、条件付き確率テーブルが実装できます。
条件を満たすイベントのみが、抽選対象になります。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
重み付け抽選のロジック

確率テーブルを理解できたら、次に押さえたいのが重み付け抽選の仕組みです。
確率テーブルは「どんなイベントが存在するか」を整理する役割を持ちますが、それだけではどのイベントがどれくらい起こりやすいかまでは十分に制御できません。
そこで使うのが重み付け抽選です。
イベントごとに数値(重み)を設定し、その比率に応じて抽選することで、よく起こるイベントと、たまにしか起こらないイベントを同じ仕組みで扱えます。
初心者の段階では、難しく考える必要はありません。
まずは「重みが大きいほど選ばれやすい」という点だけ理解できていれば十分です。
確率計算を正確に行うよりも、「体感的な出やすさ」を調整するための仕組みだと捉えると分かりやすくなります。
この考え方を押さえておけば、イベントの種類が増えても、バランスを崩さずにランダム性を演出できます。

それでは、実際に重み付け抽選をどのようにコードで実装するのかを見ていきましょう。
重み付け抽選の実装
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
public class WeightedRandom { public static T Select<T>(List<WeightedItem<T>> items) { if (items.Count == 0) return default(T); // 重みの合計を計算 int totalWeight = 0; foreach (var item in items) { totalWeight += item.weight; } // ランダム値を生成 int randomValue = Random.Range(0, totalWeight); // 重みに応じて選択 int currentWeight = 0; foreach (var item in items) { currentWeight += item.weight; if (randomValue < currentWeight) { return item.item; } } return items[items.Count - 1].item; } } [System.Serializable] public class WeightedItem<T> { public T item; public int weight; } |
このコードで、重み付け抽選が実装できます。
重みが大きいほど、選択されやすくなります。
重みの調整例
✅ 重みの調整例
- よく発生するイベント:重み10(50%の確率)
- 普通のイベント:重み5(25%の確率)
- レアイベント:重み1(5%の確率)
重みを調整することで、イベントの発生頻度を制御できます。

重み付け抽選は、バランスを保ちながらランダム性を確保できます。重みを調整して、適切な発生頻度を設定しましょう。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
マンネリを防ぐ方法

確率テーブルと重み付け抽選を実装できれば、ランダムイベントはひとまず動きます。
ただし、実際にプレイしてみると、「仕組みは正しいのに、なぜか同じイベントばかり起きる」と感じることがあります。
これが、ランダムイベントにおけるマンネリの正体です。
初心者の段階では、まず前項の確率テーブルと重み付け抽選を正しく理解し、意図した通りに動かせることが最優先です。
マンネリ対策は、その次のステップと考えて問題ありません。
一方で、育成ゲームのように長時間プレイされるジャンルでは、マンネリ対策を後回しにすると、遊び続けたときの体験が単調になりやすくなります。
そのため、仕組みが安定してきた段階で、早めに意識しておくことも重要です。
このセクションでは、余裕が出てきたときに導入できる「同じイベントが続かないための仕組み」を紹介します。基本構造はシンプルなので、段階的に取り入れていきましょう。

まずは、もっとも分かりやすい連続発生を防ぐ方法から解説します。
連続発生防止システム
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
public class AntiRepetitionSystem : MonoBehaviour { private List<string> recentEvents = new List<string>(); public int maxRecentCount = 3; // 直近3回のイベントを記録 public GameEvent SelectRandomEventWithAntiRepetition(ProbabilityTable table) { // 直近のイベントを除外 List<EventEntry> availableEntries = new List<EventEntry>(); foreach (var entry in table.entries) { if (!recentEvents.Contains(entry.eventData.eventID)) { availableEntries.Add(entry); } } // 除外後も候補があるかチェック if (availableEntries.Count == 0) { // 候補がない場合は、記録をリセット recentEvents.Clear(); availableEntries = new List<EventEntry>(table.entries); } // 重み付け抽選 int totalWeight = 0; foreach (var entry in availableEntries) { totalWeight += entry.weight; } int randomValue = Random.Range(0, totalWeight); int currentWeight = 0; foreach (var entry in availableEntries) { currentWeight += entry.weight; if (randomValue < currentWeight) { // 記録に追加 RecordEvent(entry.eventData.eventID); return entry.eventData; } } return null; } void RecordEvent(string eventID) { recentEvents.Add(eventID); // 最大数を超えたら、古いものを削除 if (recentEvents.Count > maxRecentCount) { recentEvents.RemoveAt(0); } } } |
このコードで、連続発生防止システムが実装できます。
直近のイベントを記録し、同じイベントが連続で発生しないようにします。
クールダウンシステム
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
public class EventCooldownSystem : MonoBehaviour { private Dictionary<string, int> eventCooldowns = new Dictionary<string, int>(); public void ProcessCooldowns() { List<string> keysToRemove = new List<string>(); foreach (var kvp in eventCooldowns) { eventCooldowns[kvp.Key] = kvp.Value - 1; if (eventCooldowns[kvp.Key] <= 0) { keysToRemove.Add(kvp.Key); } } foreach (var key in keysToRemove) { eventCooldowns.Remove(key); } } public void SetCooldown(string eventID, int cooldownTurns) { eventCooldowns[eventID] = cooldownTurns; } public bool IsOnCooldown(string eventID) { return eventCooldowns.ContainsKey(eventID) && eventCooldowns[eventID] > 0; } } |
クールダウンシステムを実装します。
イベント発生後、一定期間は再発生しないようにします。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
バランスを崩さない設計

バランスを崩さないためには、イベントの効果を制限します。
設計方法を紹介します。
イベント効果の制限
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
[System.Serializable] public class BalancedEvent { public string eventID; public List<StatChange> statChanges = new List<StatChange>(); public int maxStatChange = 5; // 1回のイベントで変動する最大値 public void ApplyStatChanges(CharacterStats stats) { foreach (var change in statChanges) { int actualChange = Mathf.Clamp(change.value, -maxStatChange, maxStatChange); switch (change.statType) { case StatType.Strength: stats.strength = Mathf.Clamp(stats.strength + actualChange, 0, 100); break; case StatType.Intelligence: stats.intelligence = Mathf.Clamp(stats.intelligence + actualChange, 0, 100); break; case StatType.Charm: stats.charm = Mathf.Clamp(stats.charm + actualChange, 0, 100); break; } } } } |
このコードで、イベント効果が制限されます。
1回のイベントで変動する最大値を設定します。
バランス調整のポイント
- 効果の上限:1回のイベントで変動する最大値を設定
- 発生頻度:重みを調整して、適切な発生頻度を設定
- 条件付き発生:ステータスに応じて、発生するイベントを変える
これらのポイントを守れば、バランスを保てます。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
実装例:完全なランダムイベントシステム

実際に使える、完全なランダムイベントシステムの実装例を紹介します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
using UnityEngine; public class CompleteRandomEventSystem : MonoBehaviour { [Header("システム")] public ConditionalProbabilityTable probabilityTable; public AntiRepetitionSystem antiRepetitionSystem; public EventCooldownSystem cooldownSystem; public CharacterTraining characterTraining; public void ProcessRandomEvent() { // クールダウンを処理 cooldownSystem.ProcessCooldowns(); // ランダムイベントを選択 GameEvent selectedEvent = antiRepetitionSystem.SelectRandomEventWithAntiRepetition( probabilityTable.baseTable ); if (selectedEvent != null && !cooldownSystem.IsOnCooldown(selectedEvent.eventID)) { // イベントを実行 ExecuteEvent(selectedEvent); // クールダウンを設定 cooldownSystem.SetCooldown(selectedEvent.eventID, 3); } } void ExecuteEvent(GameEvent evt) { // イベントを実行 // 実装は省略 } } |
このコードで、完全なランダムイベントシステムが実装できます。
確率テーブル、連続発生防止、クールダウンを統合しています。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
よくある質問(FAQ)

Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
あなたのオリジナルゲーム、今年こそ完成させませんか?
RPG・アクション・ホラー…Unityで本格ゲームを作りたい人のための学習サイトです。
実際に完成するゲームを題材に、
ソースコード・素材・プロジェクト一式をすべて公開。
仕事や学校の合間の1〜2時間でも、
「写経→改造」で自分のゲームまで作りきれる環境です。
まとめ

ランダムイベントは、確率テーブルから始めましょう。
重み付け抽選と連続発生防止で、バランスを保てます。
✅ 今日から始める3ステップ
- ステップ1:確率テーブルを実装する(所要2時間)
- ステップ2:重み付け抽選を実装する(所要1時間)
- ステップ3:連続発生防止システムを実装する(所要2時間)
本格的にUnityを学びたい方は、Unity入門の森で実践的なスキルを身につけましょう。
あなたのペースで、少しずつ進めていけば大丈夫です。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる



コメント