구현 완료
1. 이동구현
2. 이동 애니메이션
3. 카메라 무빙
4. 대각 이동시 원을 그리게 변경해야함
불안전 요소
1. 카메라 이동 속도가 빠를시 생기는 계단현상
2. 벽넘기가 불안정함
현재 완성까지 필요한 요소
1. 엄폐기능
2. 총기 조작 기능
3. 시네마씬을 이용한 게임 씬 제작
이전 글에서 대각 이동시 원을 그리도록 변경했다
이번에는 " 총기 조작 기능"을 만들어 보고자 한다
언제나 그렇듯, 개발에 들어가기 전 태블릿이든 타블렛이든 사용해서 설계를 하고 들어간다
원래는 갤탭 울트라를 사용해서 많이 설계를 했는데 이번에는 clip studio 영구제를 구매했기에, 이를 사용해 보려 한다
대충 생각나는데로 끄적인 그 무언가이다
현재 생각나는 설계 방향의 갈림길은
1. 총알의 구현
1.1 총알 오브젝트를 실제로 생성, 충돌철
1.2 ray의 충돌로 즉시 처리
2. 총알 괴도의 문제점
2.1 플레이어 - 타겟의 방향
2.2 카메라 - 타겟의 방향
총알의 구현은 ray로 구현하는 것이 맞는 것같은데, 괴도의 문제점은 전혀 감이 잡히지 않으니, AI에게 물어보자
추천
-
- 실제 발사 지점은 플레이어의 총구에서 시작하지만, 카메라와 조준점으로 보정.
- 방법: Raycast로 카메라의 중심에서 조준점을 찾은 후, 총구에서 해당 지점으로 레이를 발사.
- 장애물 충돌 판정을 자연스럽게 처리할 수 있음.혼합 방식:
Ray ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2));
if (Physics.Raycast(ray, out RaycastHit hitInfo, maxDistance))
{
Vector3 targetPoint = hitInfo.point;
// 총구에서 타겟 지점으로 레이 발사
Vector3 muzzlePosition = gunMuzzle.transform.position;
Vector3 direction = (targetPoint - muzzlePosition).normalized;
// 총알 발사
GameObject bullet = Instantiate(bulletPrefab, muzzlePosition, Quaternion.LookRotation(direction));
bullet.GetComponent<Rigidbody>().velocity = direction * bulletSpeed;
}
- 게임 스타일에 따라 선택:
- 현실적인 게임: 플레이어 → 조준점.
- 직관적인 플레이: 카메라 → 조준점.
이 방법으로 구현하면서 게임의 스타일에 맞는 조준 시스템을 설정하면 자연스럽고 직관적인 총기 조작이 가능합니다.
라는 대답이 나왔다
뭔가 잘 감이 오지 않아서 유튜브를 뒤지는중 정보를 찾았다
보는것과 같이, 플레이어에서 나오는 ray가 언제나 화면의 중앙을 향하고 있다
이를 구현하는 것을 목표점으로 삼아보려 한다
일단 대충 감을 잡고자 GPT에게 질문을 해보았다
void Shoot()
{
// 1. 카메라 중심에서 Ray 생성
Vector3 screenCenter = new Vector3(Screen.width / 2, Screen.height / 2, 0);
Ray cameraRay = Camera.main.ScreenPointToRay(screenCenter);
// 2. 조준점 계산
Vector3 targetPoint;
float maxDistance = 1000f;
if (Physics.Raycast(cameraRay, out RaycastHit cameraHitInfo, maxDistance))
{
targetPoint = cameraHitInfo.point;
}
else
{
targetPoint = cameraRay.GetPoint(maxDistance);
}
// 3. 총구에서 조준점으로 방향 계산
Vector3 muzzlePosition = gunMuzzle.transform.position;
Vector3 directionToTarget = (targetPoint - muzzlePosition).normalized;
// 4. 총구 근처 Ray 충돌 검사
if (Physics.Raycast(muzzlePosition, directionToTarget, out RaycastHit muzzleHitInfo, maxDistance))
{
targetPoint = muzzleHitInfo.point;
directionToTarget = (targetPoint - muzzlePosition).normalized;
}
// 5. 총알 발사
GameObject bullet = Instantiate(bulletPrefab, muzzlePosition, Quaternion.LookRotation(directionToTarget));
bullet.GetComponent<Rigidbody>().velocity = directionToTarget * bulletSpeed;
// 디버그용 Ray 시각화
Debug.DrawRay(muzzlePosition, directionToTarget * maxDistance, Color.red, 1.0f);
}
이런 참고용 코드를 만들어 주었다
이를 해석하면서 스크립트를 만들어 보려 한다
이 매커니즘을 해석하자면
1. 카메라에서 화면 중앙으로 ray를 발사
2. 1에서 만든 ray가 충돌한 위치를 point로 처리
3. 2에서 얻은 point를 Vector3값으로 얻음
4. 플레이어의 총에서 point를 향해서 ray를 발사
이제 이 설계에 따라서 코딩을 시작한다
2024 11 23 17 35
// 시험 코드
Vector3 screenCenter = new Vector3(Screen.width / 2, Screen.height / 2, 0);
Ray cameraRay = Camera.main.ScreenPointToRay(screenCenter);
Vector3 targetPoint;
float maxDistance = 100f;
if (Physics.Raycast(cameraRay, out RaycastHit cameraHitInfo, maxDistance))
{
targetPoint = cameraHitInfo.point;
}
else
{
targetPoint = cameraRay.GetPoint(maxDistance);
}
// 총구에서 조준점으로 방향 계산
Vector3 muzzlePosition = gunMuzzle.transform.position;
Vector3 directionToTarget = (targetPoint - muzzlePosition).normalized;
// 총구 근처 Ray 충돌 검사
if (Physics.Raycast(muzzlePosition, directionToTarget, out RaycastHit muzzleHitInfo, maxDistance))
{
targetPoint = muzzleHitInfo.point;
directionToTarget = (targetPoint - muzzlePosition).normalized;
}
Debug.DrawRay(muzzlePosition, directionToTarget * maxDistance, Color.red, 1.5f);
필요한 부분을 해석해서 사용했다
핵심은 카메라에서 나온 ray에서 충돌점과 플레이어의 총기 지점을 빼기 벡터로 방향을 구해서 그 방향으로 ray를 발사하는 매커니즘이다
일단 조준시에는 정상적으로 ray가 작동하기는 하는데....
조준을 하지 않고 있으면 왠지는 모르겠지만, ray가 위로 뜨는 현상이 있다
왜그런지는 진짜 모르겠다
일단은 조준시 작동은 의도한 형태가 맞기에 그대로 사용한다
2024 11 23 18 10
하나가 해결되고 하나가 박살나는 기적
문제를 해결했다
카메라에서 나온 Ray가 플레이어와 충돌해서 생긴 문제였다
이를 해결하기 위해서 layerMask를 사용한다
LayerMask layerMask = ~LayerMask.GetMask("Player");
if (Physics.Raycast(cameraRay, out RaycastHit cameraHitInfo, maxDistance, layerMask))
{
targetPoint = cameraHitInfo.point;
}
else
{
targetPoint = cameraRay.GetPoint(maxDistance);
}
이렇게 보정을 걸어주었다
이렇게 정상 작동하는 것을 알 수 있다
이제 여기에 우클릭시 사격모드로 전환하고, 이때 좌클릭시 히트 스캔방식으로 총기를 발사한다는 느낌으로 코딩을 해보려 한다
우선 기존 조준의 경우
isAiming = Input.GetMouseButton(1);
으로 구현되어 있었는데
이렇게 구현할 경우, 계속 마우스를 누르고 있어야 한다는 문제가 있다
이를 토글 형식으로 변화를 준다
if (Input.GetMouseButtonDown(1))
{
isAiming = !isAiming;
}
이렇게 해준다
이제 이때 우클릭시 히트스캔을 실행하고, 적일시 처리를 할 공간을 배정한다
if (Input.GetMouseButtonDown(0))
{
if (Physics.Raycast(muzzlePosition, directionToTarget, out RaycastHit enemy, maxDistance))
{
if (enemy.collider.CompareTag("Enemy"))
{
Debug.Log("적 맞춤");
// 이후 코딩 상황 맞춰서 처리
}
}
}
이렇게 처리한다
정상처리 된것을 확인할 수 있다
이후 if문 안쪽에 처리로 발사를 처리할 수 있다