본문 바로가기
자유게시판

항해 플러스 코육대) 총알 피하기 참가 후기!

by DearGreen 2023. 10. 3.

2023년도 항해 플러스: 제 1회 코육대

코육대 링크 : https://hanghaeplus-coyukdae.oopy.io/#1b467c7185e94a3295dc4a72a05ea3b2

 

항해 플러스: 제1회 코육대

이번 추석, 굳어버린 코딩 근육을 깨울 코딩 육상 대회가 왔다!

hanghaeplus-coyukdae.oopy.io

 


 

이번 추석 연휴 당시, 뭘 해볼까하고 여러 가지 찾아보다가 항해플러스에서 개최하는 코딩 육상 대회에 대해 알게 되었다.

연휴 때 계속 놀기보단 뭐라도 남기는 좋을 것 같아 가벼운 마음으로 참가해보기로 했다!

 

 

참가 부문은 총알 피하기로 결정했다!

개발 엔진으로는 유니티를 사용하기로 하였고, 이번 토이 프로젝트의 목표를 크게 세 가지로 잡았다!

 

1. '총알피하기' 에 충실한 싱글플레이 모드 구현

2. SQLite와 연동해 로컬 저장소를 만들어 랭킹시스템 구현

3. Photon Pun2 에셋을 이용해 멀티플레이 모드 구현

 

올해 초 개인적으로 SQLite와 Pun2를 이용해 간단한 토이 프로젝트를 진행한 적이 있었다.

이번 교육대를 계기로 총알 피하기를 제작하면서 공부한 내용을 다시 상기시킬 수 있어 매우 좋았다!

 


 

1. 총알피하기 싱글플레이 모드 구현

싱글플레이 모드 내부의 사진이다!

싱글플레이 모드는 라이프를 3개로 하였고, 3초마다 총알이 플레이어를 향해 날아오는 방식으로 만들었다.

 

아래 코드는 플레이어의 움직임을 구현한 SailMove.cs 파일이다.

싱글플레이 모드에서는 플레이어(1p)에 위 코드를 부착해 사용자의 입력을 Update()에서 처리하였다.

또한 OnTriggerEnter2D()를 이용해서 플레이어가 총알에 닿았을 때 UI 처리와 무적 시간(3초)를 부여하였다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SailMove : MonoBehaviour
{
    Rigidbody2D RB;
    SpriteRenderer SR;

    public UImanager_SinglePlay UImanager;
    public Animator Animator;
    public int PlayerSpeed = 3;
    public bool Isinvincibility = false;
    public bool CoolerOn = false;

    void Start()
    {
        RB = GetComponent<Rigidbody2D>();
        SR = GetComponent<SpriteRenderer>();
    }

    void Update()
    {
        if (!UImanager.GameOver)
        {
            playerMove();
            UseBooster();
        }
    }
    public void playerMove()
    {
        float axis_width = Input.GetAxisRaw("Horizontal");
        float axis_length = Input.GetAxisRaw("Vertical");

        if (axis_width != 0)
        {
            SR.flipX = axis_width == 1;
        }

        RB.velocity = new Vector2(PlayerSpeed * axis_width, PlayerSpeed * axis_length);
    }

    public void UseBooster()
    {
        if (Input.GetKey(KeyCode.Space) && !CoolerOn)
        {
            UImanager.slider.value -= Time.deltaTime * 2;
            PlayerSpeed = 5;
            if (UImanager.slider.value < 0.1f) CoolerOn = true;
        }
        else 
        {
            UImanager.slider.value += Time.deltaTime;
            PlayerSpeed = 3;
            if (UImanager.slider.value >= 4.9) CoolerOn = false;
        }
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.tag == "Obstacle" && !Isinvincibility)
        {
            UImanager.DropHeart();
            StartCoroutine(invincibilityTime());
        }
    }

    IEnumerator invincibilityTime()
    {
        Animator.SetBool("IsHitted", true);
        Isinvincibility = true;
        yield return new WaitForSeconds(2);
        Animator.SetBool("IsHitted", false);
        Isinvincibility = false;
    }

    IEnumerator CoolTime()
    {
        yield return new WaitForSeconds(1f);
    }
}

 

2. SQLite와 연동해 로컬 저장소를 만들어 랭킹시스템 구현

아래 코드는 로컬 환경에서 사용자의 점수(버틴 시간)을 기록하는 SQlite.cs 파일의 일부이다.

SQlite와 연동하여 Query문을 유니티 내부 스크립트에서 입력할 수 있게 하였다!

    public void RecordRanking()
    {
        // 점수를 넣어야 하는데, 등록 이름이 없다면 등록하지 않고 반려시킨다.
        if(UserName_inputField.text.Length == 0)
        {
            return;
        }

        // 점수 등록과정. InsertQueryDataBase() 함수를 이용해 등록 닉네임과 점수를 등록한다.
        // 버틴 초의 합계가 점수가 된다.
        try
        {
            int playerScore = 0;
            if (UImanager_Single != null) playerScore = ((int)UImanager_Single.Time_sec) + 60 * UImanager_Single.Time_min;
            else if(UImanager_Multi != null) playerScore = ((int)UImanager_Multi.Time_sec) + 60 * UImanager_Multi.Time_min;

            InsertQueryDataBase("insert into user_Ranking(ID,SCORE) values(\"" + UserName_inputField.text + "\",\"" + playerScore + "\")");
            DataBaseClose();

            Debug.Log("랭킹 등록 완료.");
        }
        catch (SqliteExecutionException e)
        {
            print(e);
            return;
        }
    }

 

 

3. Photon Pun2 에셋을 이용해 멀티플레이 모드 구현

멀티플레이 모드는 1대 1로 오래 버티는 사람이 승자가되는 형식으로 만들었다.

 

아래 코드는 멀티플레이 모드에서 총알을 발사하는 BulletDispensor.cs 코드이다.

총알 발사대는 게임 내부에 총 8개를 만들었으며, Pun2의 RPC 개념을 이용해 두 사용자 간 총알이 스폰되고 발사되는 식의 동기화를 처리하였다. 이 때 총알이 목표로 하는 표적은 Unity의 Random.range() 함수를 사용해 두 플레이어 중 하나에게 총알이 향하도록 만들었다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using Photon.Pun;
using Photon.Realtime;
using System.Reflection;
using UnityEditor;

public class BulletDispensor_MultiPlay : MonoBehaviourPun
{
    public GameObject bullet_prefab;
    public GameObject Player_1;
    public GameObject Player_2;

    public PhotonView PV;
    public float FireDelay = 3f;
    public float CurTime = 0;
    public int ShotPower = 3;

    public bool StartSpawn = false;

    private void Start()
    {
        PV = GetComponent<PhotonView>();
        PV.RPC("FindSail", RpcTarget.All);
    }

    // 1초 간격으로 총알 발사
    void Update()
    {
        if(StartSpawn)
        {
            CurTime += Time.deltaTime;
            if (CurTime > FireDelay)
            {
                PV.RPC("BulletDispenseRPC", RpcTarget.All);
            }
        }
    }

    [PunRPC]
    public void BulletDispenseRPC()
    {
        GameObject bullet = PhotonNetwork.Instantiate("bullet_prefab", this.transform.position, this.transform.rotation);

        int RN = Random.Range(0, 2);
        GameObject targetPlayer;
        if (RN == 1) targetPlayer = Player_1;
        else targetPlayer = Player_2;

        Vector2 direction = (targetPlayer.transform.position - this.transform.position).normalized;
        bullet.GetComponent<Rigidbody2D>().velocity = direction * ShotPower;
        CurTime = 0;
    }

    [PunRPC]
    public void FindSail()
    {
        Player_1 = GameObject.Find("1p_Sail(Clone)");
        Player_2 = GameObject.Find("2p_Sail(Clone)");
        StartSpawn = true;
    }
}

 

다만 동기화의 처리가 살짝 미흡한 부분이 있어서 총알의 위치가 미세하게 틀리는 오류가 있었지만 그럭저럭 완성했다!

 

게임을 실제로 다운로드 받을 수 있는 구글 드라이브 링크다!

코육대 평가 기간이 끝나면 다시 내릴 예정이다.

https://drive.google.com/file/d/17LcO465HNMknYEEj_k3x2SxnZphgL3M7/view?usp=sharing

 

DudgeSail.zip

 

drive.google.com

게임 조작법에 관해서는 깃허브 레포지토리에 따로 올려놓았다! 게임을 시작하기 전 아래 링크에 접속해

readme 파일을 읽어보길 바란다.

 

https://github.com/belfly1111/DudgeSail

 

GitHub - belfly1111/DudgeSail: 2023 항해플러스 제 1회 교육대 참가작 입니다.

2023 항해플러스 제 1회 교육대 참가작 입니다. Contribute to belfly1111/DudgeSail development by creating an account on GitHub.

github.com

 

이번 추석연휴 동안 시간을 의미 없게 보내기 보다는 코육대에 참가하는게 훨씬 좋은 선택이었다!

과거에 진행했었던 토이프로젝트 내용을 다시 상기시킬 수 있었던 좋은 기회였고 내년에도 코육대를 한다면 부족한 점을 더 보완해서 참가하고 싶다!