체력
EnemyHp작성
public class EnemyHp : MonoBehaviour
{
[SerializeField]
private float maxHp; //최대 체력
private float currentHp;//현재 체력
private bool isDie = false; //적이 사망상태이면 isDie를 true로 설정
private Enemy enemy;
private SpriteRenderer spriteRenderer;
private void Awake()
{
currentHp = maxHp; // 현재체력을 최대체력과 같게 설정
enemy = GetComponent<Enemy>();
spriteRenderer = GetComponent<SpriteRenderer>();
}
public void TakeDamge(float damage)
{
//Tip. 적의 체력이 damage 만큼 감소해서 죽을 상황일 때 여러 타워의 공격을 동시에 받으면
// enemy.OnDie() 함수가 여러번 실행될 수 있다.
// 현재 적의 상태가 사망 상태이면 아래 코드를 실행하지 않는다.
if (isDie == true) return;
//현재 체력을 damage만큼 감소
currentHp -= damage;
StopCoroutine("HitAlphaAnimation");
StartCoroutine("HitAlphaAnimation");
// 체력이 0이하 = 적 캐릭터 사망
if (currentHp <= 0)
{
isDie = true;
// 적 캐릭터 사망
enemy.OnDie();
}
}
private IEnumerator HitAlphaAnimation()
{
// 현재 적의 색상을 color 변수에 저장
Color color = spriteRenderer.color;
// 적의 투명도를 40%로 설정
color.a = 0.4f;
spriteRenderer.color = color;
// 0.05초 동안 대기
yield return new WaitForSeconds(0.05f);
// 적의 투명도를 100%로 설정
color.a = 1.0f;
spriteRenderer.color = color;
}
}
TowerWeapon수정
- Tower의 attackDamage를 생성하고
- Projectile 발사체에게 타워의 공격력 정보를 매개변수로 전달한다
Projectile 수정
- TowerWeapon에서 받은 인자를 damage에 넣고
- 기존에 충돌했을 떄 OnDie()했던 것을 TakeDamage()로 변경
체력바 생성
- ui에서 slider생성
- ui scale mode를 scale with screen size로
x,y를 현재 해상도로, match를 가운데로 해준다
- 상호작용 불가능 하게 Handle slide 삭제
SliderPositionAutoSetter 작성
EnemyHp 수정
EnemyHpViewer 작성
EnemySpawner 수정
ublic class EnemySpawner : MonoBehaviour
{
[SerializeField]
private GameObject enemyPrefeb; //적 프리팹
[SerializeField]
private GameObject enemyHpSliderPrefeb; //적 체력을 나타내는 slider UI 프리팹
[SerializeField]
private Transform canvasTransform; // UI를 표현하는 Canvas 오브젝트의 Transform
[SerializeField]
private float spawnTimes;//적 생성 주기
[SerializeField]
private Transform[] wayPoints; //현재 스테이지의 이동경로
private List<Enemy> enemyList; //현재 맵에 존재하는 모든 적의 정보
//적의 생성과 삭제는 EnemySpawner에서 하기에 set은 필요 없다
public List<Enemy> EnemyList => enemyList;
//public object EnemyList { get; internal set; }
private void Awake()
{
//적 리스트 메모리 할당
enemyList = new List<Enemy>();
//적 생성 코루틴 함수 호출
StartCoroutine("SpwanEnemy");
}
private IEnumerator SpwanEnemy()
{
while(true)
{
GameObject clone = Instantiate(enemyPrefeb); //적 오브젝트 생성
Enemy enemy = clone.GetComponent<Enemy>(); // 방금 생성된 적의 enemy 컴포넌트
//this는 나 자신(자신의 EnemySpawner 정보)
enemy.Setup(this, wayPoints); //wayPoint정보를 매개변수로 setup() 호출
enemyList.Add(enemy); //리스트에 방금 생성된 적 정보 저장
SpawnEnemyHPSlider(clone); // 적 체력을 나타내는 Slider UI 생성 및 설정
yield return new WaitForSeconds(spawnTimes); //spawn시간 동안 대기
}
}
public void DestroyEnemy(Enemy enemy)
{
//리스트에서 사망하는 적 정보 삭제
enemyList.Remove(enemy);
//적 오브젝트 삭제
Destroy(enemy.gameObject);
}
private void SpawnEnemyHPSlider(GameObject enemy)
{
// 적 체력을 나타내는 Slider UI 생성
GameObject sliderClone = Instantiate(enemyHpSliderPrefeb);
// Slider UI 오브젝트를 parent("Canvas" 오브젝트)의 자식으로 설정
//Tip. UI는 캔버스의 자식오브젝트로 설정되어 있어야 화면에 보인다
sliderClone.transform.SetParent(canvasTransform);
// 계층 설정으로 바뀐 크기를 다시(1,1,1)로 설정
sliderClone.transform.localScale = Vector3.one;
// Slider UI가 쫒아다닐 대상을 본인으로 설정
sliderClone.GetComponent<SliderPositionAutoSetter>().Setup(enemy.transform);
// Slider UI에 자신의 체력 정보를 표시하도록 설정
sliderClone.GetComponent<EnemyHpViewer>().Setup(enemy.GetComponent<EnemyHp>());
}
}