Skip to content

Instantly share code, notes, and snippets.

@todorok1
Last active April 5, 2025 12:10
Show Gist options
  • Select an option

  • Save todorok1/da6acc7ee735e581c8bbbbc8f4ad31ea to your computer and use it in GitHub Desktop.

Select an option

Save todorok1/da6acc7ee735e581c8bbbbc8f4ad31ea to your computer and use it in GitHub Desktop.
シンプルRPGチュートリアル第62回 敵キャラクターとのエンカウントを管理するクラス
using UnityEngine;
using System.Linq;
namespace SimpleRpg
{
/// <summary>
/// 敵キャラクターとのエンカウントを管理するクラスです。
/// </summary>
public class EncounterManager : MonoBehaviour, IPostBattle
{
/// <summary>
/// 戦闘に関する機能を管理するクラスへの参照です。
/// </summary>
[SerializeField]
BattleManager _battleManager;
/// <summary>
/// キャラクターの移動を行うクラスを管理するクラスへの参照です。
/// </summary>
[SerializeField]
CharacterMoverManager _characterMoverManager;
/// <summary>
/// 現在のマップのエンカウント情報です。
/// </summary>
EncounterData _currentEncounterData;
/// <summary>
/// 現在のマップのエンカウント情報をセットします。
/// </summary>
/// <param name="encounterData">エンカウントデータ</param>
public void SetCurrentEncounterData(EncounterData encounterData)
{
_currentEncounterData = encounterData;
}
/// <summary>
/// エンカウントが発生するかどうか確認します。
/// </summary>
public void CheckEncounter()
{
if (!IsHappenEncounter())
{
// エンカウントが発生しない場合は処理を抜けます。
return;
}
// 戦闘を開始します。
int enemyId = GetEncounterEnemyId();
var enemyData = EnemyDataManager.GetEnemyDataById(enemyId);
if (enemyData == null)
{
// エンカウントする敵キャラクターのデータが取得できない場合は処理を抜けます。
return;
}
// エンカウントが発生する場合は、キャラクターの移動を停止します。
_characterMoverManager.StopCharacterMover();
_battleManager.SetUpEnemyStatus(enemyId);
_battleManager.RegisterCallback(this);
_battleManager.StartBattle();
}
/// <summary>
/// エンカウントが発生する場合にTrueを返します。
/// </summary>
bool IsHappenEncounter()
{
if (_currentEncounterData == null)
{
// エンカウントデータがセットされていない場合はエンカウントしません。
return false;
}
if (_currentEncounterData.enemyRates == null)
{
// エンカウントする敵キャラクターのデータがセットされていない場合はエンカウントしません。
return false;
}
if (!_currentEncounterData.hasEncounter)
{
// エンカウントフラグがfalseの場合はエンカウントしません。
return false;
}
// エンカウントの確率を取得します。
float rate = _currentEncounterData.rate;
float random = Random.Range(0f, 100f);
SimpleLogger.Instance.Log($"エンカウントの確率: {rate} 乱数: {random} エンカウントするかどうか: {random <= rate}");
if (random > rate)
{
// 乱数の値がエンカウントの発生率より高い場合はエンカウントしません。
return false;
}
// 全ての敵キャラクターの出現率が0の場合もエンカウントしません。
int nonZeroEnemy = _currentEncounterData.enemyRates.Count(r => r.rate > 0);
if (nonZeroEnemy == 0)
{
return false;
}
return true;
}
/// <summary>
/// エンカウントする対象の敵キャラクターのIDを取得します。
/// </summary>
int GetEncounterEnemyId()
{
int enemyId= 0;
// 出現率の合計値を計算します。
int sumProbability = 0;
foreach (var enemyRate in _currentEncounterData.enemyRates)
{
sumProbability += enemyRate.rate;
}
// 乱数を生成して、出現率の合計値の範囲内で敵キャラクターを選択します。
int random = Random.Range(0, sumProbability);
foreach (var enemyRate in _currentEncounterData.enemyRates)
{
random -= enemyRate.rate;
if (random < 0)
{
enemyId = enemyRate.enemyId;
break;
}
}
return enemyId;
}
/// <summary>
/// 戦闘終了時のコールバックです。
/// </summary>
public void OnFinishedBattle()
{
// キャラクターが移動できるようにします。
_characterMoverManager.ResumeCharacterMover();
}
/// <summary>
/// 戦闘で負けた時のコールバックです。
/// </summary>
public void OnLostBattle()
{
// 戦闘に負けた場合は村長の前に戻します。
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment