// 총을 쏘는 실제 처리 함수 private void Shot() { // 레이캐스트 충돌 정보를 담는 컨테이너 RaycastHit hit; // hitPosition 총알궤적의 도착 지점 // 총알이 맞는 곳에 지정해야 하나, 일단은 총구 앞쪽으로 머나먼 곳으로 지정 // (총구 위치 + 총구 앞쪽x사정거리) Vector3 hitPosition = firePos.position + firePos.forward * fireDistance; // 만약-광선날리기(발사위치, 방향, 충돌 정보를 담아갈 그릇, 사정거리)-이 // 충돌을 검사한다면... if (Physics.Raycast(firePos.position, firePos.forward, out hit, fireDistance)) { // 총알궤적의 도착 지점 = 실제 광선의 충돌 지점 hitPosition = hit.point; // 피탄 효과 찍어내기 // 찍어내기(찍어낼 피탄효과 원본, 위치, 회전) // Quaternion.LookRotation(방향) => 해당 방향을 보는 쪽으로 회전을 만들어줌 // hit.normal = 충돌각 (정확하게는 충돌한 표면이 바라보는 방향) Instantiate(impactPrefab, hit.point, Quaternion.LookRotation(hit.normal)); // 만약 상대방이 IDamageable 로서 가져와진다면... // 상대방이 무조건 IDamageable 이 강제하는 // OnDamage 함수는 가지고 있다는 것을 확신가능 IDamageable target = hit.collider.GetComponent <IDamageable>(); if (target != null) { // 상대방이 진짜 무엇인지는 모르지만 상관없이 OnDamage 함수를 쓰면 된다 target.OnDamage(damage); } } // 이펙트 재생(광선 충돌위치) StartCoroutine(ShotEffect(hitPosition)); //탄약 1 소모 magAmmo--; // 탄약을 다 소모했다면 상태=탄창빔 if (magAmmo <= 0) { magAmmo = 0; state = GUN_STATE.EMPTY; } }
private void Start() { // 총의 상태를 준비로 state = GUN_STATE.READY; // 현재 탄창의 탄약을 최대로 magAmmo = magAmmoMax; // 마지막 발사 시간을 초기화 lastTimeFire = 0; // 총소리 재생용 오디오소스를 가져오기 fireAudio = GetComponent <AudioSource>(); // 총알 궤적의 꼭지점을 두개로 shotLineRenderer.positionCount = 2; // 총알 궤적 랜더러를 꺼놓기 shotLineRenderer.enabled = false; // 탄약 UI를 갱신 UpdateGunUI(); }
// 실제 재장전 처리 // 코루틴으로 쓴 이유는 탄약이 실제 들어가는데 지연시간을 주기 위해 private IEnumerator Reloading() { // 현재 상태를 재장전중으로 지정 // Update 함수에서 if문에 걸려 Shot 발사가 못되게 막음 // Reload 함수에서 if문에 걸려 Reload 함수가 중단되게 함 state = GUN_STATE.RELOADING; gunAnimator.SetTrigger("Reload"); // 잠시 장전소요 시간만큼 대기 yield return(new WaitForSeconds(reloadTime)); // 현재 탄창 총알 수를 최대 탄창 총알수로 magAmmo = magAmmoMax; // 이제 REALODING => READY로 바꾸어 총의 락을 풀어줌 state = GUN_STATE.READY; // UI 갱신 UpdateGunUI(); }