트레이서 편을 이어서 제목을 정하려 했으나 사실상 HP의 개념은 모든 캐릭터, 심지어 모든 FPS 게임에 적용되므로.. 제목을 트레이서 편으로 하지 않았다... 라는 설명입니다.
오버워치 위키(레퍼런스 1번) 사이트에는 오버워치 영웅들의 HP 정보가 잘 적혀있다. 지금까지 구현한 영웅은 트레이서밖에 없으니, 트레이서의 HP를 구현해보도록 하자.
다행히 트레이서는 이상한 overhealth 같은거 없이 150 health를 가지고 있다. (트레이서부터 구현하길 잘한듯..)
A. 플레이어 Health 구현 및 표현
사실 health만 구현하는 것은 쉽다.
Float 변수 하나 만들어서 150으로 지정해주면 끝.
중요한 건 이 health를 HP bar를 통해 유저가 게임 플레이하며 보는 것이다. 빠르게 HP 바를 구현해보자.
트레이서 편에서 만든 트레이서의 하위 오브젝트로 Canvas를 만들고, HealthBar를 만들기 위한 요소들을 추가한다.
Health bar의 백그라운드, 실제 Health를 나타내는 흰색 바, 그리고 Health의 수치를 나타내는 숫자 텍스트를 추가했다.
다른 사람들은 어떻게 하는지 레퍼런스를 참고 안해봐서 잘 모르겠지만, Health가 줄어드는 것을 다음과 같이 구현했다.
흰색 Health bar의 X값(가로길이)는 1이다. 따라서 200에서 체력이 100으로 줄었다고 했을 때,
1 * (100/200) = [HealthBar의 X값] * ([현재 체력]/[최대 체력])
값을 Health bar의 X값에 적용하면 흰색 바가 딱 반으로 줄 것이다. (아래 결과 영상에서 볼 수 있음.)
다음 코드는, Q를 눌렀을 때, 150인 트레이서의 체력이 반으로 깎이도록 구현한 것이다. (테스트용으로 구현해봄)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class HealthController : MonoBehaviour
{
public float health;
public GameObject healthBar;
public float healthBarMaxX;
public bool zeroHealth;
private float maxHealth;
private TextMeshProUGUI healthText;
private bool qTest;
void Start()
{
maxHealth = health;
healthText = GetComponentInChildren<TextMeshProUGUI>();
}
// Update is called once per frame
void Update()
{
GetInput();
if (qTest) GetDamage(150/2);
healthText.text = health.ToString();
if (health <= 0f)
{
zeroHealth = true;
health = maxHealth;
healthBar.transform.localScale = new Vector3(healthBarMaxX, healthBar.transform.localScale.y, healthBar.transform.localScale.z);
}
}
void GetInput()
{
qTest = Input.GetKeyDown(KeyCode.Q);
}
public void GetDamage(float damage)
{
health -= damage;
float XhealthBar = healthBarMaxX * (health/maxHealth);
healthBar.transform.localScale = new Vector3(XhealthBar, healthBar.transform.localScale.y, healthBar.transform.localScale.z);
}
}
zeroHealth는 플레이어의 체력이 0 이하가 되면 true가 된다.
이렇게, 기본 적으로 Health bar의 구현 및 표현을 해봤다.
B. 총알에 의해 데미지 받기
이제는 트레이서가 투사체에 맞았을 때, HP가 달도록 해보겠다.
내가 알기론, 오버워치에는 두 가지 종류의 기본 공격이 있다.
1. 총알, 히트스 (ex. 캐서디, 애쉬)
(아마도) Raycast를 사용하듯이 에임 선상에 적이 있을 때 공격하면 시간차 없이 바로 데미지가 들어감.
2. 투사체 (ex. 정크랫, 파라)
직접 폭탄 등을 던지고, 던져진 투사체에 적이 충돌해야 데미지가 들어감.
이번에 트레이서가 총알에 맞게 하려면 Raycast로 총을 쏘는 애가 필요하기 때문에 현재로서는 불가능..
일단 임의로 날라다니는 투사체를 만들어서 구현해보도록 하겠다.
정크랫 폭탄 같은 투사체를 하나 만들고, 투사체가 화살표의 방향으로 움직이도록 설정했다. 해당 투사체에는 damage라는 변수가 있는데, 이 damage라는 변수는 투사체가 트레이서와 충돌하면 쓰이게 될 것이다.
다음은 투사체에 부착한 스크립트이다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestBullet : MonoBehaviour
{
public float damage;
public float speed;
private Vector3 initPosition;
void Start()
{
initPosition = transform.position;
}
void Update()
{
transform.position -= new Vector3(0f, 0f, speed);
}
void OnCollisionEnter(Collision other)
{
transform.position = initPosition;
}
}
위에서 말했듯이 투사체는 한 방향으로 쭉 가다가 콜라이더와 충돌하면 초기 위치로 가서 다시 움직인다.
콜라이더와의 충돌은 OnCollisionEnter를 통해 감지한다.
코드에서 damage 변수가 해당 투사체의 데미지 값이다.
TracerController에 가장 위에서 구현한 health controller를 받아오고, 플레이어가 죽었을 때 리스폰 할 수 있도록 리스폰 포지션을 저장해둔다.
TracerController의 Update 함수에서, health controller의 변수 zeroHealth가 true이면 Die()함수를 호출한다.
Die() 함수에서는 플레이어를 리스폰 포지션으로 이동시키고, true였던 zeroHealth를 다시 false로 바꾸어준다.
원래 오버워치에서 죽으면 10초간 기다린 후에 리스폰 지역에서 리스폰 되는데, 일단 임의로 저렇게 해주었다.
C. 결과
트레이서 체력: 150
투사체 데미지: 40
일 때, 테스트 영상이다.
다음 편에서는.. 또 다른 트레이서의 디테일을 다루거나.. 아니면 트레이서 기본 공격을 해보겠다.
그럼 .. 즐개~ (즐거운 개발이란 뜻......)
Reference
1. https://overwatch.fandom.com/wiki/Hit_points#List_of_hero_HP
'Unity > 오버워치 따라잡기' 카테고리의 다른 글
[Unity] 오버워치 따라잡기! 트레이서 편(6) - 기본 공격 장전 (0) | 2023.05.06 |
---|---|
[Unity] 오버워치 따라잡기! 트레이서 편(5) - 기본 공격 (0) | 2023.05.04 |
[Unity] 오버워치 따라잡기! 트레이서 편(5) - Recall 시간역행 (0) | 2023.03.17 |
[Unity] 오버워치 따라잡기! 트레이서 편(4) - Recall 시간역행 (0) | 2023.03.17 |
[Unity] 오버워치 따라잡기! 트레이서 편(3) - Blink 점멸 (0) | 2023.03.16 |