🎮 Game Dev (게임개발)/PC (데스크탑, 노트북, 터치패널)
[3D 액션게임] 09. 피격 테스터 만들기
- -
🔔 유튜브 크리에이터 골든메탈님의 유니티강의 3D 쿼터뷰 액션게임 [BE5] 를 보고 공부하여 작성한 게시글입니다! 🔔
Enemy 스크립트 전체보기
더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour
{
public int maxHealth;
public int curHealth;
Rigidbody rigid;
BoxCollider boxCollider;
Material mat;
void Awake()
{
rigid = GetComponent<Rigidbody>();
boxCollider = GetComponent<BoxCollider>();
// Material은 Mesh Renderer 컴포넌트에서 접근가능합니다.
mat = GetComponent<MeshRenderer>().material;
}
void OnTriggerEnter(Collider other)
{
if(other.tag == "Melee"){
Weapon weapon = other.GetComponent<Weapon>();
curHealth -= weapon.damage;
Vector3 reactVec = transform.position - other.transform.position;
StartCoroutine(OnDamage(reactVec));
}
else if(other.tag == "Bullet"){
Bullet bullet = other.GetComponent<Bullet>();
curHealth -= bullet.damage;
Vector3 reactVec = transform.position - other.transform.position;
Destroy(other.gameObject);
StartCoroutine(OnDamage(reactVec));
}
}
IEnumerator OnDamage(Vector3 reactVec)
{
mat.color = Color.red;
yield return new WaitForSeconds(0.1f);
if(curHealth > 0) {
mat.color = Color.white;
}
else {
mat.color = Color.gray;
gameObject.layer = 12;
// 죽었을 시, 넉백
reactVec = reactVec.normalized;
reactVec += Vector3.up;
rigid.AddForce(reactVec * 5, ForceMode.Impulse);
Destroy(gameObject, 4);
}
}
}
🧷 1. 테스트 객체 만들기
- 테스트용 3D 박스 오브젝트를 넣습니다.
- 물리효과를 받기위한 Rigidbody를 추가 후, X축, Z축에 대한 회전을 동결해 주었습니다(Constraints- Freeze Rotation X, Z 체크)
🧷 2. Enemy 스크립트 피격 기능 구현
- 적 최대 체력, 현재 체력
/* Enemy script */
public class Enemy : MonoBehaviour
{
public int maxHealth;
public int curHealth;
Rigidbody rigid;
BoxCollider boxCollider;
void Awake()
{
rigid = GetComponent<Rigidbody>();
boxCollider = GetComponent<BoxCollider>();
}
void OnTriggerEnter(Collider other)
{
if(other.tag == "Melee"){
Weapon weapon = other.GetComponent<Weapon>();
curHealth -= weapon.damage;
}
else if(other.tag == "Bullet"){
Bullet bullet = other.GetComponent<Bullet>();
curHealth -= bullet.damage;
Destroy(other.gameObject);
}
}
}
- 최대 체력과, 현재 체력 변수를 넣었습니다.
- OnTriigerEnter 이벤트로 근접무기, 총알(총이 아닙니다!)에 닿을 경우, 데미지를 받게 끔 해줍니다.
- 만든 prefabs 의 총알과, 현재 들고있는 무기의 태그를 확인해 줍시다.
- 총알은 Bullet, 망치는 Melee 태그를 가지고 있습니다.
- 인스턴트 총알 사라지도록
- 총알은 Collider에 is Trigger이 켜있고, 중력을 안받기위해 Rigidbody의 Use Gravity 체크를 끄도록 합니다.
/* Bullet Script */
public class Bullet : MonoBehaviour
{
public int damage;
void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.tag == "Floor") {
Destroy(gameObject, 3);
}
}
void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Wall")
{
Destroy(gameObject);
}
}
}
- OnCollistionEnter에 있었떤 벽 피격시 오브젝트 사라지는 코드를 OnTriggerEnter로 바꿔줍시다.
Destroy(other.gameObject);
- Enemy script에서 총알이 적에 맞을 시, 관통 못하게 총알이 사라지는 코드도 꼭 적어줍시다.
🧷 3. Enemy 피격 후 이벤트
- 피격 시 색 변화
public class Enemy : MonoBehaviour
{
Material mat;
void Awake()
{
// Material은 Mesh Renderer 컴포넌트에서 접근가능합니다.
mat = GetComponent<MeshRenderer>().material;
}
void OnTriggerEnter(Collider other)
{
if(other.tag == "Melee"){
Weapon weapon = other.GetComponent<Weapon>();
curHealth -= weapon.damage;
StartCoroutine(OnDamage(reactVec));
}
else if(other.tag == "Bullet"){
Bullet bullet = other.GetComponent<Bullet>();
curHealth -= bullet.damage;
Destroy(other.gameObject);
StartCoroutine(OnDamage(reactVec));
}
}
IEnumerator OnDamage()
{
mat.color = Color.red;
yield return new WaitForSeconds(0.1f);
if(curHealth > 0) {
mat.color = Color.white;
}
else {
mat.color = Color.gray;
Destroy(gameObject, 4);
}
}
}
- 오브젝트의 Material을 통해 적 피격 시 빨간색으로 만들 것 입니다.
- 안죽으면 원래색으로 돌아오고, 죽으면 그레이 색이 됩니다.
- Material은 Mesh Renderer 컴포넌트를 통해 접근해야합니다.
- 색 변화는 코루틴을 통해 넣어줍니다.
- 적 죽은 상태
- 유니티를 통해 새로운 Layer을 만들어 둔 뒤, 적은 Enemy 레이어로, 죽은 상태는 번호를 잘 기억해 놓읍시다. (저는 12번이 죽은 상태 레이어입니다.)
IEnumerator OnDamage(Vector3 reactVec)
{
mat.color = Color.red;
yield return new WaitForSeconds(0.1f);
if(curHealth > 0) {
mat.color = Color.white;
}
else {
mat.color = Color.gray;
gameObject.layer = 12;
}
}
- 코루틴에서 죽을 시 gameObject.layer = 12; 즉 죽은 상태 레이어로 바꿔줍시다.
- 유니티의 Edit - Project Settings - Physics의 Layer Collision Martix를 들어갑니다
- EnemyDead에 관한 레이어가 Floor, Wall, EnemyDead 빼고 다 닿지 않게 만들어줍시다.
- 적 죽을 때, 살짝 밀려나는 이벤트
/* Enemy script, 추가되는 부분만 작성하였습니다. */
public class Enemy : MonoBehaviour
{
void OnTriggerEnter(Collider other)
{
if(other.tag == "Melee"){
Vector3 reactVec = transform.position - other.transform.position;
StartCoroutine(OnDamage(reactVec));
}
else if(other.tag == "Bullet"){
Vector3 reactVec = transform.position - other.transform.position;
StartCoroutine(OnDamage(reactVec));
}
}
IEnumerator OnDamage(Vector3 reactVec)
{
if(curHealth > 0) {
}
else {
// 죽었을 시, 넉백
reactVec = reactVec.normalized;
reactVec += Vector3.up;
rigid.AddForce(reactVec * 5, ForceMode.Impulse);
}
}
}
- 적이 데미지를 받는 코루틴 OnDamage() 함수를 실행할 때 Vector3값도 매개변수로 전달해줬습니다.
- 이 reactVec 값은 적과 무기의 사이의 거리벡터입니다.
- 적이 죽었을 시 Normalized된 reactVec 값에, 약간 UP값을 주며, AddForce 해 주었습니다. (normalized 함수는, 길이를 1로 변환해줍니다.)
이번 시간에는 적이 피격 될 시 Enemy 스크립트를 배웠는데,
trigger 이벤트함수 뿐만아니라, 태그나 레이어를 잘 활용 해야된다고 느꼈습니다.
이 강의에서 더 추가해보고 싶은 기능은, 무기 데미지에 따라서 적이 안죽더라도 넉백이 되는 기능을 추가할까 합니다.
출처: 골든메탈님 유튜브
https://www.youtube.com/watch?v=IoaPxcSHwEM&list=PLO-mt5Iu5TeYkrBzWKuTCl6IUm_bA6BKy&index=9
'🎮 Game Dev (게임개발) > PC (데스크탑, 노트북, 터치패널)' 카테고리의 다른 글
[3D 액션게임] 11. 목표를 추적하는 AI 만들기 (0) | 2022.04.07 |
---|---|
[3D 액션게임] 10. 수류탄 구현하기 (0) | 2022.04.06 |
[3D 액션게임] 08. 플레이어 물리엔진 고치기 (0) | 2022.04.04 |
[3D 액션게임] 07-1. 원거리 무기 재장전시 모션캔슬 (0) | 2022.04.04 |
[3D 액션게임] 07. 원거리무기 공격구현 (0) | 2022.04.02 |
Contents
소중한 공감 감사합니다