오늘 학습 키워드
마우스 따라다니기, 점프 스케어 만들기
오늘 학습 한 내용을 나만의 언어로 정리하기
마우스 따라다니기
void Update()
{
Vector3 mousePosition = Input.mousePosition; // 마우스 포지션 가져오기
mousePosition.z = Mathf.Abs(Camera.main.transform.position.z); // 카메라와의 거리만큼 Z축 위치 설정
Vector3 targetPosition = Camera.main.ScreenToWorldPoint(mousePosition);
targetPosition.z = 0; // Z축 위치를 0으로 설정하여 2D 평면에서 움직이도록 함
transform.position = Vector3.MoveTowards(transform.position, targetPosition, speed * Time.deltaTime);
}
마우스 포지션 가져와서 그걸 월드 포인트로 바꿈
갑툭튀 애니메이션 만들기
초 간격 0.01초로 해서 진짜 갑툭튀처럼 보이게 함
그리고 마지막에 마우스 오브젝트 삭제해서 계속 나오지 않게 함
화면이 흔들리는 연출 만들기 (Using DoTween)
DoTween 에셋을 사용해서, 마우스를 쫓아오는 객체가 일정 거리 이내로 다가오면 화면이 흔들리게 만들 것.
참고 자료 : 팀원분의 설명 + 벨로그 글
DOTween에는 DOShakePosition 이라는 함수가 있음. 이걸 사용해서 만들 것.
public class FollowCursor : MonoBehaviour
{
public float speed = 5f;
public float gameOverDistance; // 게임 오브젝트와 마우스 포인터 사이 게임오버 기준 거리
public float shakeDistance; // 카메라가 흔들리기 시작 할 거리
public Vector3 originalCameraPosition; // 카메라 원래 위치 저장용
public GameObject jumpScareImage; // 점프스케어 이미지 오브젝트
private Tween shaking; // 카메라 흔드는거 저장해놓고 중단할 때 사용
// Start is called before the first frame update
void Start()
{
originalCameraPosition = Camera.main.transform.position;
Vector2 size = GetComponent<SpriteRenderer>().bounds.size; // 스프라이트의 크기
gameOverDistance = size.x / 2; // 게임 오브젝트의 크기 반으로 설정
shakeDistance = size.x * 2f;
}
// Update is called once per frame
void Update()
{
Vector3 mousePosition = Input.mousePosition; // 마우스 포지션 가져오기
mousePosition.z = Mathf.Abs(Camera.main.transform.position.z); // 카메라와의 거리만큼 Z축 위치 설정
Vector3 targetPosition = Camera.main.ScreenToWorldPoint(mousePosition);
targetPosition.z = 0; // Z축 위치를 0으로 설정하여 2D 평면에서 움직이도록 함
transform.position = Vector3.MoveTowards(transform.position, targetPosition, speed * Time.deltaTime);
float distance = Vector3.Distance(transform.position, targetPosition);
if (distance < gameOverDistance)
{
// 놀래키기
jumpScareImage.SetActive(true);
Destroy(this.gameObject); // FollowCursor 스크립트 제거
Invoke("OnExitButton", 0.5f);
}
UpdateShaking(distance);
}
public void UpdateShaking(float distance)
{
// 가까워질수록 카메라가 흔들리도록 함
float intensity = Mathf.Clamp01(1f - (distance / shakeDistance));
float strength = intensity * 2.0f;
if(intensity <= 0) // intensity가 0보다 작다 = 거리가 멀다
{
if (shaking != null)
{
shaking.Kill();
Camera.main.transform.position = originalCameraPosition; // 카메라 원래 위치로 되돌리기
shaking = null;
}
return;
}
if (shaking != null) shaking.Kill();
shaking = Camera.main.transform.DOShakePosition(
duration: 0.5f,
strength: strength,
vibrato: 30,
randomness: 90f,
snapping: false,
fadeOut: false
);
}
public void OnExitButton()
{
Application.Quit();
}
}
여기서 intensity에 대해 조금 더 정리하는 편이 좋을 듯 함
float intensity = Mathf.Clamp01(1f - (distance / shakeDistance));
여기서 원래 Clamp는 세 개의 값을 받음.
- Mathf.Clamp(값, 최소값, 최대값)
첫 번째 인수로 넣었던 값이 최소값보다 작지 않도록, 최대값보다 크지 않도록 일종의 경계를 지어두는 것.
그렇다면 Clamp01은 무엇인가?
최소값이 0이고 최대값이 1인 Clamp이다. 그래서 인수도 하나만 받음.
그러면 왜 값을 1f - (distance / shakeDistance) 로 넣었는가?
먼저 distance는 현재 마우스와 쫓아오는 오브젝트 간의 거리.
shakeDistance는 흔들리기 시작할 거리이다.
만약에 distance가 shakeDistance보다 크다면 = 거리가 멀다면
Mathf.Clamp01(1f - (최소 1 이상)) = 0 이 반환될 것.
반대로, distance가 shakeDistance보다 작다면 = 거리가 가깝다면
Mathf.Clamp01(1f - (아무리 커도 1이 안됨)) = 0 이상이 반환될 것.
그리고 distance가 작을수록, 즉 거리가 가까울 수록 1f에서 빼는 값이 작기때문에 1에 가까운 값이 반환될 것.
그러니 intensity는 얼마나 가까운지를 0에서 1사이로 가지고있는 척도라고 보면 될 것.
함수를 부른게 누구인가?
팀원분이 버튼이 눌려지면 실행될 OnClick 메소드를 만들려고 하셨는데,
어떻게 해야 이 함수를 부른 버튼을 찾을지 고민하셨음. 그래서 나도 한 번 찾아보았음.
public void OnClickHandler()
{
GameObject caller = UnityEngine.EventSystems.EventSystem.current.currentSelectedGameObject;
Debug.Log("클릭한 오브젝트: " + caller.name);
}
EventSystem.current.currentSelectedGameObject는 UI 상에서 현재 이벤트를 발생시킨 GameObject를 알려준다고 함.
학습하며 겪었던 문제점 & 에러
문제 1
- 문제&에러에 대한 정의
using UnityEngine;
public class FollowCursor : MonoBehaviour
{
public float followSpeed = 5f; // 따라가는 속도
void Update()
{
// 마우스 위치를 월드 좌표로 변환
Vector3 mousePosition = Input.mousePosition;
mousePosition.z = 10f; // 카메라에서의 거리 (조정 필요)
Vector3 targetPosition = Camera.main.ScreenToWorldPoint(mousePosition);
// 현재 위치에서 목표 위치로 부드럽게 이동
transform.position = Vector3.MoveTowards(transform.position, targetPosition, followSpeed * Time.deltaTime);
}
}
이렇게 했더니 마우스 커서를 따라다니는 이미지가 카메라 뒤로 넘어가버리는 현상이 발생함
- 해결 방법
위에 마우스 따라다니기에서 만든 것처럼 마우스 포지션의 Z를 카메라 위치로 하고, 그걸 월드포인트로 변환한 좌표의 z를 0으로 만들어서 평면에서 움직이게 함
- 새롭게 알게 된 점
Unity 2D로 작업해도 좌표계 자체는 3D를 계속 사용하고 있다.
- 이 문제&에러를 다시 만나게 되었다면?
사용하고있는 좌표계에 맞게 변환할 것
내일 학습 할 것은 무엇인지
내일 꼭 할거는 아니긴 한데, DOTween에 대해 좀 더 알아보고싶음.