상세 컨텐츠

본문 제목

유니티 총 발사하기

유니티/기능

by MJ_119 2024. 8. 14. 15:57

본문

총알 발사 : 총알 프리팹에 아래 스크립트를 추가한다. 중력해제, 트리거 활성화 한다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BulletManager : MonoBehaviour
{
    Rigidbody bulletRigidbody;
    public float moveSpeed; // 총알 스피드

    // Start is called before the first frame update
    void Start()
    {
        bulletRigidbody = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
        BulletMove();
    }

    public void BulletMove()
    {
        bulletRigidbody.velocity = transform.forward * moveSpeed;
    }
}

 

 

 

 

 

@ 건 컨트롤러 스크립트 : 캐릭터에 스크립트를 넣는다

using System.Collections;
using System.Collections.Generic;
using Unity.Burst.CompilerServices;
using UnityEditor;
using UnityEngine;

public class GunController : MonoBehaviour
{
    // 현재 장착된 총
    [SerializeField]
    private Gun currentGun;

    // 연사 속도 계산
    private float currentFireRate;

    // 효과음 재생
    private AudioSource audioSource;

    // 상태 변수
    bool isReload = false;

    CharacterControllerMove characterControllerMove;

    // 조준점 위치
    Vector3 targetPoint;

    // Start is called before the first frame update
    void Start()
    {
        audioSource = GetComponent<AudioSource>();
        characterControllerMove = GetComponent<CharacterControllerMove>();
    }

    // Update is called once per frame
    void Update()
    {
        GunFireRateCalc();
        TryFire();
        TryReload();
    }

    // 재장전 시도
    private void TryReload()
    {
        if(Input.GetKeyDown(KeyCode.R) && !isReload && currentGun.currentBulletCount < currentGun.reloadBulletCount)
        {
            StartCoroutine(ReloadCoroutine());
        }
    }

    // 연사속도 재계산
    private void GunFireRateCalc()
    {
        if(currentFireRate > 0)
            currentFireRate -= Time.deltaTime;
    }

    // 발사 시도
    private void TryFire()
    {
        if(Input.GetMouseButton(0) && currentFireRate <= 0 && !isReload)
        {
            Fire();
        }
    }

    // 발사 전
    private void Fire()
    {
        if(!isReload)
        {
            // 탄창에 총알이 1개라도 있으면
            if (currentGun.currentBulletCount > 0)
            {
                // 총알 발사
                Shoot();
            }
            // 탄창에 총알이 없으면
            else
            {
                // 재장전
                StartCoroutine(ReloadCoroutine());
            }
        }

    }

    // 재장전
    IEnumerator ReloadCoroutine()
    {
        if ( currentGun.carryBulletCount > 0 )
        {
            isReload = true;

            characterControllerMove.animator.SetTrigger("Reload");

            // 현재 가지고있는 총알을 버리지 않고 합쳐서 재장전하기
            currentGun.carryBulletCount += currentGun.currentBulletCount;
            currentGun.currentBulletCount = 0;

            yield return new WaitForSeconds(currentGun.reloadTime);

            if ( currentGun.reloadBulletCount <= currentGun.carryBulletCount )
            {
                currentGun.currentBulletCount = currentGun.reloadBulletCount;
                currentGun.carryBulletCount -= currentGun.reloadBulletCount;
            }
            else
            {
                currentGun.currentBulletCount = currentGun.carryBulletCount;
                currentGun.carryBulletCount = 0;
            }

            isReload = false;

        }
        else
        {
            print("총알이 없음");
        }
    }

    // 발사 후
    private void Shoot()
    {
        currentGun.currentBulletCount--; // 탄창 총알 -1
        currentFireRate = currentGun.fireRate; // 연사 속도 제한
        PlaySE(currentGun.fire_Sound); // 총에 등록된 총 발사 사운드 재생
        currentGun.muzzleFlash.Play(); // 총구 반짝임 재생

        // 총알 생성 및 발사
        Ray ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2, 0));
        RaycastHit hit;

        
        if (Physics.Raycast(ray, out hit))
        {
            // 레이가 무언가에 충돌한 경우 hit.point를 사용할 수 있습니다.
            targetPoint = hit.point;
        }
        // 총구에서 목표 지점을 향한 방향 벡터 계산
        Vector3 direction = (targetPoint - currentGun.bulletPoint.position).normalized;

        Instantiate(currentGun.bulletObj, currentGun.bulletPoint.position, Quaternion.LookRotation(direction));
        Hit();
        print("총알 발사함");
    }


    private void Hit()
    {

    }
    private void PlaySE(AudioClip clip)
    {
        audioSource.clip = clip;
        audioSource.Play();
    }
}

 

 

 

 

 

 

 

Gun 스크립트 : 원하는 총에 넣는다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Gun : MonoBehaviour
{
    public string gunName; // 총의 이름
    public float range; // 사정 거리
    public float accuracy; // 정확도
    public float fireRate; // 연사속도
    public float reloadTime; // 재장전 속도

    public int damage; // 총의 데미지

    public int reloadBulletCount; // 총알 재장전 개수
    public int currentBulletCount; // 현재 탄창에 남아있는 총알 개수
    public int maxBulletCount; // 최대 총알 개수
    public int carryBulletCount; // 캐릭터가 가지고 있는 모든 총알 개수

    public float retroActionForce; // 반동 세기
    public float retroActionFineSightForce; // 정조준시의 반동 세기

    public Vector3 fineSightOriginPos; // 정조준시 총의 위치
    public ParticleSystem muzzleFlash; // 총구 섬광

    public AudioClip fire_Sound; // 총 발사 사운드

    // 총알 프리팹
    public GameObject bulletObj;
    // 총알 생성 위치
    public Transform bulletPoint;

}

 

 

Bullet Point : 총 끝에 빈 오브젝트를 만들어서 총알이 생성 후 발사될 위치를 지정해준다.

Bullet Obj : 총알 프리팹을 넣는다.

Muzzle Flash : 총구 섬광 이펙트

 

 

 

--- 아직 미완성 ---

관련글 더보기