Unity_2기 내일배움캠프 TIL

Unity_2기 10주차 (230112)

잼잼재미 2024. 1. 12. 18:40

오늘 구현 내용


1. 총기 구현

  • 1번, 2번 키로 무기 교체 구현
  • 마우스 왼쪽 클릭으로 발사 구현
  • 마우스 오른쪽 클릭으로 정조준 구현
  • R 키로 재장전 구현
  • 총기 반동 구현

 

 

 

트러블 슈팅


1. Gun 발사

 

Sword에서 Gun으로 무기를 교체 후, 발사를 입력하면 다음과 같이 오류가 계속 나왔다.

 

 

private Sword _sword;
private GunController _gunController;

private void Awake()
{
    _rigidbody = GetComponent<Rigidbody>();
    _sword = GetComponentInChildren<Sword>();
    _gunController = GetComponentInChildren<GunController>();
}

 

위와 같이 GunController 스크립트를 가지고 있는 GunHolder가 게임 시작 시, 비활성화 되어있기 때문에 생기는 오류라고 생각했다.

 

private void Awake()
{
    _rigidbody = GetComponent<Rigidbody>();
    _sword = GetComponentInChildren<Sword>();
    _gunController = GetComponentInChildren<GunController>();
}

void Start()
{
    SwordHolderActive();
}

private void GunHolderActive()
{
    _isGun = true;
    foreach (GameObject holder in HolderList)
    {
        holder.gameObject.SetActive(false);
    }

    HolderList[1].SetActive(true);
}

 

게임 시작 전, 모든 Holder를 활성화 해놓고, 다음과 같이 Start문에서 비활성화를 했다.

 

 

 

해결 완료!

 

 

2. Gun 정조준 시, 카메라 확대

 

위와 같이 정조준 시, 카메라가 조금 확대되는 효과를 주기 위해 Camera의 Position.z 값을 0에서 1로 수정하는 코드를 작성했다. 

 

 

private Vector3 _originCameaPos;

IEnumerator COFineSightActivate()
{
    _originCameaPos = Camera.main.transform.position;

    while (CurrentGun.transform.localPosition != CurrentGun.FineSightOriginPos)
    {
        CurrentGun.transform.localPosition = Vector3.Lerp(CurrentGun.transform.localPosition, CurrentGun.FineSightOriginPos, 0.2f);
        Camera.main.transform.position = new Vector3(0, 0, 1f);

        yield return null;
    }
}

IEnumerator COFineSightDeActivate()
{
    while (CurrentGun.transform.localPosition != CurrentGun.OriginPos)
    {
        CurrentGun.transform.localPosition = Vector3.Lerp(CurrentGun.transform.localPosition, CurrentGun.OriginPos, 0.2f);
        Camera.main.transform.position = _originCameaPos;
        yield return null;
    }
}

 

정조준 시, 원래 main 카메라의 Position을 저장하고, Position을 변경한다. 그리고 정조준이 해제되면 저장했던 Position으로 돌아가도록 했다.

 

 

 

하지만 main 카메라의 Position이 (0, 0, 1)이 아니라 이상한 값으로 이동했다.

 

 

IEnumerator COFineSightActivate()
{
    _originCameaPos = Camera.main.transform.localPosition;

    while (CurrentGun.transform.localPosition != CurrentGun.FineSightOriginPos)
    {
        CurrentGun.transform.localPosition = Vector3.Lerp(CurrentGun.transform.localPosition, CurrentGun.FineSightOriginPos, 0.2f);
        Camera.main.transform.localPosition = new Vector3(0, 0, 1f);

        yield return null;
    }
}

IEnumerator COFineSightDeActivate()
{
    while (CurrentGun.transform.localPosition != CurrentGun.OriginPos)
    {
        CurrentGun.transform.localPosition = Vector3.Lerp(CurrentGun.transform.localPosition, CurrentGun.OriginPos, 0.2f);
        Camera.main.transform.localPosition = _originCameaPos;
        yield return null;
    }
}

 

해결 방법은 의외로 간단했다. main 카메라가 Player의 자식 오브젝트로 있기 때문에 localPosition을 사용해야 제대로 동작했다. 

 

 

해결 완료!

 

 

3. Physics.Raycast를 이용한 총기 구현 개선

총기 구현은 Bullet 프리팹을 실제로 생성하는 방법과 프리팹을 생성하지 않고 Physics.Raycast를 사용해서 대상을 인식하는 방법이 있다. 

 

 

Bullet 프리팹 구현
Physics.Raycast

 

실제로 초당 프레임을 비교해보니 63 FPS -> 73 FPS로 Physics.Raycast로 구현하는 방법이 많이 안정적이었다. 그리고 총알 프리팹으로 총기 구현을 하려면 총알에 실제와 같은 속도나 물리 엔진을 적용해야하는데, 적용하기가 어렵고 총알 자체가 오히려 보이지 않는 것이 더욱 사실적이기 때문에 Physics.Raycast로 구현하지 않을 이유가 없었다. 또한, 여러명의 적과 동료가 동시에 총을 사용하면 이러한 프레임 차이는 더욱 심할 것이라고 생각했다. 그래서 팀원들과 협의 끝에 Physics.Raycast로 총기 구현을 진행하도록 했다.

 

 

오늘의 회고


어제 구현했던 Player에 오늘은 총기 구현을 했다. 사실 지난 팀 프로젝트에서 내가 총기 구현을 맡았기 때문에 생각보다 어렵진 않았다. 하지만 역시나 오류는 생겼다. 코드가 조금만 수정되도 오류는 피할 수 없는 것 같다. 오늘 생겼던 오류들은 전부 코드 한 줄의 아주 간단한 실수였다. 항상 코드를 작성할 때 한줄 한줄 생각하면서 작성해야 하는 것 같다. Player 구현은 어느정도 완료 되어서 다음주 부터는 적을 구현할 예정이다.

'Unity_2기 내일배움캠프 TIL' 카테고리의 다른 글

Unity_2기 11주차 (230116)  (0) 2024.01.16
Unity_2기 11주차 (230115)  (0) 2024.01.15
Unity_2기 10주차 (230111)  (0) 2024.01.11
Unity_2기 10주차 (230110)  (0) 2024.01.10
Unity_2기 10주차 (230109)  (1) 2024.01.09