Chapter 2-7. 무기 : 마우스 회전에 따른 무기 흔들림
카테고리: Unity Lesson 3
태그: Unity Game Engine
인프런에 있는 케이디님의 [유니티 3D] 실전! 생존게임 만들기 - Advanced 강의를 듣고 정리한 필기입니다. 😀
🌜 강의 들으러 가기 Click
Chapter 2. 무기
무기 흔들림 구현하기
📜WeaponSway.cs
Holder
에 붙여 준다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WeaponSway : MonoBehaviour
{
private Vector3 originPos; // 기존 위치. 원래 위치 값으로 돌아가기 위해 보존.
private Vector3 currentPos; // 현재 위치. 계속 계산해나가며 업데이트 할 것.
[SerializeField]
private Vector3 limitPos; // 정조준이 아닐 때 무기가 최대 얼만큼까지 흔들릴 수 있는지.
[SerializeField]
private Vector3 fineSightLimitPos; // 정조준 할 때 무기가 최대 얼만큼까지 흔들릴 수 있는지.
[SerializeField]
private Vector3 smoothSway; // 총이 흔들릴 때 부드럽게 흔들리는 정도.
[SerializeField]
private GunController theGunController; // 📜GunController.cs 의 isFineSightMode 를 받아 오기 위해. 정조준 상태 여부에 따라 흔들림 정도가 다르므로 알아야 함.
void Start()
{
originPos = this.transform.localPosition;
currentPos = originPos;
}
void Update()
{
TrySway();
}
private void TrySway()
{
if (Input.GetAxisRaw("Mouse X") != 0 || Input.GetAxisRaw("Mouse Y") != 0)
Swaying();
else
BackToOriginPos();
}
private void Swaying()
{
float _moveX = Input.GetAxisRaw("Mouse X"); // -1.0 혹은 0.0 혹은 1.0
float _moveY = Input.GetAxisRaw("Mouse Y"); // -1.0 혹은 0.0 혹은 1.0
if(!theGunController.isFineSightMode)
{
currentPos.Set(Mathf.Clamp(Mathf.Lerp(currentPos.x, -_moveX, smoothSway.x), -limitPos.x, limitPos.x),
Mathf.Clamp(Mathf.Lerp(currentPos.y, -_moveY, smoothSway.y), -limitPos.y, limitPos.y),
originPos.z);
}
else
{
currentPos.Set(Mathf.Clamp(Mathf.Lerp(currentPos.x, -_moveX, smoothSway.x), -fineSightLimitPos.x, fineSightLimitPos.x),
Mathf.Clamp(Mathf.Lerp(currentPos.y, -_moveY, smoothSway.y), -fineSightLimitPos.y, fineSightLimitPos.y),
originPos.z);
}
transform.localPosition = currentPos;
}
private void BackToOriginPos()
{
currentPos = Vector3.Lerp(currentPos, originPos, smoothSway.x);
transform.localPosition = currentPos;
}
}
- 무기를 들고 있을 때나 맨손일 때 마우스 회전에 따라 총과 손의 위치에 자연스러운 흔들림을 준다. !
- 마우스를 👈 방향으로 움직여 화면을 왼쪽으로 회전하면, 무기와 손은 원래 위치로부터 👉 오른쪽 방향으로 살짝 쏠리게 하고
- 마우스를 👉 방향으로 움직여 화면을 오른쪽으로 회전하면, 무기와 손은 원래 위치로부터 👈 왼쪽 방향으로 살짝 쏠리게 하고
- 마우스를 👆 방향으로 움직여 화면을 위로 회전하면, 무기와 손은 원래 위치로부터 👇 아래쪽 방향으로 살짝 쏠리게 하고
- 마우스를 👇 방향으로 움직여 화면을 아래로 회전하면, 무기와 손은 원래 위치로부터 👆 위쪽 방향으로 살짝 쏠리게 한다.
- 정조준일 땐 덜 쏠리게 하고, 정조준이 아닐 땐 더 쏠리게 한다.
- 정조준땐 움직임이 덜하고 정확해야 하니까.
- Start()
orginiPos
에 원래 위치 보존- 이 스크립트가 붙을
Holder
는Player
에 붙음으로서Player
기준으로 (0, 0, 0) 원점을 위치로 가진다. (LocalPosition) - 따라서
orginiPos
에 Vector3.zero 값이 저장될 것이다.
- 이 스크립트가 붙을
currentPos
는orginiPos
에서 시작
- Update()
- 매 프레임마다 마우스 회전에 따른 총, 무기에 흔들림을 주거나 마우스 움직임이 없다면 원상복귀 하는 일을 수행하는 TrySway() 함수 실행
- TrySway()
- 마우스 움직임에 변화가 있다면 총, 무기에 흔들림을 주는 Swaying() 함수 실행
if (Input.GetAxisRaw("Mouse X") != 0 || Input.GetAxisRaw("Mouse Y") != 0) Swaying();
- 마우스 움직임에 변화가 없다면 흔들림으로 인해 변화되었던 총, 무기의 위치를
originPos
로 원상 복귀하는 BackToOriginPos() 함수 실행else BackToOriginPos();
- 마우스 움직임에 변화가 있다면 총, 무기에 흔들림을 주는 Swaying() 함수 실행
- Swaying()
- 총이나 손이 너무 이동해서 화면 밖을 벗어나면 안되니까, 정조준이 아닌 상태일 땐
limitPos
만큼만(delta) 이동하게 하였다.currentPos
Vector3 업데이트- X 값
- Mathf.Lerp(currentPos.x, -_moveX, smoothSway.x) 값이되
currentPos.x
에서-_moveX
까지smoothSway.x
비율로 보간한 값-_moveX
이렇게 음수인 이유- 마우스를 왼쪽으로 움직이면 팔은 반대 방향인 오른쪽으로 쏠리게 하고, 마우스를 오른쪽으로 움직이면 팔은 반대 방향인 왼쪽으로 쏠리게 하는게 자연스러우니까.
-_moveX
는 어차피 -1, 1 둘 중 하나이므로currentPos.x
는 보간이 끝나면 -1, 1에 근접해진다.Holder
는 부모인 Player 기준으로 원점이 원래 위치니까 흔들려 봤자 원래 위치로부터 최대 거리 1 정도 만큼만 쏠리게 만들어준 것이다.
- 단, [-limitPos.x, limitPos.x] 범위를 넘지 않도록 막아 주었다.
- 너무 쏠려서 화면에서 사라지는 것을 방지하고자.
- 예를 들어
limitPos.x
가 0.2 값이라면currentPos.x
는 -1, 1 둘 중 하나인-_moveX
에 근접하는 것을 목표로 하되 0.2 를 넘지 않게 하므로Holder
는 부모인 Player 기준으로 원점이 원래 위치니까 흔들려 봤자 원래 위치로부터 최대 거리 0.2 정도 만큼만 쏠리게 하는 것과 같다.
- 예를 들어
- 너무 쏠려서 화면에서 사라지는 것을 방지하고자.
- Mathf.Lerp(currentPos.x, -_moveX, smoothSway.x) 값이되
- Y 값
- Mathf.Lerp(currentPos.y, -_moveY, smoothSway.y) 값이되
- 단, [-limitPos.y, limitPos.y] 범위를 넘지 않도록 막아 주었다.
- Z 값
- 마우스 회전으로 Z 값에 변화를 주는건 없으니 그대로 원래 위치 Z 값을 따름.
originPos.z
- 마우스 회전으로 Z 값에 변화를 주는건 없으니 그대로 원래 위치 Z 값을 따름.
- X 값
- 정조준 상태일 땐 범위를 [-fineSightLimitPos, fineSightLimitPos] 으로 해주면 되고 그 외는 동일
- 현재 위치를 위에서 설정한
currentPos
로 업데이트.Holder
오브젝트의 로컬 위치가(플레이어 기준에서의 위치가)currentPos
로 바뀐다.
- 총이나 손이 너무 이동해서 화면 밖을 벗어나면 안되니까, 정조준이 아닌 상태일 땐
- BackToOriginPos()
currentPos
을 원래 위치인originPos
로 계속해서smoothSway.x
만큼 보간해나간다.- 그냥 비율로는 아무거나
smoothSway.x
로 선택했다.
- 그냥 비율로는 아무거나
- 현재 위치를 위에서 설정한
currentPos
로 업데이트.
위 같은 설정대로라면 예를 들어 정조준이 아닐 때 마우스를 아래로 움직이게 되면 총은 0.05 비율로 보간되어가며 원래 위치로부터 위로 0.1 만큼 떨어진 위치로 무기(손 혹은 총)가 이동하게 된다.
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글 남기기