1. 적 봇 생성
오버워치 훈련장처럼 적 봇 유닛을 생성해주었습니다.
일정 Hp를 가지고 있고, Hp가 0이 되면 사라지는 기능을 구현했습니다.
그리고 일정시간 뒤에 해당 리스폰 포지션에서 다시 살아나는 기능도 구현했습니다.
일단, 적 봇 유닛을 만들어줍니다.
[Enemy.cs]
public class Enemy : MonoBehaviour
{
Rigidbody rigidEnemy;
[SerializeField]
// 해당 적 봇의 원래 포지션.
public Vector3 originPos;
// 체력.
public float maxHp;
public float currHp;
public float moveSpeed;
public bool isMoveRight;
void Start()
{
rigidEnemy = GetComponent<Rigidbody>();
currHp = maxHp;
isMoveRight = true;
}
void Update()
{
// 필드에 존재하면 움직이라는 함수.
if(gameObject.activeSelf == true)
{
Move();
}
}
void Move()
{
// 필드에서 임의로 설정한 이동구간.
if (transform.position.x > 8)
isMoveRight = false;
else if (transform.position.x < -15)
isMoveRight = true;
if (isMoveRight == true)
transform.Translate(moveSpeed * Vector3.right * Time.deltaTime, Space.World);
else
transform.Translate(-moveSpeed * Vector3.right * Time.deltaTime, Space.World);
}
// 데미지를 입었을 때 호출되는 함수.
public void Damaged(float _damage)
{
currHp -= _damage;
if(currHp <= 0)
{
gameObject.SetActive(false);
// 킬로그 표시.
UIManager.m.ActiveEvent_ImgHitEnemy("Kill");
}
}
// 다시 생성될 때 호출되는 초기화 함수.
public void Init()
{
currHp = maxHp;
isMoveRight = true;
}
}
[EnemySpawner.cs]
public class EnemySpawner : MonoBehaviour
{
[SerializeField]
Enemy enemy;
public float coolTime = 2f;
void Update()
{
// 적 봇 유닛이 디액티브되면 사망으로 판정.
if(enemy.gameObject.activeSelf == false)
{
ReCreateEnemy();
}
}
// 적 봇 사망 후 일정 시간 후 재생성되는 함수.
void ReCreateEnemy()
{
coolTime -= Time.deltaTime;
// 쿨타임 후 포지션, 체력, 쿨타임 초기화한 다음 재생성.
if(coolTime <= 0)
{
enemy.gameObject.transform.position = enemy.originPos;
enemy.Init();
coolTime = 2f;
enemy.gameObject.SetActive(true);
}
}
}
2. 총 슈팅
솔져는 히트스캔이기 때문에 총을 쏘면 바로 적이 피격되는 기능을 구현했습니다.
(Raycast 활용)
[AimController.cs]
public class AimController : MonoBehaviour
{
// 총알 피격 이펙트.
public GameObject bulletEffect;
// 유닛카메라.
[Header("Camera")]
public Camera theCamera;
[Header("Fire Stat")]
public float weaponRange = 100f;
public float damage = 20f;
[Header("Ray")]
// 레이저를 쐈을 때 맞은 대상.
RaycastHit hit;
public void SetAim()
{
// Physics,Raycast매서드 사용.
// (현재 카메라의 포지션에서, 카메라 앞방향(z값)으로 발사, 대상, 레이저 길이)
if(Physics.Raycast(theCamera.transform.position, theCamera.transform.forward, out hit, weaponRange))
{
// 헤드 판정.
if (hit.collider.tag == "Head")
{
Enemy enemy = hit.transform.GetComponent<Enemy>();
if (enemy != null)
{
// 조준선에 헤드를 맞췄다는 이미지 생성.
UIManager.m.ActiveEvent_ImgHitEnemy("Head");
// 적에게 데미지를 주는 함수.
enemy.Damaged(damage*2);
}
}
// 몸샷 판정.
else if(hit.collider.tag == "Body")
{
Enemy enemy = hit.transform.GetComponent<Enemy>();
if (enemy != null)
{
// 조준선에 몸샷을 했다는 이미지 생성.
UIManager.m.ActiveEvent_ImgHitEnemy("Body");
enemy.Damaged(damage);
}
}
// 적이 아닌 벽 등 다른 오브젝트일 때는 해당 지점에 총알이 박힌 듯한 bulletEffect생성.
else
{
GameObject effect = Instantiate(bulletEffect, hit.point, Quaternion.LookRotation(hit.normal));
Destroy(effect, 0.2f);
}
}
}
}
[UnitController.cs]
public class UnitController : MonoBehaviour
{
AimController aimController;
public ParticleSystem muzzleFlash;
[Header("Shoot")]
// 슈팅 딜레이 속도.
public float shootRate;
public float shootDelayTime;
private float maxBullet = 30;
public float currBullet;
void Start()
{
rigidUnit = GetComponent<Rigidbody>();
unitAnimController = GetComponent<UnitAnimationController>();
capsuleCollider = GetComponent<CapsuleCollider>();
aimController = GetComponent<AimController>();
}
void Update()
{
Crouch(); // 앉기.
IsGround(); // 땅에 닿았는지 판별.
Jump(); // 점프.
Move(); // 기본 이동.
UnitRotation(); // 유닛 좌우 회전.
CameraRotation(); // 카메라 회전
Shoot(); // 좌클릭 - 기본공격
}
void Shoot()
{
shootDelayTime += Time.deltaTime;
// 마우스 좌클릭을 눌렀을 때 슈팅 딜레이 타임이 슈팅속도보다 크고 총알이 있다면,
// 레이저 발사. 총구 화염 이펙트 플레이. 슈팅사운드 플레이.
// 슈팅할 때마다 딜레이타임 초기화. 총알 감소. 총알 텍스트 변경.
if (Input.GetMouseButton(0) && shootDelayTime > shootRate && currBullet > 0)
{
aimController.SetAim();
muzzleFlash.Play();
AudioManager.m.audioSoldierFire.Play();
shootDelayTime = 0;
currBullet--;
UIManager.m.CountBullet(currBullet, maxBullet);
}
}
}
3. 재장전
키보드 R버튼을 누르거나 현재 총알이 0이면 자동으로 장전하는 기능을 구현했습니다.
[UnitController.cs]
public class UnitController : MonoBehaviour
{
AimController aimController;
[Header("Effect")]
public ParticleSystem muzzleFlash;
[Header("Shoot")]
public float shootRate;
public float shootDelayTime;
// 최대, 현재 총알개수.
private float maxBullet = 30;
public float currBullet;
void Start()
{
rigidUnit = GetComponent<Rigidbody>();
unitAnimController = GetComponent<UnitAnimationController>();
capsuleCollider = GetComponent<CapsuleCollider>();
aimController = GetComponent<AimController>();
currSpeed = walkSpeed;
originPosY = myCamera.transform.localPosition.y;
currCrouchPosY = originPosY;
// 현재 총알 = 최대 총알로 시작.
currBullet = maxBullet;
// UI 총알 텍스트 변경.
UIManager.m.CountBullet(currBullet, maxBullet);
}
void Update()
{
Crouch(); // 앉기.
IsGround(); // 땅에 닿았는지 판별.
Jump(); // 점프.
Move(); // 기본 이동.
UnitRotation(); // 유닛 좌우 회전.
CameraRotation(); // 카메라 회전
Shoot(); // 좌클릭 - 기본공격
Reload(); // 장전.
}
void Shoot()
{
// 장전 중일 땐 슈팅 불가.
if (isReloading == true)
return;
shootDelayTime += Time.deltaTime;
if (Input.GetMouseButton(0) && shootDelayTime > shootRate && currBullet > 0)
{
aimController.SetAim();
muzzleFlash.Play();
AudioManager.m.audioSoldierFire.Play();
shootDelayTime = 0;
currBullet--;
UIManager.m.CountBullet(currBullet, maxBullet);
}
}
// 재장전 함수.
void Reload()
{
// 키보드 R키를 누르고 현재 총알이 최대 총알과 다르다면 또는 현재총알이 없다면
// 장전 중 모드로 변경, 장전 애니메이션 트루.
if ((Input.GetKeyDown(KeyCode.R) && currBullet != maxBullet) || currBullet <= 0)
{
isReloading = true;
unitAnimController.isReload(true);
StartCoroutine("ReloadRoutine");
}
}
// 1.5초 뒤에 현재 총알 최대로 만들고, 총알 텍스트 변경, 장전 중 모드 해제.
IEnumerator ReloadRoutine()
{
yield return new WaitForSeconds(1.5f);
currBullet = maxBullet;
UIManager.m.CountBullet(currBullet, maxBullet);
unitAnimController.isReload(false);
isReloading = false;
}
}
[Result]
지금 아바타 애니메이션 조정을 못해서 총구의 위치가 이상합니다.
그래도 게임시작하면 적 봇 유닛이 움직이고, 마우스 좌클릭을 누르면 슈팅이 되고, R키를 누르면 장전이 됩니다.
https://www.youtube.com/watch?v=mHV31Uj_PsM
'Unity > Unity FPS게임 프로젝트(오버워치라이크)' 카테고리의 다른 글
[Unity 게임프로젝트] FPS게임<오버워치>(5-2) - 캐릭터 스킬 기능 활성화(미완성) (0) | 2024.05.27 |
---|---|
[Untiy 게임프로젝트] FPS 게임<오버워치>(5) - 캐릭터 스킬 기능 (0) | 2024.05.23 |
[Unity 게임프로젝트] FPS 게임<오버워치>(3) - 캐릭터 점프, 앉기 기능 구현 (0) | 2024.05.15 |
[Unity 게임프로젝트] FPS 게임<오버워치>(2) - 캐릭터 이동 및 카메라 회전, 마우스 커서 고정 기능 구현 (0) | 2024.05.15 |
[Unity 게임프로젝트] FPS 게임<오버워치>(1) - 프로젝트 세팅, 캐릭터 세팅 (0) | 2024.05.14 |