반응형
소닉이나 여타 많은 게임들은 Peeking 기능을 제공한다
특히 다양한 기믹과 숨겨진 장치들이 즐비한 매트로베니아 장르에도
이러한 기능은 잘 어울릴 것 같다
0. 준비
플레이어로 사용할 캡슐콜라이더를 만들고 타일맵을 대충 깔아보자
1. 지형 제작
이렇게 3가지 나누어 만들었다
타일맵 (바깥지형)
특징: 타일맵 콜라이더 컴포넌트가 붙어있다
거짓맵 ( 단순히 지형을 보여주기 위함 )
특징: 아무런 컴포넌트도 붙어있지 않음
플랫폼맵 ( 밟고 올라갈 수 있는 지형 )
특징: 아래에선 통과가 되지만 위에선 통과가 안됨
설정방법
1. 타일맵 콜라이더 Used By Effector 활성화
2. 리지드바디 2D 컴포넌트 부착 후 바디타입 Static으로 변경
3. Platform Effector 2D 컴포넌트 부착
※ 사다리가 붙을 지형 맨 위에 이러한 지형을 만들어 놓으면
같은 효과를 볼 수 있을 것이다.
2. 카메라
카메라의 이동, 제한범위, 피킹을 만든 스크립트이다
using UnityEngine;
namespace Peeking
{
public class CameraController : MonoBehaviour
{
// 플레이어
[SerializeField]
private GameObject player;
// 카메라가 움직이는 값
private float cameraX;
private float cameraY;
private float limitCameraX;
private float limitCameraY;
// 피킹 관련
private bool isPeeking;
private float peekingSpeed = 5f;
private float peekingDir = 0f;
private float maxPeekingOffset = 2f;
private float peeking = 0f;
// 카메라 범위 제한
[SerializeField] private float leftLimit;
[SerializeField] private float rightLimit;
[SerializeField] private float topLimit;
[SerializeField] private float bottomLimit;
private void LateUpdate()
{
// 카메라 이동
cameraX = player.transform.position.x;
cameraY = player.transform.position.y;
// 카메라 범위 제한
limitCameraX = Mathf.Clamp(cameraX, leftLimit, rightLimit);
limitCameraY = Mathf.Clamp(cameraY, bottomLimit, topLimit);
// 피킹
Peek();
}
// 피킹 함수
private void Peek()
{
if (isPeeking)
{
float targetPeekingOffset = peekingDir * maxPeekingOffset;
peeking = Mathf.MoveTowards(peeking, targetPeekingOffset, peekingSpeed * Time.deltaTime);
float movePeeking = limitCameraY + peeking;
if (movePeeking > topLimit)
{
movePeeking = topLimit;
}
else if (movePeeking < bottomLimit)
{
movePeeking = bottomLimit;
}
transform.position = new Vector3(limitCameraX, movePeeking, -10);
}
else
{
transform.position = new Vector3(limitCameraX, limitCameraY, -10);
peeking = 0;
}
}
// 외부에서 값을 변경해줄 수 있게 해주는 함수
public void SetPeeking(bool _isPeeking, float _peekingDir)
{
isPeeking = _isPeeking;
peekingDir = _peekingDir;
}
}
}
3. 플레이어
피킹은 플레이어가 움직이지 않을때만 가능하게 만들고 싶었다
그렇기 때문에 Enum을 사용하여 조금 더 명확하게 만들었다
using UnityEngine;
namespace Peeking
{
public enum PlayerState
{
None,
Idle,
Move,
}
public class PlayerController : MonoBehaviour
{
private PlayerState state;
// 카메라 피킹
float peekDir;
float peekingTime;
// 이동
float moveSpeed = 7f;
float moveDir = 0f;
Rigidbody2D rigid;
int jumpCount = 1;
void Start()
{
state = PlayerState.Idle;
rigid = GetComponent<Rigidbody2D>();
}
void Update()
{
OnKeyboard();
PlayerStateSwitch();
}
private void PlayerStateSwitch()
{
switch (state)
{
case PlayerState.Idle:
Peeking();
break;
case PlayerState.Move:
PlayerMove();
break;
default:
break;
}
}
// 키보드 입력
private void OnKeyboard()
{
// 이동
if(Input.GetKey(KeyCode.LeftArrow))
{
state = PlayerState.Move;
moveDir = -1f;
}
else if(Input.GetKey(KeyCode.RightArrow))
{
state = PlayerState.Move;
moveDir = 1f;
}
else
{
moveDir = 0f;
state = PlayerState.Idle;
}
// 점프
if (Input.GetKey(KeyCode.Space) && jumpCount < 1)
{
rigid.velocity = Vector2.up * 9;
jumpCount++;
}
if (rigid.velocity.y == 0f)
jumpCount = 0;
}
// 피킹
void Peeking()
{
float targetPeekDir = Input.GetKey(KeyCode.UpArrow) ? 1f : (Input.GetKey(KeyCode.DownArrow) ? -1f : 0f);
if (targetPeekDir != 0f)
{
peekingTime += Time.deltaTime;
if (peekingTime > 0.5f)
{
peekDir = targetPeekDir;
}
}
else
{
peekingTime = 0f;
peekDir = 0f;
}
Camera.main.GetComponent<CameraController>().SetPeeking(true,peekDir);
}
// 이동
void PlayerMove()
{
transform.position += Vector3.right * moveDir * moveSpeed * Time.deltaTime;
}
}
}
4. 완성
반응형
'유니티 > 기능구현' 카테고리의 다른 글
[Unity] 유니티 C#) 메트로배니아 미니맵과 전체맵 ( 심화편 ) (1) | 2024.12.23 |
---|---|
[Unity] 유니티 C#) 메트로배니아 미니맵과 전체맵 ( 기본기능편 ) (1) | 2024.12.20 |
[Unity] 유니티 C#) 2D 매트로베니아 미니맵과 전체맵 ( 유니티 설정편 ) (0) | 2024.12.19 |
[Unity] 유니티 C#) FPS 주무기를 어떻게 구현할까? ( 저격총 ) (4) | 2024.10.27 |
[Unity] 유니티 C#) FPS 주무기를 어떻게 구현할까? ( 샷건 ) (0) | 2024.10.23 |