---(전략)---voidInitGameObjectPools() {---(중략)--- // 적 캐릭터의 dead 애니메이션이 종료된 후 일정 확율로 나타나게될 코인.CreateGameObject(coinObj,20, gameObjectPoolPosition); }---(후략)---
---(전략)---publicvoidResetEnemy() { // 임의의 확율로 코인을 생성한다.int makePossibleCoin =UnityEngine.Random.Range(0,10);if(makePossibleCoin >=7) {GameData.Instance.gamePlayManager.SpawnCoin(transform.position); } // 적 캐릭터를 초기 위치로 이동시킨다. currentState =EnemyState.none;transform.position=GameData.Instance.gamePlayManager.gameObjectPoolPosition.position;animator.ResetTrigger("isDead");animator.SetTrigger("isAlive"); // hpbar를 반환한다.hpBarObj.transform.position=GameData.Instance.gamePlayManager.enemyHPBarRoot.position; hpBarObj =null; }---(후략)---
예제 3-80는 책에서는 DeadEnd이나 게임 플레이 매니저에서 이미 제작된 ResetEnemy를 활용하도록 변경하였습니다. 이후에 등장하는 DeadEnd도 모두 ResetEnemy로 변경할 것입니다.
@GM 게임 오브젝트의 GamePlayManager에 아래 사항 연결
결과창 연결
예제 3-81: GamePlayManager.cs
---(전략)--- // 획득한 점수 저장.int score =0; // 처치한 적 숫자 기록.int deadEnemys =0; // 획득한 코인 숫자 저장.int getCoins =0;---(후략)---
예제 3-82: GamePlayManager.cs
// 처치한 적과 획득한 코인 저장.publicvoidAddDeadEnemyAndCoin(int getCoin =0) { // 처치한 적 숫자 증가. deadEnemys++; // 획득한 코인 숫자 증가. getCoins += getCoin;if(getCoin >0) { // 유저 인터페이스에 반영.coinLb.text=getCoins.ToString(); } }---(후략)---
예제 3-83: Enemy.cs
---(전략)---publicvoidResetEnemy() { // 임의의 확율로 코인을 생성한다.int makePossibleCoin =UnityEngine.Random.Range(0,10);if(makePossibleCoin >=7) {GameData.Instance.gamePlayManager.SpawnCoin(transform.position); // 처치한 적 숫자 및 획득한 코인 숫자 전달.GameData.Instance.gamePlayManager.AddDeadEnemyAndCoin(10); }else { // 처치한 적 숫자 전달.GameData.Instance.gamePlayManager.AddDeadEnemyAndCoin(); }---(후략)---
예제 3-84: GamePlayManager.cs
---(전략)--- // 결과창 게임 오브젝트.publicGameObject resultWindow; // 결과창에 사용되는 UILabelpublicUILabel resultHighScoreLb, resultNowScoreLb, resultWaveLb, resultDeadEnemysLb, resultGetCoinsLb;---(중략)--- // 결과창을 나타나게 한다.publicvoidOpenResult() { // 재 생성 방지.if(resultWindow.activeInHierarchy) return; // 적 생성 구문 해제.if (IsInvoking("CheckSpawnEnemy")) {CancelInvoke("CheckSpawnEnemy"); } // TODO: 최고 점수를 나타낼 수 있도록 해야한다.resultHighScoreLb.text="0";resultNowScoreLb.text=score.ToString();resultWaveLb.text=waveLb.text;resultDeadEnemysLb.text=deadEnemys.ToString();resultGetCoinsLb.text=getCoins.ToString(); // 결과창을 나타나게 한다.resultWindow.SetActive(true); }---(후략)---
예제 3-85: GamePlayManager.cs
---(전략)---publicvoidDamage(float damageTaken) {---(중략)---if (farmCurrentHP <=0) { nowGameState =GameState.gameOver; // 결과창 표시.OpenResult(); }---(중략)---voidCheckSpawnEnemy() {---(중략)--- // 적 생성 데이터 전체가 소모되었다면 게임을 종료하도록 한다.if (currentEnemyWaveDataIndexNo >=enemyWaveDatas.Count) { nowGameState =GameState.gameOver;CancelInvoke("CheckSpawnEnemy"); // 결과창 표시.OpenResult();return; }---(후략)---
---(전략)--- // 결과창이 나타날 때 적 캐릭터를 정지하는 목적으로 사용된다.public event System.Action OnFreeze;---(중략)--- // 모든 적 캐릭터의 FreezeEnemy 메서드를 OnFreeze에 등록.voidSetupAllEnemyFreeze() {int j=0;GameObject tempObj;Enemy tempEnemyScript;for(int i=0; i<spawnEnemyObjs.Count; ++i) { j=0;while(j<gameObjectPools[ spawnEnemyObjs[i].name].lastIndex) {if(gameObjectPools[ spawnEnemyObjs[i].name].GetObject(j,out tempObj)) { tempEnemyScript =tempObj.GetComponent<Enemy>(); // enemy 스크립트의 FreezeEnemy 메서드를 등록. OnFreeze +=tempEnemyScript.FreezeEnemy; }++j; } } }---(후략)---
예제 3-88: GamePlayManager.cs
---(전략)---publicvoidOpenResult() {---(중략)--- // 결과창을 나타나게 한다.resultWindow.SetActive(true); // 이벤트에 등록된 메서드가 있는지 체크.if(OnFreeze !=null) {OnFreeze(); }---(후략)---
---(전략)--- // 사용중이지 않을 때 돌아갈 위치 저장.publicvoidInitReturnPosition(Vector3 setupInitPos) { initPos = setupInitPos; } // 충돌 처리를 허가할 때 사용.publicvoidTurnOnTrigger() { isWork =true; } // 발사 게임 오브젝트를 초기화한다.publicvoidResetShotObj() {transform.position= initPos; isWork =false;rigidbody2D.velocity=Vector3.zero; }---(후략)---
책 335페이지의 AttackAndRemove 메서드는 앞서 제작한 새로운 적 캐릭터 추가의 예제 3-48에 나온 AttackAndDestroy 메서드를 지칭하는 것입니다. 여기서는 앞서 제작한 이름 그대로 AttackAndDestroy로 사용합니다.
예제 3-91: ShotObj.cs
---(전략)---voidOnTriggerEnter2D(Collider2D other) { // 사용중이지 않을 때 충돌 처리를 막는다.if(!isWork) return; // 적 캐릭터 인 경우, 공격하여 피해를 가한다.if (other.CompareTag("enemy") ||other.CompareTag("boss")) { // 공격 후 게임 오브젝트 제거.AttackAndDestroy(other); } // 게임 플레이 화면 외부로 진입했을 때 초기 위치로 돌아가도록 한다.elseif (other.CompareTag("invisibleArea")) {ResetShotObj(); } }protectedvoidAttackAndDestroy(Collider2D other) {IDamageable damageTarget = (IDamageable)other.GetComponent(typeof(IDamageable));damageTarget.Damage(attackPower); // 공격 후 초기화.ResetShotObj(); }---(후략)---
예제 3-92: EnemyShotObj.cs
---(전략)---voidOnTriggerEnter2D(Collider2D other) { // 장애물과 충돌 시, 공격하여 피해를 가한다.if( other.CompareTag("obstacle")) { // 공격 후 게임 오브젝트 제거.AttackAndDestroy(other); } // 게임 플레이 화면 외부로 진입했을 때 초기 위치로 돌아가도록 한다.elseif (other.CompareTag("invisibleArea")) {ResetShotObj(); } }---(후략)---
---(전략)--- // 로비씬으로 전환할 때 사용한다.voidLoadReadyScene(bool isPrepareGame) { // isPrepareGame를 활용하여 로비씬의 준비상태를 분기할 수 있도록 한다.GameData.Instance.isPrepareGame= isPrepareGame;---(후략)---
표 3-89: UIButton 컴포넌트 설정
Pause Widnow 연결
GamePlayManager.Button.cs
publicvoidClickPauseHomeButton() { // 다른 씬으로 전환한다.LoadReadyScene(false); }
게임 플레이 시 invisibleArea 태그를 추가하라는 에러가 나오면 태그를 추가합니다.