오랫만에 돌아옴

게임 제목 FarmingKnight가 될 가능성이 크다

이번엔 출시 하겠지 뭐..



기획을 좀 갈아엎고 싶어서 새로 만들었음 

정확히는 액션감을 넣고 싶었는데 조이스틱으론 대쉬 같은 제스쳐가 쉽지 않다는게 이유임


그래서 상하좌우 + 대각선 방향키 + 중앙 버튼으로 캐릭터를 구성하고 싶었음


마을 농사 + 로그라이크 던전 기본 틀은 여전히 그대로인데 기존 기획이랑 차이점이라면

기존엔 한칸씩 상호작용하면서 게임 했다면 이젠 걍 전부 범위 공격으로 때려서 밭도 범위 공격으로 갈고 물도 범위 공격으로 뿌리고 돌도 나무도 적도 다 범위공격으로 후림

그저 범위공격임


암튼 그런식으로 좀 한번에 터지는 느낌이 주고 싶었음




일단 캐릭터와 이동 버튼을 구현해야함


최근에 세피리아라고 던그리드 개발사에서 새로 출시한 게임 사서 했는데

캐릭터가 나름 신박하더라고


원래 탑다운이면 보통 좌우 / 상 / 하 해서 세장을 그리잖아?


근데 세피리아는 옆 / 옆 위 두장만 그려서 하더라고



24b0d121e09c28a8699fe8b115ef046c62f4204f

24b0d121e09c28a8699fe8b115ef046c60f12f4f

이런식으로.



개인적으로 보자마자 꽤 좋은 방법이라고 생각했음


일단 측면이랑 앞 뒷면은 시점 자체가 다르다보니 비용이 증가하고 어색한 느낌이 있음

근데 이 방법은 일단 테두리를 상당수 공유함 (이건 픽셀 수가 적어서 가능한 느낌이지만)


그리고 이미지를 2장만 그리면 되기에 비용이 상당히 줄어듦



단점 뽑자면 상 하 이동시 약간의 부자연스러움이 있음 기본적으로 측면만 바라보기 때문에


그래도 굉장히 쓸만한 테크닉인듯




이동 버튼은 꽤 오랫동안 고민했는데 결국은 이 방법이 정답인거같음.


모바일 이동 버튼을 유니티에서 구현하려하면 살짝 벽이 있는데


경우를 하나 뽑자면


1. A 버튼을 누른채로

2. B 버튼으로 손을 드래그

3. B 버튼 위에서 손을 뗌

4. B 버튼 중단


이걸 유니티의 기본 Input System으로 구현하려면 좀 힘듦


OnPointerUp 메서드는 손을 뗄 때 처음 누른 버튼에서 호출함.

한마디로 B 위에서 손을 떼도 A버튼 중단이 호출됨


해결법은 그냥 중앙 통제 했음.
















using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class MoveButton : Selectable, IPointerEnterHandler, IPointerExitHandler
{
    [SerializeField] private MovePadController movePadController;
 
    public Vector2 direction;
 
    public override void OnPointerEnter(PointerEventData eventData)
    {
        movePadController.SetHoveredButton(this);
        DoStateTransition(SelectionState.Highlighted, false);
    }
 
    public override void OnPointerExit(PointerEventData eventData)
    {
        movePadController.ClearHoveredButton(this);
        DoStateTransition(SelectionState.Normal, false);
    }
 
    public void OnPointerPressed()
    {
        DoStateTransition(SelectionState.Pressed, false);
    }
 
    public void OnPointerReleased()
    {
        DoStateTransition(SelectionState.Normal, false);
    }
}
 
cs


버튼은 Enter, Exit 시점에 중앙 통제하는 애한테 Hover, 마우스 올라온 상태만 보냄

모바일 환경이라면 그닥 필요없는 코드긴 한데 마우스를 쓰거나 그 외의 상황까지 상정해서 이렇게 코드를 짰음.

버튼 위에 마우스 포인터 올라간 상태임. 마지막 버튼만 기록함.


참고로 Selectable은 유니티 내장 클래스 Button에 있는 Highlighted Pressed Selected Disabled 같은거 제공해주는 건데 귀찮아서 가져와서 썼음




    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            isMouseDown = true;
            if (currentHoveredButton != null)
            {
                currentPressedButton = currentHoveredButton;
                currentPressedButton.OnPointerPressed();
                CheckDoubleClick(currentPressedButton);
            }
        }
 
        if (Input.GetMouseButtonUp(0))
        {
            isMouseDown = false;
            if (currentPressedButton != null)
            {
                currentPressedButton.OnPointerReleased();
                currentPressedButton = null;
            }
        }
    }
cs


중앙 통제하는 곳에선 마우스가 Hover된 상태인 버튼을 기준으로 누를때 뗄 때 해당 버튼에서 처리함.


추가로 마우스 위에 올라간걸 감지할 때 마우스가 이미 눌려있으면 누른걸로 판정함




대충 보면 이런느낌


2ab4d677abd531a04e81d2b628f17c6c95fa9bdcf8


그리고 이걸 이제서야 깨달았다는게 좀 바보같은데

2D상에서 캐릭터 이동은 걍 무조건

RigidBody2D.velocity & RigidBody2D.MovePosition


이 두개만 쓰고 플레이어는 무조건 Circle Collider 2D


이 외의 방법을 쓰는순간 벽에 비벼지더라





다음은 체력바를 만들거임


얘도 살짝 고민이 있었음.

SpriteRenderer로 구현하면 뭔가 어정쩡하게 구현된다는게 문제였음.


뭐 여전히 UI에 비하면 구리긴 한데 복잡하게 꾸미지 않는다는 전제하엔 이 방법으로 계속 쓰게 될거같음




24b0d121e09c28a8699fe8b115ef046ec348cb

우선 사각형 스프라이트 세개를 그림



24b0d121e09c28a8699fe8b115ef046549ae

하나는 테두리, 하나는 뒷 배경, 하나는 체력바임


이때 체력바 스프라이트만 Pivot을 Left Center로 설정함


24b0d121e09c28a8699fe8b115ef046c61f92a


위와 같은 계층으로 그렸으면 체력바의 Transform은 해당 값으로 고정됨


24b0d121e09c28a8699fe8b115ef046c61f12a49


여기서 scale.x 값이 바의 value임



이제 아웃라인과 배경의 scale을 지정해줄건데

나는 체력바에 크기를 따로 지정하고 싶음



다만 scale로 만지다보니 가로나 세로 둘중에 하나만 늘려도 비율이 안맞게 됨

24b0d121e09c28a8699fe8b115ef0464de84


이런식으로 



그래서 따로 코드를 짰음


    [SerializeField] private SpriteRenderer hpBack;
    [SerializeField] private SpriteRenderer hpBar;
 
 
    public float pixelRatio = 0.5f;
 
    private void Awake() {
        SetHpBarSize();
        SetHPBar(1f);
    }
 
    [ContextMenu("SetHpBarSize")]
    public void SetHpBarSize(){
        float k = transform.localScale.y * (1 - pixelRatio);
        hpBack.transform.localScale = new Vector3(1 - k / transform.localScale.x, pixelRatio, 1f);
    }
 
 
    public void SetHPBar(float ratio)
    {
        hpBar.transform.localScale = new Vector3(ratio, 1f, 1f);
    }

cs


이 코드인데 내가 되는 대로 수식 짜서 구현한거임.

이것보다 더 나은 방법 있는지는 모르겠음.


pixelRatio 값은 Outline 상자랑 Background 상자 크기의 세로 비율임. 해당 값을 기반으로 좌우에 padding 넣어주는 느낌임

그래서 가로길이는 세로 길이랑 비율에 영향은 안줌


암튼 그래서 보면


2ab4d674abd531a04e81d2b628f17d655cd01ad550


대충 이런식으로 유동적인 생성이 가능.....................


테두리 비중을 세로 길이 따라서 안 늘리고 유지하는법도 나중에 필요하면 짜긴 해야할 듯





추가로 이 굉장히 강력한 녀석을 최근에서야 알았는데


24b0d121e09c28a8699fe8b115ef046c61f52c4f


바로 Sorting Group임


이녀석은 본인 자식에 있는 오브젝트들의 order in layer을 하나로 합쳐줌


내부 오더링이 가능해진다는거임



이게 없으면 sprite로 체력바를 구성하면



24b0d121e09c28a8699fe8b115ef0468e6aa


이런식으로 체력바가 열받게 겹쳐져버리는데



24b0d121e09c28a8699fe8b115ef0468e5a3

쓰면 그룹으로 묶여서 깔끔하게 나눠짐