멋쟁이사자처럼부트캠프 유니티 게임 개발 5기 26일차 - 벡터, 행렬, 플랫포머 게임

2025. 6. 23. 16:49·강의/멋쟁이 사자처럼 유니티 부트캠프

벡터의 내적과 외적, 행렬에 대해 배우며 게임 수학 부분을 마무리하고, 새롭게 플랫포머 게임 제작에 들어갔다.

일반적인 RPG 게임에서 필요한 타일맵, 콤보 기술 등 다양한 스킬들을 배울 수 있을 것 같아서 기대된다. 개인적으로 하는 프로젝트에서 고민 됐던 부분들도 배울 수 있을 것 같다.

 

벡터

내적

두 벡터의 관계

|a||b|cos

Vecotr3.Dot(a, b)

public Vector3 vecA = new Vector3(1, 0, 0);
public Vector3 vecB = new Vector3(0, 1, 0);

void Start()
{
    float result = Vector3.Dot(vecA, vecB);
    Debug.Log($"벡터의 내적 {result}"); // 0
    
    float angle = Vector3.Angle(vecA, vecB);
    Debug.Log($"벡터의 끼임각 {angle}");
}

외적

두 벡터의 수직 벡터

|a||b|sin

Vector3.Cross(a, b)

public Vector3 vecA = new Vector3(1, 0, 0);
public Vector3 vecB = new Vector3(0, 1, 0);

void Start()
{
    Vector3 result = Vector3.Cross(vecA, vecB);
    Debug.Log($"벡터의 외적 {result}"); // (0, 0, 1)
}

반사각

Vector3.Reflect(입사각, 법선 벡터)

Vector3 reflect = Vector3.Reflect(vecA, vecB);
Debug.Log($"반사각 {reflect}");

선형 이동 (Lerp)

두 값 사이를 선형적으로 보간 → Linear Interpolation

// 0부터 10까지 천천히 움직이게
Math.Lerp(0, 10, 0.5f);

// Lerp(현재 위치, 목표 위치, 이동 비율)
transform.position = Vector3.Lerp(transform.position, target.position,  smoothValue);

행렬 실습

행렬을 이용해 타일을 까는 코드를 작성해보았다.

public class SetTile : MonoBehaviour
{
    public GameObject tilePrefab;
    public int rows = 5, cols = 5;

    IEnumerator Start()
    {
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                var pos = new Vector3(i, 0, j);
                
                GameObject tile = Instantiate(tilePrefab, pos, Quaternion.identity);
                Renderer rend = tile.GetComponent<Renderer>();
                
                if ( (i+j) % 2 == 0)
                    rend.material.color = Color.black;
                else
                    rend.material.color = Color.white;
                
                yield return new WaitForSeconds(0.1f);
            }
        }
    }
}

터렛 생성

깔려지는 타일을 클릭하면 해당 칸에 터렛이 생성되는 코드이다.

public class Tile : MonoBehaviour
{
    public GameObject turretPrefab;

    void OnMouseDown()
    {
        Instantiate(turretPrefab, transform.position, Quaternion.identity);
    }
}

결과

버튼

UI 버튼 클릭 시 터렛인덱스가 변경되어 다른 터렛을 설치할 수 있도록 하였다.

public class SetTile : MonoBehaviour
{
    public Button[] buttons;

    public static int turretIndex;
    
    void Awake()
    {
        buttons[0].onClick.AddListener(()=>ChangeIndex(0));
        buttons[1].onClick.AddListener(()=>ChangeIndex(1));
        buttons[2].onClick.AddListener(()=>ChangeIndex(2));
        buttons[3].onClick.AddListener(()=>ChangeIndex(3));
        buttons[4].onClick.AddListener(()=>ChangeIndex(4));
    }

    void ChangeIndex(int index)
    {
        turretIndex = index;
    }
}

 

public class Tile : MonoBehaviour
{
    public GameObject[] turretPrefabs;
    void OnMouseDown()
    {
        Instantiate(turretPrefabs[SetTile.turretIndex], transform.position, Quaternion.identity);
    }
}

클로져(Closure) 이슈

클로저(Closure)란, 외부 변수나 필드와 같은 '환경'을 저장하고 있는 함수이다.

아래 코드처럼 for문의 변수 i를 람다식에 사용할 경우 클로져로 인식하기 때문에 의도한 결과대로 동작하지 않는다.

따라서 이를 해결하기 위해 새로운 변수 j를 만들어서 대입하는 방식을 쓸 수 있다.

buttons[0].onClick.AddListener(()=>ChangeIndex(0));
buttons[1].onClick.AddListener(()=>ChangeIndex(1));
buttons[2].onClick.AddListener(()=>ChangeIndex(2));
buttons[3].onClick.AddListener(()=>ChangeIndex(3));
buttons[4].onClick.AddListener(()=>ChangeIndex(4));

// 위처럼 실행되지 않음
for (int i=0; i<5; i++)
    buttons[i].onClick.AddListener(()=>ChangeIndex(i));
    
// 해결
for (int i=0; i<5; i++)
{
	int j = i;
    buttons[j].onClick.AddListener(()=>ChangeIndex(j));
}

 

결과

 

플랫포머 게임

플레이어 이동

항상 해왔던 키보드 입력을 받는 플레이어 이동을 구현했다.

public class KnightController_Keyboard : MonoBehaviour
{
    Animator animator;
    Rigidbody2D knightRb;

    private Vector3 inputDir;

    private bool isGround;

    [SerializeField]
    private float moveSpeed = 3f;
    [SerializeField]
    private float jumpPower = 1f;
    void Start()
    {
        animator = GetComponent<Animator>();
        knightRb = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        InputKeyboard();
    }
    
    void FixedUpdate()
    {
        Move();
    }

    void OnCollisionEnter2D(Collision2D other)
    {
        if (other.gameObject.CompareTag("Ground"))
        {
            animator.SetBool("isGround", true);
            isGround = true;
        }
    }

    private void OnCollisionExit2D(Collision2D other)
    {
        if (other.gameObject.CompareTag("Ground"))
        {
            animator.SetBool("isGround", false);
            isGround = false;            
        }
    }

    void InputKeyboard()
    {
    	// GexAxis : 서서히 0이 됨
        // GexAxisRaw : -1, 0, 1이 나오기때문에 바로 멈춤
        float h = Input.GetAxisRaw("Horizontal");
        float v = Input.GetAxisRaw("Vertical");
        inputDir = new Vector3(h, v, 0);

        Jump();
        SetAnimation();
    }

    void Jump()
    {
        if (Input.GetKeyDown(KeyCode.Space) && isGround)
        {
            animator.SetTrigger("Jump");
            knightRb.AddForceY(jumpPower, ForceMode2D.Impulse);
        }
    }
    
    void Move()
    {
        if (inputDir.x != 0)
            knightRb.linearVelocityX = inputDir.x * moveSpeed;
        
    }

    void SetAnimation()
    {
        if (inputDir.x != 0)
        {
            var scaleX = inputDir.x > 0 ? 1 : -1;
            transform.localScale = new Vector3(scaleX, 1, 1);
            
            animator.SetBool("isRun", true);
        }
        else
        {
            animator.SetBool("isRun", false);
        }
    }

    
}

조이스틱

터치스크린

UI 패널을 만들고 Event Trigger 컴포넌트를 추가한다.

이벤트들을 추가하면 다양한 UI 이벤트를 인식하는데, Image 컴포넌트의 Raycast Target이 켜져있기 때문이다.

'강의/멋쟁이 사자처럼 유니티 부트캠프' 카테고리의 다른 글
  • 멋쟁이사자처럼부트캠프 유니티 게임 개발 5기 28일차 - 타일맵, 키보드 공격
  • 멋쟁이사자처럼부트캠프 유니티 게임 개발 5기 27일차 - 조이스틱 이동, 점프, 공격
  • 멋쟁이사자처럼부트캠프 유니티 게임 개발 5기 25일차 - 몬스터 게임 마무리, 삼각함수
  • 멋쟁이사자처럼부트캠프 유니티 게임 개발 5기 24일차 - 몬스터 피격, 죽음, 스폰
로또
로또
게임 개발자 연습생의 발전 일지
  • 로또
    게임 개발 발전소
    로또
  • 전체
    오늘
    어제
    • 분류 전체보기 N
      • 개발
        • 코딩테스트
        • JAVA
        • DB
        • Unity
      • 강의 N
        • 패스트캠퍼스 0원 챌린지
        • 멋쟁이 사자처럼 유니티 부트캠프 N
      • 게임
        • 공부
        • 리뷰
  • 블로그 메뉴

    • 홈
    • 방명록
    • 글쓰기
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    오공완
    2839
    게임개발
    환급챌린지
    직장인인강
    BFS
    패스트캠퍼스후기
    Java
    수강료0원챌린지
    패스트캠퍼스
    dfs
    그리디
    자료구조
    3D웹인터랙티브
    백준
    백트래킹
    트리
    분리집합
    직장인자기계발
    완전탐색
    Unity
    C4D
    멋쟁이사자처럼후기
    패캠챌린지
    패캠인강후기
    그래프
    C#
    한번에끝내는프론트엔드개발초격차패키지Online
    코딩테스트
    그리디알고리즘
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
로또
멋쟁이사자처럼부트캠프 유니티 게임 개발 5기 26일차 - 벡터, 행렬, 플랫포머 게임
상단으로

티스토리툴바