즐거운 유니티 공부 시간이다
이번 글부터는 새로운 프로젝트로 시작한다
유니티짱은 어쨋든 사용되니 import하고 시작한다
이번에는 특이하게, light도 전용 프리팹을 사용한다
????????
뭔가 생각한것과 많이 다르지만, 일단 진행해 보자
책에서는 바탕을 sky가 아니라 다른세팅으로 해서 차이가 날 수 있다
책에서는 game창에 설정이 있다고 하는데, 최신 버전에서는
window - rendering - lighting으로 가야한다
skybox의 메테리얼을 none로 만들어준다
그후 카메라를 세팅해주면 이러한 형태가 나온다
Light는 유니티짱의 것을 사용하면 너무 밝아져서 포기하기로 했다, 결국 중요한것은 코드이니...
이제 여기에 카메라를 회전시킬 수 있는 기능을 넣어볼 것이다.
구현 기능은 "왼클릭 유지상태에서는 상하좌우, 오른클릭 유지시에는 카메라가 회전" 기능을 만든다
public class CameraMove : MonoBehaviour
{
void Update()
{
if (Input.GetMouseButton(0))
{
Camera.main.transform.Translate(Input.GetAxisRaw("Mouse X") / 10, Input.GetAxisRaw("Mouse Y") / 10, 0);
}
else if (Input.GetMouseButton(1))
{
Camera.main.transform.Rotate(Input.GetAxisRaw("Mouse Y") * 10, Input.GetAxisRaw("Mouse X") * 10, 0);
}
}
}
코드를 해석하자면
if 왼클릭중
카메라를 이동시킨다 - 마우스 이동으로 => 좌우 = x좌표값, 상하 = y좌표값
else if 오른클릭중
카메라를 회전시킨다 - 마우스 이동으로 => 상하좌우 마우스와 동일
이다
이때 생각해본 영역은, 카메라에 .main이라는 코드가 붙어 있는데, 씬에서 메인 카메라를 찾아서 조작하는 것 이다.
즉, 메인 카메라를 다룰때는 굳이 카메라를 public나 컴포넌트를 가져올 필요가 없다는 것이다.
새로운 것 또 배워간다
이렇게 만든 스크립트를 카메라에 담고 테스트 해본다
마우스로 카메라의 position과 rotate를 조작할 수 있는 것을 확인할 수 있다
다만, 현재 상태로는 유니티짱을 중심으로 도는것이 아닌, 자유시점에 가깝다
그렇기에, 유니티짱을 중심으로 회전하도록 만들어 보자
카메라의 중심축이 되어줄 빈 오브젝트를 만들고, 좌표값을 유니티 짱에 맞추어 준다
그리고 카메라를 하위로 넣어준다
그리고 스크립트를 부모 오브젝트를 움직이도록 수정한다
public class CameraMove : MonoBehaviour
{
GameObject CameraParent;
void Start()
{
CameraParent = GameObject.Find("CameraParent");
}
void Update()
{
if (Input.GetMouseButton(0))
{
Camera.main.transform.Translate(Input.GetAxisRaw("Mouse X") / 10, Input.GetAxisRaw("Mouse Y") / 10, 0);
}
else if (Input.GetMouseButton(1))
{
CameraParent.transform.Rotate(Input.GetAxisRaw("Mouse Y") * 10, Input.GetAxisRaw("Mouse X") * 10, 0);
}
}
}
회전의 Camera.main을 CameraParent로 수정해 주었다
이렇게 할 시, 회전을 부모의 오브젝트를 기준으로 회전하게 된다
이제 유니티짱을 기준으로 회전하는 것을 볼 수있다
이제 여기에 줌 인, 아웃을 넣어보자
조작에는 스크롤을 사용한다
스크롤은 Mouse ScrollWheel이라는 키워드를 사용한다
public class CameraMove : MonoBehaviour
{
GameObject CameraParent;
void Start()
{
CameraParent = GameObject.Find("CameraParent");
}
void Update()
{
if (Input.GetMouseButton(0))
{
Camera.main.transform.Translate(Input.GetAxisRaw("Mouse X") / 10, Input.GetAxisRaw("Mouse Y") / 10, 0);
}
else if (Input.GetMouseButton(1))
{
CameraParent.transform.Rotate(Input.GetAxisRaw("Mouse Y") * 10, Input.GetAxisRaw("Mouse X") * 10, 0);
}
Camera.main.fieldOfView += 20 * Input.GetAxis("Mouse ScrollWheel");
if (Camera.main.fieldOfView < 10) Camera.main.fieldOfView = 10;
}
}
이렇게 2줄이 추가되었다
if문이 들어가는 이유는 거리값이 너무 극단적일 경우 카메라가 뒤집히는 현상이 있기 때문이다
추가적으로 카메라 위치를 초기화 하는 기능도 넣어보자
매커니즘은 정해진 transform값을 기억 해주었다가, 특정 키가 입력될시 그 위치로 다시 돌아가는 것이다
public class CameraMove : MonoBehaviour
{
GameObject CameraParent;
Vector3 defaultPosition;
Quaternion defaultRotation;
float defaultZoom;
void Start()
{
CameraParent = GameObject.Find("CameraParent");
defaultPosition = Camera.main.transform.position;
defaultRotation = CameraParent.transform.rotation;
defaultZoom = Camera.main.fieldOfView;
}
void Update()
{
if (Input.GetMouseButton(0))
{
Camera.main.transform.Translate(Input.GetAxisRaw("Mouse X") / 10, Input.GetAxisRaw("Mouse Y") / 10, 0);
}
else if (Input.GetMouseButton(1))
{
CameraParent.transform.Rotate(Input.GetAxisRaw("Mouse Y") * 10, Input.GetAxisRaw("Mouse X") * 10, 0);
}
Camera.main.fieldOfView += 20 * Input.GetAxis("Mouse ScrollWheel");
if (Camera.main.fieldOfView < 10) Camera.main.fieldOfView = 10;
if (Input.GetMouseButton(2))
{
Camera.main.transform.position = defaultPosition;
CameraParent.transform.rotation = defaultRotation;
Camera.main.fieldOfView = defaultZoom;
}
}
}
추가된 코드는
각 값을 저장하는 변수들과
초기화하는 부분,
마우스 휠 버튼시 초기화하는 기능이다
모든 기능이 정상적으로 작동하는 것을 볼 수 있다
이제 코드를 리펙토링 해보자
이 부분은 함수로 따로 처리하는 것이 좀 더 나을 것 같다
함수를 작성해서
시작할때 실행하게 하여 가독성을 높인다
이런 방식으로 모든 update의 코드들도 함수화를 진행한다
public class CameraMove : MonoBehaviour
{
GameObject CameraParent;
Vector3 defaultPosition;
Quaternion defaultRotation;
float defaultZoom;
void Start()
{
init();
}
void Update()
{
cameraMove();
cameraRotate();
cameraZoomInOut();
cameraInit();
}
private void init()
{
CameraParent = GameObject.Find("CameraParent");
defaultPosition = Camera.main.transform.position;
defaultRotation = CameraParent.transform.rotation;
defaultZoom = Camera.main.fieldOfView;
}
private void cameraMove()
{
if (Input.GetMouseButton(0))
{
Camera.main.transform.Translate(Input.GetAxisRaw("Mouse X") / 10, Input.GetAxisRaw("Mouse Y") / 10, 0);
}
}
private void cameraRotate()
{
if (Input.GetMouseButton(1))
{
CameraParent.transform.Rotate(Input.GetAxisRaw("Mouse Y") * 10, Input.GetAxisRaw("Mouse X") * 10, 0);
}
}
private void cameraZoomInOut()
{
Camera.main.fieldOfView += 20 * Input.GetAxis("Mouse ScrollWheel");
if (Camera.main.fieldOfView < 10) Camera.main.fieldOfView = 10;
}
private void cameraInit()
{
if (Input.GetMouseButton(2))
{
Camera.main.transform.position = defaultPosition;
CameraParent.transform.rotation = defaultRotation;
Camera.main.fieldOfView = defaultZoom;
}
}
}
코드의 절대적인 길이는 길어지지만, Update의 내용이 간소화 되는것을 확인할 수 있다
본 글의 파일은 깃에 업로드 됩니다.
'공부 > 유니티' 카테고리의 다른 글
유니티3D 공부(Part4) 유니티짱 터치하기, 레이(Raycast)와 충돌처리 (0) | 2024.10.01 |
---|---|
유니티3D 공부(Part3) 말하는 유니티짱 만들기(효과음 넣기), 세이브, 로드기능 (1) | 2024.10.01 |
유니티 문제들(움직임, 카메라, 맵핑) - 캐릭터 움직임, 카메라 무빙, 대각선 이동 보정 (1) | 2024.09.27 |
유니티3D 공부(Part 1 - 5, Part 1 END) 씬 전환하기, 타이틀 화면, 승리, 패배 씬 추가 (0) | 2024.09.26 |
유니티3D 공부(Part 1-4) 적 만들기, 네이게이션 메쉬(NavMesh), 플레이어 추적 (1) | 2024.09.25 |