https://made-myblog.tistory.com/75
-팀원분이 만들어주신 Enemy 공격 테스트씬을 참고하여 GameScene에 적용하기 위한 포스팅이다.
-EnemyMove.cs를 수정하였다.
muzzleTrans : 총알이 발사될 지점
muzzleGo : player를 향해 겨눌 총구의 object
playerTrans : 적이 공격할 player의 transform
attackCount : 공격 횟수(한 번 공격을 시작할 때 몇 번 쏠 것인지)
dealLossTime : attackCount만큼 공격할 때 간격(주기)
onAttackPlayer : enemy가 player 공격에 성공했을 때 main에게 알리는 대리자
onCompleteAttack : enemy가 attackCount만큼 공격을 다 하고 난 뒤 main에게 알리는 대리자
isAttack : 현재 enemy가 공격하는 중인지 아닌지를 알리는 상태
-Enemy 1, 2, 3에게 muzzleTrans, muzzleGo, AttackCount, DeadLossTime을 다음과 같이 할당한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using System;
public class EnemyMove : MonoBehaviour
{
public enum eEnemyType
{
Enemy1, Enemy2, Enemy3
}
public eEnemyType enemyType;
public KeyValuePair<int, Transform> target;
protected bool isReady;
public float moveSpeed = 5.5f;
public float rotSpeed = 8f;
public float changeTargetTime = 5f;
public float trackingTargetTime = 2f;
private float elapsedTime = 3f;
public float offset = 0.5f;
public float length = 3.5f;
public int depth = 3;
public Action<int> onChangeTarget;
protected Rigidbody rBody;
private List<Tuple<Ray, bool>> listRays = new List<Tuple<Ray, bool>>();
private Vector3 dir;
private bool isDetected;
//player attack
//=============================================================================================================================
[SerializeField] protected Transform[] muzzleTrans;
[SerializeField] protected GameObject muzzleGo;
protected Transform playerTrans;
public int attackCount = 3;
public float dealLossTime = 0.2f;
public Action onAttackPlayer;
public Action onCompleteAttack;
protected bool isAttack;
//=============================================================================================================================
private void FixedUpdate()
{
if (!this.isReady) return;
this.AimPlayer();
this.Detect();
this.DecideDir();
this.Move();
}
private void Start()
{
this.rBody = this.GetComponent<Rigidbody>();
}
virtual public void Init(Vector3 pos)
{
//..Enemy 위치 지정 후
this.transform.position = pos;
//..활성화(보여주기)
this.gameObject.SetActive(true);
}
virtual public void Detect()
{
this.listRays.Clear();
this.isDetected = false;
Vector3[] pos = new Vector3[] { this.transform.right, -this.transform.right, this.transform.forward };
for (int i = 0; i < pos.Length; i++)
{
Ray ray = new Ray(this.transform.position + Vector3.up * this.offset, pos[i]);
DrawAndHitRay(ray);
}
for (int i = 0; i < 2; i++)
{
this.RecurDrawAndHitRay(pos[i], pos[2], 0);
}
}
virtual public void Move()
{
float curSpeed = this.moveSpeed;
float posZ = this.transform.position.z;
float targetPosZ = this.target.Value.position.z;
if (posZ > targetPosZ + 15)
{
curSpeed = this.moveSpeed * 1.5f;
}
else if (posZ > targetPosZ + 7)
{
curSpeed = this.moveSpeed;
}
else if (posZ > targetPosZ + 3)
{
curSpeed = this.moveSpeed * 0.9f;
}
if (this.isDetected) curSpeed *= 0.8f;
//float velocityY = this.rBody.velocity.y;
//this.rBody.velocity = this.transform.forward * curSpeed;
//this.rBody.velocity += Vector3.up * velocityY;
this.rBody.MovePosition(this.rBody.position + this.transform.forward * curSpeed * Time.fixedDeltaTime);
//Debug.LogFormat("<color=green>curspeed: {0}</color>", curSpeed);
}
virtual public void DecideDir()
{
List<List<Ray>> listNotHitRays = new List<List<Ray>>();
List<Tuple<Ray, bool>> newListRays = listRays.OrderBy(x => Vector3.Distance(x.Item1.direction, this.transform.right)).ToList();
for (int i = 0; i < newListRays.Count; i++)
{
Tuple<Ray, bool> tupleRay = newListRays[i];
if (!tupleRay.Item2)
{
if (listNotHitRays.Count == 0)
{
listNotHitRays.Add(new List<Ray>());
}
listNotHitRays[listNotHitRays.Count - 1].Add(tupleRay.Item1);
if (i < newListRays.Count - 1 && newListRays[i + 1].Item2)
{
listNotHitRays.Add(new List<Ray>());
}
}
}
if (this.isDetected)
{
this.elapsedTime = 0f;
int maxCount = 0;
int maxCountIndex = 0;
for (int i = 0; i < listNotHitRays.Count; i++)
{
if (listNotHitRays[i].Count > maxCount)
{
maxCount = listNotHitRays[i].Count;
maxCountIndex = i;
}
}
this.dir = Vector3.zero;
for (int i = 0; i < listNotHitRays[maxCountIndex].Count; i++)
{
this.dir += listNotHitRays[maxCountIndex][i].direction;
}
this.dir /= maxCount;
this.transform.rotation = Quaternion.Lerp(this.transform.localRotation, Quaternion.LookRotation(this.dir), this.rotSpeed * Time.deltaTime);
}
else
{
this.elapsedTime += Time.deltaTime;
if (this.elapsedTime > this.trackingTargetTime)
{
this.dir = this.target.Value.position - this.transform.position;
//Debug.LogFormat("<color=red>{0}</color>", Quaternion.LookRotation(this.dir));
this.transform.rotation = Quaternion.Lerp(this.transform.rotation, Quaternion.LookRotation(this.dir), this.rotSpeed * Time.deltaTime * 0.6f);
}
else
this.transform.rotation = Quaternion.Lerp(this.transform.localRotation, Quaternion.LookRotation(this.dir), this.rotSpeed * Time.deltaTime);
}
}
virtual public void RecurDrawAndHitRay(Vector3 pos1, Vector3 pos2, int depth)
{
Ray ray = new Ray(this.transform.position + Vector3.up * this.offset, (pos1 + pos2).normalized);
this.DrawAndHitRay(ray);
if (depth < this.depth)
{
this.RecurDrawAndHitRay(pos1, (pos1 + pos2).normalized, depth + 1);
this.RecurDrawAndHitRay(pos2, (pos1 + pos2).normalized, depth + 1);
}
}
virtual public void DrawAndHitRay(Ray ray)
{
int layerMask = 1 << 3 | 1 << 6 | 1 << 7;
RaycastHit hit;
if (Physics.Raycast(ray, out hit, this.length, layerMask))
{
this.isDetected = true;
Debug.DrawRay(ray.origin, ray.direction.normalized * this.length, Color.red);
this.listRays.Add(new Tuple<Ray, bool>(ray, true));
// Debug.LogFormat("<color=blue>hit</color>: {0}", hit.collider.gameObject);
}
else
{
Debug.DrawRay(ray.origin, ray.direction.normalized * this.length, Color.green);
this.listRays.Add(new Tuple<Ray, bool>(ray, false));
}
}
virtual public void UpdateTargetPos(int idx, Transform targetTrans)
{
this.target = new KeyValuePair<int, Transform>(idx, targetTrans);
if (!isReady)
{
isReady = true;
this.StartCoroutine(this.CoChangeTarget());
}
}
virtual public IEnumerator CoChangeTarget()
{
while (true)
{
yield return new WaitForSeconds(this.changeTargetTime);
this.onChangeTarget(this.target.Key);
}
}
//추가 구현(공격)===========================================================================================================================
//조준
protected void AimPlayer()
{
this.muzzleGo?.transform.LookAt(this.playerTrans);
}
//player 공격 method
public void AttackPlayer()
{
StartCoroutine(this.CoAttackPlayer());
}
//dealLossTime에 맞춰 player를 공격하는 method
protected IEnumerator CoAttackPlayer()
{
for (int i = 0; i < this.attackCount; i++)
{
for (int j = 0; j < this.muzzleTrans.Length; j++)
{
GameObject bulletGo = BulletGenerator.Instance.GenerateBullet(this.muzzleTrans[j]);
Bullet bullet = bulletGo.GetComponent<Bullet>();
Debug.Log(bullet);
bullet.Init(() =>
{
this.onAttackPlayer();
});
}
yield return new WaitForSeconds(this.dealLossTime);
}
this.onCompleteAttack(); //공격이 완료되면 대리자를 사용하여 TestEnemy1Main.cs에게 공격 완료를 알림.
}
//=======================================================================================================================================
virtual public void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(this.transform.position, 2f);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class Enemy1Move : EnemyMove
{
public Action<EnemyData> OnGetData;
public Action<int> OnGetHit;
public Transform hpBarPoint;
public int currHP = 0;
private int maxHP = 0;
public Action<Enemy1Move> onDieEnemy;
private void Awake()
{
this.OnGetData = (data) =>
{
//this.currHP = data.enemyHp; ;//set HP;
this.maxHP = data.enemyHp; ;//set HP;
this.currHP = this.maxHP;
};
}
private void Start()
{
this.rBody = GetComponent<Rigidbody>();
this.OnGetHit = (damage) =>
{
this.currHP -= damage;
};
}
private void FixedUpdate()
{
this.Detect();
this.DecideDir();
this.Move();
if (this.currHP <= 0)
{
Debug.Log("<color=red>Enemy1 Die!!!!!!!!!</color>");
this.onDieEnemy(this);
if (isAttack)
{
this.onCompleteAttack();
}
}
}
public override void Init(Vector3 pos)
{
base.Init(pos);
this.currHP = this.maxHP;
}
public override void Detect()
{
base.Detect();
}
public override void DecideDir()
{
base.DecideDir();
}
public override void Move()
{
base.Move();
}
public override void RecurDrawAndHitRay(Vector3 pos1, Vector3 pos2, int depth)
{
base.RecurDrawAndHitRay(pos1, pos2, depth);
}
public override void DrawAndHitRay(Ray ray)
{
base.DrawAndHitRay(ray);
}
public override void UpdateTargetPos(int idx, Transform targetTrans)
{
base.UpdateTargetPos(idx, targetTrans);
}
public override IEnumerator CoChangeTarget()
{
return base.CoChangeTarget();
}
public override void OnDrawGizmos()
{
base.OnDrawGizmos();
}
}
-----------------------------------------------------------------------------------------------------------------------------------------------------------------Bullet
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class Bullet : MonoBehaviour
{
private Transform target;
private Rigidbody rBody;
private Vector3 targetPos;
public float moveSpeed = 5f;
public Action onAttackPlayer;
// Start is called before the first frame update
void Start()
{
this.target = GameObject.Find("CenterEyeAnchor").transform;
this.targetPos = this.target.position;
this.rBody = this.GetComponent<Rigidbody>();
}
public void Init(Action callback)
{
this.onAttackPlayer = callback;
}
// Update is called once per frame
void FixedUpdate()
{
this.transform.LookAt(this.target);
this.rBody.MovePosition(this.rBody.position + this.transform.forward * this.moveSpeed * Time.fixedDeltaTime);
if (this.transform.position.z < this.target.position.z)
{
Destroy(this.gameObject);
}
}
private void OnTriggerEnter(Collider collision)
{
Debug.LogFormat("gameObject: {0}, tag: {1}", collision.gameObject.name, collision.tag);
if (collision.CompareTag("Player"))
{
Debug.Log("attack player");
this.onAttackPlayer();
}
Destroy(this.gameObject);
}
}
-Bullet 프리팹 생성 후 Bullet.cs 부착해준다.
-빈오브젝트를 생성해 BulletGenerator를 붙여준 후 Bullet Prefab에 생성한 Bullet 프리팹을 할당해준다.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
Main 수정
-Player의 CeneterEyeAnchor의 자식으로 다음과 같은 오브젝트를 넣어준다.
-Player와 충돌했는지 확인하게하는 역할을 한다.
----------------------------------------------------------------------------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------------------------------------------------------------------------
Player HP 연동
-main에서 저장하고있는 현재 PlayerHp를 공격당함에 따라 감소시켜줘야한다.
-이 HP는 플레이어의 정면에있는 UI에 나타난다.
-메인에 플레이어의 데이터를 초기화하기 위해 start 시 데이터를 가져오도록했다.
- 플레이어가 공격당했을 때 현재 player의 HP를 감소시킨다.
- HP 슬라이더의 max 값을 처음에 데이터 가져올때 함께 셋팅시킨다.
-플레이어의 현재 HP 값을 UI에 보여지도록 update에서 변경되도록 하였다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using System;
using System.Linq;
using Newtonsoft.Json;
using System.IO;
public class GameMain : MonoBehaviour
{
[SerializeField] Canvas worldCanvas;
[SerializeField] Canvas rightHandCanvas;
[SerializeField] TextMeshProUGUI guideText;
[SerializeField] GameObject uiHPBarPrefab;
[SerializeField] GameObject uiDamageTextPrefab;
[SerializeField] GameObject uiEnergyCellPrefab;
[SerializeField] GameObject gunEnergyCellGo;
[SerializeField] GameObject uiPlayerHpText;
[SerializeField] GameObject uiPlayerHpSlider;
[SerializeField] EnergyCellController energyCellForCharge;
[SerializeField] RightHandController rightHand;
[SerializeField] Transform uiEnergyCellTransform;
[SerializeField] Transform worldUITransform;
public bool isFirstHP = false;
private GameObject hpBarUIGo;
private GameObject damageTextUIGo;
private GameObject energyTextUIGo;
private Action<Enemy1Move> OnGenerateEnemy;
private int currPlayerHp;
private int currScore;
private int currShiledGauge;
private int currGunId;
private string currGunType;
private int currGunDamage;
private int currGunEnergy;
private int currGunMaxEnergy;
private List<GameObject> enemyHpBarPools = new List<GameObject>();
private List<GameObject> activeHPBar = new List<GameObject>();
//----------------------------------SJY Map Main-----------------------------------------------------------
[SerializeField] private MapController mapController;
[SerializeField] private CamMove camMove;
//----------------------------------SJY Enemy1Move Main-----------------------------------------------------------
public enum eWave
{
WAVE1, WAVE2, WAVE3
}
private eWave wave;
[SerializeField] private Transform[] arrTargetPos;
private List<Enemy1Move> listEnemies = new List<Enemy1Move>();
private List<bool> isTargeted = new List<bool>();
private int EnemyCount = 2;
private int[] maxWaveEnemyCount = new int[3] { 3, 6, 9 };
private int remainEnemyCount;
//----------------------------------SJY EnemyAttack-----------------------------------------------------------
private float enemyAttackCoolTime = 4f;
private float enemyAttackelapsedTime;
private bool isEnemyAttack;
private int enemyAttackIdx = 0;
private void Awake()
{
}
// Start is called before the first frame update
void Start()
{
Debug.Log("Start");
this.guideText.gameObject.SetActive(false);
this.worldCanvas.transform.SetParent(this.worldUITransform);
this.worldCanvas.transform.localPosition = Vector3.zero;
this.worldCanvas.transform.localRotation = Quaternion.identity;
this.energyTextUIGo = this.uiEnergyCellPrefab;
this.rightHandCanvas.transform.SetParent(this.uiEnergyCellTransform);
this.rightHandCanvas.transform.localPosition = Vector3.zero;
this.rightHandCanvas.transform.localRotation = Quaternion.identity;
DataManager.Instance.LoadPlayerDatas();
DataManager.Instance.LoadGunrDatas();
DataManager.Instance.LoadEnemyDatas();
List<PlayerData> playerData = DataManager.Instance.GetPlayerDatas();
List<GunData> gunData = DataManager.Instance.GetGunDatas();
List<EnemyData> enemyData = DataManager.Instance.GetEnemyDatas();
Debug.LogFormat("player Data Count: {0}",playerData.Count);
for(int i = 0; i < playerData.Count; i++)
{//get player data
if (playerData[i].playerUserName == "Unknown")
{
Debug.Log("default user");
this.currPlayerHp = playerData[i].playerHp;
this.currScore = playerData[i].score;
this.currShiledGauge = playerData[i].shiledGauge;
this.currGunId = playerData[i].currGunId;
}
}
this.uiPlayerHpSlider.GetComponent<Slider>().maxValue = this.currPlayerHp;
// var playerGunId = playerData[0].currGunId;
Debug.LogFormat("Gun Data Count: {0}", gunData.Count);
for (int i = 0; i < gunData.Count; i++)
{
if (this.currGunId == gunData[i].gunId)
{//Find player's current gun's Data on GunData
Debug.Log(gunData[i].gunType);
this.currGunType = gunData[i].gunType;
this.currGunDamage = gunData[i].gunDamage;
this.currGunEnergy = gunData[i].gunEnergyCell;
this.currGunMaxEnergy = gunData[i].gunEnergyCell;
}
}
this.enemyHpBarPool();
this.damageTextUIGo = Instantiate(this.uiDamageTextPrefab, this.worldCanvas.transform);
this.damageTextUIGo.SetActive(false);
this.OnGenerateEnemy = (enemy) =>
{
var go = this.CreateHpBar(enemy.hpBarPoint.position);
this.activeHPBar.Add(go);
for (int j = 0; j < enemyData.Count; j++)
{
if (enemy.tag == enemyData[j].enemyType)
{
Debug.Log(enemyData[j].enemyType);
var slider = go.GetComponent<Slider>();
slider.maxValue = enemyData[j].enemyHp;
Debug.Log(slider.maxValue);
slider.value = slider.maxValue;//reset slider value as full state
//this.listEnemies[j].currHP = (int)slider.value; //set EnemyHp
//Debug.Log(listEnemies[j].gameObject);
enemy.OnGetData(enemyData[j]);
}
}
};
this.rightHand.OnHitEnemy = (hitPos,hitObject) =>
{
// Debug.LogFormat("Hit Enemy! Point: {0}", hitPos);
StartCoroutine(this.CoShowDamageText(hitPos));
for (int i = 0; i < this.listEnemies.Count; i++)
{
if (hitObject == this.listEnemies[i].gameObject)
{
Debug.LogFormat("Object: {0} , Damage : {1}",i,currGunDamage);
this.activeHPBar[i].GetComponent<Slider>().value -= currGunDamage;
hitObject.GetComponent<Enemy1Move>().OnGetHit(currGunDamage);
if(this.activeHPBar[i].GetComponent<Slider>().value <= 0)
{
this.activeHPBar[i].SetActive(false);
this.activeHPBar.Remove(this.activeHPBar[i]);
}
}
}
};
this.rightHand.OnShoot = () =>
{
this.currGunEnergy -= 1;
};
this.energyCellForCharge.OnCharge = () => {
this.currGunEnergy = this.currGunMaxEnergy;//reset energyCell as full state
this.gunEnergyCellGo.SetActive(true);
StartCoroutine(this.CoResetEnergyCellItem());
};
//----------------------------------SJY Map Main-----------------------------------------------------------
Vector3 camPos = Vector3.zero;
this.mapController.onInformInitPos = (pos) =>
{
camPos = pos;
};
this.mapController.onInformRoute = (rail) =>
{
this.camMove.UpdateRoute(rail.GetRoute());
};
this.mapController.Init();
this.camMove.Init(camPos);
//----------------------------------SJY Enemy1Move Main-----------------------------------------------------------
// EnemyPool.instance.LoadAll();
for (int i = 0; i < arrTargetPos.Length; i++)
{
isTargeted.Add(false);
}
this.StartCoroutine(this.CoStartSpawnEnemy1());
}
private IEnumerator CoResetEnergyCellItem()
{
this.energyCellForCharge.gameObject.SetActive(false);
yield return new WaitForSeconds(2f);
// Debug.Log("Rest Energy Item");
this.energyCellForCharge.transform.SetParent(this.energyCellForCharge.energyCellOriginalPoint);
this.energyCellForCharge.transform.localPosition = Vector3.zero;
this.energyCellForCharge.transform.localRotation = Quaternion.identity;
this.energyCellForCharge.gameObject.SetActive(true);
}
private void enemyHpBarPool()
{
for (int i = 0; i < this.EnemyCount; i++)
{
GameObject go = Instantiate(this.uiHPBarPrefab, this.worldCanvas.transform);
go.SetActive(false);
this.enemyHpBarPools.Add(go);
}
}
private GameObject GetEnemyHpBarInPool()
{
foreach(GameObject hpBar in enemyHpBarPools)
{
if(hpBar.activeSelf == false)
{
return hpBar;
}
}
return null;
}
private GameObject CreateHpBar(Vector3 position)
{
GameObject go = this.GetEnemyHpBarInPool();
go.transform.position = position;
go.SetActive(true);
return go;
}
private IEnumerator CoShowDamageText(Vector3 UIPos)
{
this.damageTextUIGo.transform.position = UIPos;
this.damageTextUIGo.SetActive(true);
var text = this.damageTextUIGo.GetComponent<TextMeshProUGUI>();
text.text = string.Format("{0}",this.currGunDamage);
yield return new WaitForSeconds(0.3f);
this.damageTextUIGo.SetActive(false);
}
// Update is called once per frame
void Update()
{
//enemy 공격 구현=======================================================================================
if (this.listEnemies.Count > 0 && !isEnemyAttack)
{
this.enemyAttackelapsedTime += Time.deltaTime;
if (this.enemyAttackelapsedTime > this.enemyAttackCoolTime)
{
this.listEnemies[(enemyAttackIdx++ % this.listEnemies.Count)].AttackPlayer();
this.isEnemyAttack = true;
}
}
else
{
this.enemyAttackelapsedTime = 0f;
this.isEnemyAttack = false;
}
//=======================================================================================
if (activeHPBar.Count != 0)
{
for (int i = 0; i < this.listEnemies.Count; i++)
{
//Debug.LogFormat("{0}, {1}", this.activeHPBar[i], this.listEnemies[i]);
this.activeHPBar[i].transform.position = this.listEnemies[i].hpBarPoint.position;
}
}
//change energyCell UI's text
this.energyTextUIGo.GetComponent<TextMeshProUGUI>().text = string.Format("{0}", this.currGunEnergy);
//change player HP UI
this.uiPlayerHpText.GetComponent<TextMeshProUGUI>().text = string.Format("{0}", this.currPlayerHp);
this.uiPlayerHpSlider.GetComponent<Slider>().value = this.currPlayerHp;
this.rightHand.isAttack = true;
if(this.currGunEnergy <= 0)
{
this.gunEnergyCellGo.SetActive(false);
this.rightHand.isAttack = false;
}
if (isFirstHP)
{
this.guideText.gameObject.SetActive(true);
this.guideText.text = "물약을 잡아 HP를 회복하세요.";
}
}
//Methods
//----------------------------------SJY Enemy1Move Main-----------------------------------------------------------
private IEnumerator CoStartSpawnEnemy1()
{
this.remainEnemyCount = maxWaveEnemyCount[(int)this.wave];
for (int i = 0; i < this.EnemyCount; i++)
{
yield return new WaitForSeconds(5f);
this.SpawnEnemy1();
}
}
private void SpawnEnemy1()
{
float x = UnityEngine.Random.Range(-3f, 3f);
float z = UnityEngine.Random.Range(10f, 15f);
while (true)
{
int layer = 1 << 3 | 1 << 6 | 1 << 7;
//Debug.Log(layer.ToBinaryString());
//Debug.Log(enemy.gameObject.layer.ToString());
Collider[] hit = new Collider[10];
int num = Physics.OverlapSphereNonAlloc(this.arrTargetPos[2].position + Vector3.right * x
+ Vector3.forward * z, 2f, hit, layer);
if (num == 0)
break;
x = UnityEngine.Random.Range(-3f, 3f);
z = UnityEngine.Random.Range(10f, 20f);
}
Vector3 pos = this.arrTargetPos[2].position + Vector3.right * x + Vector3.forward * z;
int idx = 0;
int number = UnityEngine.Random.Range(0, 10);
switch (this.wave)
{
case eWave.WAVE1:
idx = (int)EnemyMove.eEnemyType.Enemy1;
break;
case eWave.WAVE2:
if (number < 3)
{
idx= (int)EnemyMove.eEnemyType.Enemy1;
}
else
idx=(int)EnemyMove.eEnemyType.Enemy2;
break;
case eWave.WAVE3:
if (number < 2)
{
idx = (int)EnemyMove.eEnemyType.Enemy1;
}
else if (number < 4)
{
idx = (int)EnemyMove.eEnemyType.Enemy2;
}
else
{
idx = (int)EnemyMove.eEnemyType.Enemy3;
}
break;
}
GameObject enemyGo = EnemyPoolManager.instance.EnableEnemy(idx);
Enemy1Move enemy = enemyGo.GetComponent<Enemy1Move>();
enemy.Init(pos);
listEnemies.Add(enemy);
enemy.onChangeTarget = (idx) =>
{
Debug.Log("target change!");
Debug.LogFormat("<color=yellow>{0} preTargetPos: {1}</color>", enemy.name, arrTargetPos[idx]);
this.SetTargetPos(enemy);
this.isTargeted[idx] = false;
};
enemy.onDieEnemy = (enemy) =>
{
this.remainEnemyCount--;
listEnemies.Remove(enemy);
this.isTargeted[enemy.target.Key] = false;
EnemyPoolManager.instance.DisableEnemy(enemy.gameObject);
if (this.remainEnemyCount >= this.EnemyCount)
{
Invoke("SpawnEnemy1", 2f);
}
else
{
if (this.remainEnemyCount == 0)
{
Debug.LogFormat("{0} completed", this.wave.ToString());
if (this.wave == eWave.WAVE3) return;
this.wave++;
this.StartCoroutine(CoStartSpawnEnemy1());
}
}
};
//enemy Attack 추가부분================================================================================================
enemy.onAttackPlayer = () =>
{
int damage = DataManager.Instance.GetEnemyData(enemy.tag).enemyDamage;
Debug.LogFormat("player get {0} damage / current Player's HP: {1}", damage, this.currPlayerHp);
this.currPlayerHp -= damage;
};
enemy.onCompleteAttack = () =>
{
Debug.Log("enemy attack complete");
this.isEnemyAttack = false;
this.enemyAttackelapsedTime = 0f;
};
//====================================================================================================================
this.SetTargetPos(enemy);
this.OnGenerateEnemy(enemy);
}
private void SetTargetPos(Enemy1Move enemy)
{
List<int> listIndex = new List<int>();
for (int i = 0; i < this.isTargeted.Count; i++)
{
if (!isTargeted[i])
{
listIndex.Add(i);
}
}
int rand = UnityEngine.Random.Range(0, listIndex.Count);
int idx = listIndex[rand];
enemy.UpdateTargetPos(idx, this.arrTargetPos[idx]);
this.isTargeted[idx] = true;
Debug.LogFormat("<color=magenta>{0} curTargetPos: {1}</color>", enemy.name, arrTargetPos[idx]);
}
}
'[VR] GroundZero 개발' 카테고리의 다른 글
[4Idle - GroundZero] Wave 기능 구현 2 (0) | 2024.01.04 |
---|---|
[4Idle - Gazzlers] Player의 Score 데이터 연동 및 UI 수정 / 회복 아이템 사용 시 데이터 연동 (0) | 2023.12.28 |
[4Idle - Gazzlers] GameScene 맵 수정 (1) | 2023.12.26 |
[4Idle - Gazzlers] GameScene에 Wave 별로 Enemy 1,2,3 생성 (1) | 2023.12.26 |
[4Idle - Gazzlers] GameScene test 빌드 문제 해결 2 (0) | 2023.12.22 |