-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
245 additions
and
115 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,120 +1,216 @@ | ||
using UnityEngine; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using UnityEngine.SceneManagement; | ||
|
||
public class AnomalyManager : MonoBehaviour | ||
public class AnomalyManager : AbstractStageObserver | ||
{ | ||
/********** | ||
* fields * | ||
**********/ | ||
|
||
// 이상현상 컨트롤러 프리팹 | ||
public GameObject[] prefabs; | ||
|
||
// 개수 | ||
public int numStage; | ||
public int numAnomaly; | ||
|
||
// 테스트용 수치 | ||
public int testMode; | ||
public int testAnomalyID; | ||
|
||
// 난수 | ||
private SCH_Random _random; | ||
|
||
// 이상현상 색인 배열 | ||
private int[] _anomalyList; | ||
|
||
/************** | ||
* properties * | ||
**************/ | ||
|
||
// 클래스 이름 | ||
public override string Name { get; } = "AnomalyManager"; | ||
|
||
// 클래스 인스턴스 | ||
public static AnomalyManager Instance { get; private set; } | ||
public GameObject[] anomalyPrefabs; // Anomaly1Manager ~ Anomaly31Manager 프리팹 보관용 리스트 | ||
private List<int> anomalyList = new List<int>(); // 이상현상 리스트 | ||
private const int AnomalyCount = 8; // 사이즈 8 | ||
private System.Random random = new System.Random(); | ||
public bool checkSpecificAnomaly; | ||
public bool checkIntersect; | ||
public int SpecificAnomalyNum; | ||
public GameObject currentAnomalyInstance; // 현재 활성화된 이상현상 인스턴스 | ||
// 하나의 AnomalyManager만 보장 | ||
private void Awake() | ||
|
||
/************************************* | ||
* implementation: AbstractBehaviour * | ||
*************************************/ | ||
|
||
// `Awake` 메시지 용 메서드 | ||
protected override bool Awake_() | ||
{ | ||
if (Instance == null) | ||
{ | ||
bool res = false; | ||
|
||
if (Instance == null) { | ||
Log($"`Instance` has not been set => set `Instance` as `{Name}`"); | ||
Instance = this; | ||
DontDestroyOnLoad(gameObject); | ||
GenerateAnomalyList(); | ||
} | ||
else | ||
{ | ||
res = base.Awake_(); | ||
} else { | ||
Log($"`Instance` has already been set => destroy `{gameObject.name}`"); | ||
Destroy(gameObject); | ||
} | ||
// 프리팹이 설정되어 있는지 확인 | ||
if (anomalyPrefabs == null || anomalyPrefabs.Length == 0) | ||
{ | ||
Debug.LogError("Anomaly prefabs are missing! Please assign prefabs in the Inspector."); | ||
|
||
return res; | ||
} | ||
|
||
// 필드를 초기화하는 메서드 | ||
protected override bool InitFields() | ||
{ | ||
bool res = base.InitFields(); | ||
|
||
_random = new SCH_Random(); | ||
|
||
_anomalyList = new int[numStage]; | ||
|
||
return res; | ||
} | ||
|
||
/***************************************** | ||
* implementation: AbstractStageObserver * | ||
*****************************************/ | ||
|
||
// 단계 변경 시 불리는 메서드 | ||
public override bool UpdateStage() | ||
{ | ||
bool res = base.UpdateStage(); | ||
|
||
if (GameManager.Instance.Stage == 1) { | ||
Log("Call `GenerateList` begin"); | ||
if (GenerateList()) { | ||
Log("Call `GenerateList` sucess"); | ||
} else { | ||
Log("Call `GenerateList` failed", mode: 1); | ||
res = false; | ||
} | ||
} | ||
|
||
return res; | ||
} | ||
// 이상현상 리스트 생성 | ||
private void GenerateAnomalyList() | ||
|
||
/*************** | ||
* new methods * | ||
***************/ | ||
|
||
// 이상현상 컨트롤러를 생성 후 반환하는 메서드 | ||
public AbstractAnomalyObject GetAnomalyController() | ||
{ | ||
anomalyList.Clear(); | ||
HashSet<int> uniqueNumbers = new HashSet<int>(); | ||
bool hasHighAnomaly = false; | ||
GameObject obj; | ||
AbstractAnomalyObject controller = null; | ||
int stage = GameManager.Instance.Stage; | ||
|
||
for (int i = 0; i < AnomalyCount; i++) | ||
{ | ||
int anomaly; | ||
if (!checkSpecificAnomaly) | ||
{ | ||
do | ||
{ | ||
anomaly = GenerateRandomAnomaly(); | ||
} while (i > 0 && anomaly == anomalyList[i - 1] // 연속 방지 | ||
|| (anomaly != 0 && !uniqueNumbers.Add(anomaly))); // 중복 방지 | ||
|
||
if (anomaly >= 21) | ||
{ | ||
hasHighAnomaly = true; | ||
} | ||
if (stage == 0) { | ||
obj = Instantiate(prefabs[0]); | ||
if (obj != null) { | ||
controller = obj.GetComponent<AbstractAnomalyObject>(); | ||
} else { | ||
Log($"Find `AbstractAnomalyObject` for {obj.name} failed", mode: 2); | ||
} | ||
else | ||
{ | ||
if(checkIntersect && i%2==1) anomaly = 0; | ||
else anomaly = SpecificAnomalyNum; | ||
} else if (stage > 0 && stage <= numStage) { | ||
obj = Instantiate(prefabs[_anomalyList[stage - 1]]); | ||
if (obj != null) { | ||
controller = obj.GetComponent<AbstractAnomalyObject>(); | ||
} else { | ||
Log($"Find `AbstractAnomalyObject` for {obj.name} failed", mode: 2); | ||
} | ||
anomalyList.Add(anomaly); | ||
} else { | ||
Log($"Invalid stage: {stage}", mode: 2); | ||
} | ||
|
||
if(!hasHighAnomaly) | ||
{ | ||
int randomIndex = random.Next(0, AnomalyCount); | ||
int highAnomaly = random.Next(21, 32); | ||
anomalyList[randomIndex] = highAnomaly; | ||
} | ||
Debug.Log($"[AnomalyManager] Generated Anomaly List: {string.Join(", ", anomalyList)}"); | ||
return controller; | ||
} | ||
// 20% 확률로 0, 나머지 확률로 1~31의 이상현상을 생성 | ||
private int GenerateRandomAnomaly() | ||
|
||
// 모든 이상현상 컨트롤러가 `AbstractAnomalyObject`의 서브클래스이기 전에 쓸 메서드 | ||
public void StartAnomalyController() | ||
{ | ||
return random.Next(0, 100) < 20 ? 0 : random.Next(1, 31); | ||
int stage = GameManager.Instance.Stage; | ||
|
||
if (stage == 0) { | ||
Instantiate(prefabs[0]); | ||
} else if (stage > 0 && stage <= numStage) { | ||
Instantiate(prefabs[_anomalyList[stage - 1]]); | ||
} else { | ||
Log($"Invalid stage: {stage}", mode: 2); | ||
} | ||
} | ||
// 현재 스테이지에 맞는 이상현상을 로드 | ||
public void CheckAndInstantiateAnomaly() | ||
|
||
// 이상현상 색인 리스트를 생성하는 메서드 | ||
private bool GenerateList() | ||
{ | ||
int stageIndex = GameManager.Instance.GetCurrentStage() - 1; | ||
if (stageIndex >= anomalyList.Count) | ||
{ | ||
Debug.LogError("Invalid stage index in anomaly list."); | ||
return; | ||
} | ||
else if (stageIndex == -1) | ||
{ | ||
Debug.Log($"[AnomalyManager] Current Stage : {GameManager.Instance.GetCurrentStage()}"); | ||
currentAnomalyInstance = Instantiate(anomalyPrefabs[0]); | ||
return; | ||
bool res = true; | ||
|
||
switch (testMode) { | ||
case 0: | ||
GenerateAnomalyListNormal(); | ||
break; | ||
case 1: | ||
GenerateAnomalyListTest1(); | ||
break; | ||
case 2: | ||
GenerateAnomalyListTest2(); | ||
break; | ||
default: | ||
Log("Generate `_anomalyList` failed", mode: 1); | ||
res = false; | ||
break; | ||
} | ||
int anomaly = anomalyList[stageIndex]; | ||
Debug.Log($"[AnomalyManager] Current Stage: {GameManager.Instance.GetCurrentStage()}, Anomaly Number: {anomaly}"); | ||
// 특정 인덱스에 해당하는 이상현상 프리팹만 인스턴스화 | ||
if (anomaly >= 0 && anomaly < anomalyPrefabs.Length && anomalyPrefabs[anomaly] != null) | ||
{ | ||
currentAnomalyInstance = Instantiate(anomalyPrefabs[anomaly]); | ||
if (currentAnomalyInstance == null) | ||
{ | ||
Debug.LogError("Failed to instantiate anomaly prefab."); | ||
} | ||
else | ||
{ | ||
Debug.Log("Anomaly instantiated successfully."); | ||
|
||
return res; | ||
} | ||
|
||
// 일반 이상현상 색인 리스트를 생성하는 메서드 | ||
private void GenerateAnomalyListNormal() | ||
{ | ||
bool hasHighAnomaly = false; | ||
|
||
while (!hasHighAnomaly) { | ||
int idxLastZero = -2; | ||
|
||
_anomalyList = _random.Permutation(numAnomaly, numStage - 1); | ||
for (int idx = 0; idx < numStage; idx++) { | ||
if (idx - idxLastZero > 1 && _random.UniformDist(0.0, 1.0) < 0.2) { | ||
// 직전 단계가 제0번이 아닌 경우 20 %의 확률로 제0번 생성 | ||
_anomalyList[idx] = 0; | ||
idxLastZero = idx; | ||
} else { | ||
// 0번을 위한 색인 조정 | ||
_anomalyList[idx] += 1; | ||
|
||
// 적대적 이상현상 포함 확인 | ||
if (_anomalyList[idx] > 20) { | ||
hasHighAnomaly = true; | ||
} | ||
} | ||
} | ||
} | ||
else | ||
{ | ||
Debug.LogError($"Anomaly prefab for anomaly {anomaly} is missing or not assigned in the prefab list."); | ||
|
||
Log($"Generate `_anomalyList` success: [{string.Join(", ", _anomalyList)}]"); | ||
} | ||
|
||
// 테스트용 이상현상 색인 리스트를 생성하는 메서드 1 | ||
private void GenerateAnomalyListTest1() | ||
{ | ||
for (int idx = 0; idx < numStage; idx++) { | ||
// 원하는 이상현상이 계속 나오도록 | ||
_anomalyList[idx] = testAnomalyID; | ||
} | ||
|
||
Log($"Generate `_anomalyList` success: [{string.Join(", ", _anomalyList)}]"); | ||
} | ||
// 스테이지 실패 시 이상현상 리스트 재 생성 | ||
public void ResetAnomaliesOnFailure() | ||
|
||
// 테스트용 이상현상 색인 리스트를 생성하는 메서드 2 | ||
private void GenerateAnomalyListTest2() | ||
{ | ||
GenerateAnomalyList(); | ||
for (int idx = 0; idx < numStage; idx++) { | ||
// 원하는 이상현상과 제0번이 번갈아 나오도록 | ||
if (idx % 2 == 0) { | ||
_anomalyList[idx] = testAnomalyID; | ||
} else { | ||
_anomalyList[idx] = 0; | ||
} | ||
} | ||
|
||
Log($"Generate `_anomalyList` success: [{string.Join(", ", _anomalyList)}]"); | ||
} | ||
} | ||
} |
Oops, something went wrong.