들어가며
거의 2주 만에 돌아오는 블로그입니다.. 분명히 적어도 3일에 한 번씩은 하려 했는데 말입니다...
퍼즐게임 메인시스템이라는 게 그렇게 순순히 만들어지지 않더라고요. 뭐 하나 만들고 버그 고치고,
이제 다 했나? 싶으니까 이거 막아야 되고, 이거 추가해야 되고, 이거 수정해야 되고..... ㅎ...ㅏ.....
이젠 "진짜 다 만들었다. 이 정도면 이제 블록들 추가 양산만 하면 되는 정도다."싶은 정도이고,
테스트를 하려면 아트가 필요한데 아직 아트가 나오지 않아 기다리며 적는 글입니다.
사실 스크립트 하나하나 까면서 보여주고 싶었습니다만....
너무 많습니다.
추가된 스크립트만 해도 10개 정도는 될 거 같고.. 특히 몇 가지는 200줄 정도 가량 되기 때문에...
불가능할 거라 생각합니다.
나중에 방학 때 기회가 된다면 공부하면서 코드 리팩터링 하고,
하나하나 세세하게 블로그에 올려보도록 하겠습니다. 못할 거 같긴 한데...
혹시라도 무엇을 만드는지 잘 모른다면 예전 글부터 순서대로 읽으시는 걸 추천드립니다.
2024.10.24 - [개발일기/VIY] - [개발일지] VIVI Is You 줄여서 VIU #00
팀프 제출이 벌써 2주일밖에 남지 않았습니다.. 내일 지스타도 갈 거 기 때문에 더 열심히 달려야 할 거 같아요
오늘 만들 것
제가 모작하고 있는 원작 게임 바바이스유를 안다면 다들 아실 겁니다만 모를 수 있기 때문에 설명하겠습니다.
전부터 계속 설명했지만 바바이스유는 퍼즐게임입니다. 맵에는 각기 다른 오브젝트 들이 배치되어 있습니다. 이 오브젝트들은 각자 이름을 가지고 있는데, 이 이름이 주어 역할로 맵에 블록들이 설치 돼있습니다.
ex) baba, wall, flag, box, water.... 등등
그다음 동사 역할하는 블록도 있습니다. 원작에서도 종류가 많진 않지만.. 솔직히 이걸 2주 안에 다 만들 수 있을지
모르겠습니다. 일단 가장 중요하고 많이 쓰이는 걸로 Is블록이 있습니다.
왼쪽 또는 위쪽에 앞서 설명한 주어블록이 들어갑니다. 이후 오른쪽 또는 아래쪽에 목적어? 블록들을 놓게 됩니다.
목적어 블록들은 많이 쓰이는 것들로는
win - 닿으면 게임 클리어
you - 플레이어
stop - 통과되지 않고, 움직이지 않음
push - 통과되지 않고, 밀리게 됨
defeat - 닿으면 플레이어 사망... 등등 여러 가지 있습니다 일단 defeat 빼고 전부 다 구현했습니다.
이렇게 여러 가지 역할을 하는 블록들을 직접 움직여서 조합하여 you로 지정된 오브젝트, 즉 플레이어가 win에 닿아서 맵을 클리어하는 시스템입니다.
결과적으로는 주어, 동사, 목적어 가 조합 된 거에 따라 적용되게 하는 시스템을 이번에 개발했습니다.
만들기 시작
IVerbable
우선 인터페이스 하나를 만들어줍니다. IVerbable.
동사에 적용될 수 있게 하는 인터페이스입니다.
public interface IVerbable
{
public void VerbApply(List<Agent> agents);
public void VerbCancel(List<Agent> agents);
}
agent 리스트를 받아와서 각자 맞는 효과를 적용하고, 적용한 걸 취소하는 메서드들입니다.
Verb
Verb. 동사입니다. 주어와 목적어 사이를 연결해 주는 역할입니다.
인풋을 받았을 때, DirectObj(이하생략) 메서드를 실행시켜서 양쪽, 위아래에
주어와 목적어가 같이 있는지를 감지해 줍니다.
private void DirectObject() //양쪽 감지하는 코드
{
ShootRayAndApply(-Vector2.right);
ShootRayAndApply(Vector2.up);
}
private void ShootRayAndApply(Vector2 dir)
{
Vector3 padding = new Vector3(dir.x * 0.5f, dir.y * 0.5f, 0);
RaycastHit2D ray = Physics2D.Raycast(transform.position+padding, dir, 1);
if (ray.collider != null&&ray.collider.TryGetComponent(out Subject subject))
{
RaycastHit2D otherRay = Physics2D.Raycast(transform.position+-padding, -dir, 1);
if (otherRay.collider != null&&otherRay.collider.TryGetComponent(out IVerbable verbable))
{
if(subject.IsApply(dir,verbable))
ApplyVerb(subject, verbable);
}
}
}
이런 식으로 우선 위쪽과 왼쪽에 레이를 쏴서 주어가 있는지를 체크 후, 반대쪽을 체크해
아까 만든 인터페이스를 감지해 주고, 조건에 해당하면 동사를 적용시켜 주는 코드입니다.
protected abstract void ApplyVerb(Subject subject, IVerbable verbable);
적용은 추상화했습니다.
이후 이 클래스를 상속받는 IsVerb를 만듭니다. Is는 그냥 적용만 해주면 되기 때문에 아까 만든 인터페이스
메서드를 실행시켜 주면 됩니다.
protected override void ApplyVerb(Subject subject, IVerbable verbable)
{
verbable.VerbApply(subject.GetAgents());
}
Subject
Subject. 주어입니다. 이 친구가 사실 시간을 제일 많이 잡아먹었습니다.
단순 동사 적용은 쉬웠는데. 사실 이 게임은 주어 is 주어가 가능합니다.
Wall is flag로 하면 Wall이 Flag로 바뀌게 되는 거죠. 이때 Flag에 적용되던 효과들도 당연히
적용됩니다. 사실 그래서 Subject는 주어로써도 할 일을 해줘야 하고,
Verbable로써도 할 일을 해줘야 하는데, 그중에서도 해야 할 일도 굉장히 많은 편이 돼버린 거죠..
코드가 200 몇 줄이 되어버렸고, 문제가 생겨도 무슨 문제인지 알아보기도 힘들고..
내 코드가 이해가 안 가는 상황이었습니다...ㅎㅎ
그래서 SOLID 원칙은 지켜야 한다는 것을 뼈저리게 느꼈습니다.
만든 게 너무 많은 관계로, 구조를 글로 설명하겠습니다.
사실 하나하나 하고 싶은데... 시간이 없네요
우선 주어에 오른쪽, 또는 아래 동사가 적용될 수 있었기 때문에
딕셔너리에 방향벡터를 키값으로 두 가지를 만들어서 값에 저장합니다.
들어가는 값은 클래스로 따로 선언했는데, 이 부분이 적용 됐는지를 확인할 불값과,
적용이 된 IVerbable이 들어가 있습니다.
이후 동사와 마찬가지로 인풋에 구독하여, 인풋마다 감지하여서 감지가 되지 않는다면
불값을 false로 바꿔주며, 적용되어 있던 IVerbable의 Cancel함수를 실행해 주면 됩니다.
이후 주어와 주어 쪽을 해줘야 하는데....
너무 많습니다... 방학 때 진짜 꼭 해볼게요....
여러 가지 Verbable
Stop - 이미 움직일 때 장애물 콜라이더를 감지하게 만들었기 때문에 Stop이 발현되면
Agent 위치에 콜라이더 타일을 설치했습니다
Win - 콜라이더를 켜주어서 닿으면 승리처리를 했습니다
You - You상태를 추가해 줬습니다
Push - IPushable에 IsPushable을 켜주었습니다.
완성본
아직 아트가 없는 관계로 gif는 없습니다! 다음에 gif만 글로 따로 올릴게요!
마치며
진짜 개발일지 꼭 다 쓰고 싶었는데.... 시스템 하나 만들고 나서 쓴다는 건 좀 잘못된 거였을까요?
쓰기가 막막하네요... 나머지라도 열심히 달리며 써보겠습니다.
'개발일기 > VIY' 카테고리의 다른 글
[개발일지]VIY Push 버그 수정 #05 (2) | 2024.10.30 |
---|---|
[개발일지] VIY Rollback시스템 완..? #04 (1) | 2024.10.30 |
[개발일지] VIY Push시스템 만들기 #03 (5) | 2024.10.29 |
[개발일지] VIY 롤백시스템 #02 (3) | 2024.10.26 |
[개발일지] VIY 타일기반 움직임 시스템 #01 (2) | 2024.10.26 |