본 리듬게임 코드는 이 강좌 코드를 참고하여 작성했습니다
이 코드로 작성 된 게임을 봐 주세요 🥰
⁌ Game Manager ⁍
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
public static GameManager instance;
public int currentScore;
public int scorePerPerfect = 200;
public Text scoreText;
public Text bonusText;
public int currentbonus;
public int Tracker;
public int[] bonusHolds;
public float totalNote;
public float PerHits;
public float MissedHits;
public float percentHits;
public GameObject resultsScreen;
public Text PerfectHitText,MissedHitText,RankText,finalText,PercentHitText;
void Start()
{
instance = this;
currentbonus = 1;
totalNote = FindObjectsOfType<NoteObject>().Length;
}
void Update()
{
if(resultsScreen.activeInHierarchy == true)
{
PerfectHitText.text = PerHits.ToString();
MissedHitText.text = "" + MissedHits;
float totalHit = PerHits;
float percentHits = (totalHit/totalNote) * 100f;
PercentHitText.text = percentHits.ToString("F1") + "%";
string rankVal = "F";
if(percentHits > 40)
{
rankVal = "D";
if(percentHits > 55)
{
rankVal = "C";
if(percentHits > 70)
{
rankVal = "B";
if(percentHits > 85)
{
rankVal = "A";
if(percentHits > 95)
{
rankVal = "S";
if(percentHits > 99)
{
rankVal ="SS";
}
}
}
}
}
RankText.text = rankVal;
finalText.text = currentScore.ToString();
}
}
}
public void NoteHit()
{
if(currentbonus - 1 < ComboHolds.Length)
{
Tracker ++;
if(ComboHolds[currentbonus - 1] <= Tracker)
{
Tracker = 0;
currentbonus ++;
}
}
bonusText.text = "x" + currentbonus;
//currentScore += scorePerNote * currentCombo;
scoreText.text = "" + currentScore;
}
public void perfectHit()
{
currentScore += scorePerPerfect * currentbonus;
NoteHit();
PerHits++;
}
public void NoteMiss()
{
Debug.Log("Missed");
currentbonus = 1;
Tracker = 0;
bonusText.text = "x" + currentbonus;
MissedHits++;
}
}
게임 매니저에서
결과 화면과,점수,보너스 점수등의 UI 설정을 해주어야 하니
using UnityEngine.UI 를 작성해준다.
변수 🍳
public static GameManager instance;
public int currentScore;
public int scorePerPerfect = 200;
public Text scoreText;
public Text bonusText;
public int currentbonus;
public int Tracker;
public int[] bonusHolds;
public float totalNote;
public float PerHits;
public float MissedHits;
public float percentHits;
public GameObject resultsScreen;
public Text PerfectHitText,MissedHitText,RankText,finalText,PercentHitText;
여러 스크립트에 영향을 주는 GameManager를
instance를 이용해 싱글턴 패턴으로 만들어준다.
위에가 scoreText
아래가 bonusText.
Text를 Hierarchy에서 끌고와서 넣어준다.
Score Per Perfect는 Perfect할때 줄 점수.
Tracker 콤보 같은 개념(?) 노트를 입력할때마다 ++ 되는데
Holds에 입력된 숫자만큼 콤보를 끊기지 않고 하게 되면
x2 x3 x4... 계속 올라가게된다.
Start 🥞
void Start()
{
instance = this;
currentbonus = 1;
totalNote = FindObjectsOfType<NoteObject>().Length;
}
instance = this로 싱글턴 패턴을 완벽하게 만들어주고,
기본 currentbonus는 1로 설정해준다.
TotalNote의 숫자는 NoteObject를 찾게해서 배열(Length)
Update 🍿
void Update()
{
if(resultsScreen.activeInHierarchy == true)
{
PerfectHitText.text = PerHits.ToString();
MissedHitText.text = "" + MissedHits;
float totalHit = PerHits;
float percentHits = (totalHit/totalNote) * 100f;
PercentHitText.text = percentHits.ToString("F1") + "%";
string rankVal = "F";
if(percentHits > 40)
{
rankVal = "D";
if(percentHits > 55)
{
rankVal = "C";
if(percentHits > 70)
{
rankVal = "B";
if(percentHits > 85)
{
rankVal = "A";
if(percentHits > 95)
{
rankVal = "S";
if(percentHits > 99)
{
rankVal ="SS";
}
}
}
}
}
RankText.text = rankVal;
finalText.text = currentScore.ToString();
}
}
}
if 조건문을 사용하여 resultScreen이 Hierarchy에 active = true일때 보여줄 텍스트를 설정해주었다.
( 강좌에선 노래가 끝나면 result이 보여지게 해주었지만,나는 스크립트에서 시작과 끝을 정해주지 않았기때문에
Box Collider를 이용해 노래가 끝나는 지점을 통과하면(Player가) result화면이 active 되게 해주었다.
(밑에 Player스크립트 참고))
inspector에서 끌고온 PerFectHitText를 = perHits와 연결 시켜준다. (ToString을 이용해서 숫자를 문자화.)
Hit 🥚
public void NoteHit()
{
if(currentbonus - 1 < bonusHolds.Length)
{
Tracker ++;
if(bonusHolds[currentbonus - 1] <= Tracker)
{
Tracker = 0;
currentbonus ++;
}
}
bonusText.text = "x" + currentbonus;
//currentScore += scorePerNote * currentbonus;
scoreText.text = "" + currentScore;
}
public void perfectHit()
{
currentScore += scorePerPerfect * currentbonus;
NoteHit();
PerHits++;
}
public void NoteMiss()
{
Debug.Log("Missed");
currentbonus = 1;
Tracker = 0;
bonusText.text = "x" + currentbonus;
MissedHits++;
}
}
NoteHit으로 기본적으로 노트를 맞췄을때를 설정해준다.
1로 설정해준 currenbouns가 bonusHolds보다 작다면 Tracker++
bonusHolds안에 배열 [currentbonus]를 넣어주고 -1 한게 Tracker와 < 거나 = 다면
Tracker는 0으로 초기화
currentbonus는 ++ 해준다. (x2,x3,x4....)
( 동영상으로 Tracker와 Currentbonus가 어떻게 변하는지 보세요 ! )
그리고 판정이 되었을때 부분인
perfectHit.
Perfect or Miss로 해두어서 두가지 밖에 없는데
더 많은 판정을 넣은 분들은 저런식으로 더 코드를 작성하면 된다.
단, Miss부분에는
currentbonus와 Tracker를 다시 초기화 해주어야 한다..
⁌ Player ⁍
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerImage : MonoBehaviour
{
public SpriteRenderer Psr;
public Sprite AImage;
public Sprite SImage;
public Sprite FImage;
public Sprite GImage;
public KeyCode AKeyCode;
public KeyCode SKeyCode;
public KeyCode FKeyCode;
public KeyCode GKeyCode;
Animator anim;
public GameObject resultsScreen;
public GameObject _1Text;
public GameObject _2Text;
public GameObject _3Text;
public GameObject _4Text;
public GameObject _5Text;
public GameObject _5_2Text;
public GameObject _5_3Text;
public GameObject _6Text;
public GameObject _7Text;
public GameObject _8Text;
public GameObject _9Text;
void Start()
{
Psr = GetComponent<SpriteRenderer>();
anim = GetComponent<Animator>();
anim.Rebind();
}
void Update()
{
//A
if(Input.GetKeyDown(AKeyCode))
{
Psr.sprite = AImage;
anim.enabled = false;
}
if(Input.GetKeyUp(AKeyCode))
{
anim.enabled = true;
}
//W
if(Input.GetKeyDown(SKeyCode))
{
Psr.sprite = SImage;
anim.enabled = false;
}
if(Input.GetKeyUp(SKeyCode))
{
anim.enabled = true;
}
//D
if(Input.GetKeyDown(FKeyCode))
{
Psr.sprite = FImage;
anim.enabled = false;
}
if(Input.GetKeyUp(FKeyCode))
{
anim.enabled = true;
}
//S
if(Input.GetKeyDown(GKeyCode))
{
Psr.sprite = GImage;
anim.enabled = false;
}
if(Input.GetKeyUp(GKeyCode))
{
anim.enabled = true;
}
}
void OnTriggerEnter2D(Collider2D other)
{
if(other.tag == "Finish")
{
resultsScreen.SetActive(true);
}
if(other.tag == "Text_1")
{
_1Text.SetActive(true);
}
if(other.tag == "Text_2")
{
_2Text.SetActive(true);
}
if(other.tag == "Text_3")
{
_3Text.SetActive(true);
}
if(other.tag == "Text_4")
{
_4Text.SetActive(true);
}
if(other.tag == "Text_5")
{
_5Text.SetActive(true);
}
if(other.tag == "Text_5_1")
{
_5_2Text.SetActive(true);
}
if(other.tag == "Text_5_2")
{
_5_3Text.SetActive(true);
}
if(other.tag == "Text_6")
{
_6Text.SetActive(true);
}
if(other.tag == "Text_7")
{
_7Text.SetActive(true);
}
if(other.tag == "Text_8")
{
_8Text.SetActive(true);
}
if(other.tag == "Text_9")
{
_9Text.SetActive(true);
}
}
void OnTriggerExit2D(Collider2D other)
{
if(other.tag == "Text_1")
{
_1Text.SetActive(false);
}
if(other.tag == "Text_2")
{
_2Text.SetActive(false);
}
if(other.tag == "Text_3")
{
_3Text.SetActive(false);
}
if(other.tag == "Text_4")
{
_4Text.SetActive(false);
}
if(other.tag == "Text_5")
{
_5Text.SetActive(false);
}
if(other.tag == "Text_5_1")
{
_5_2Text.SetActive(false);
}
if(other.tag == "Text_5_2")
{
_5_3Text.SetActive(false);
}
if(other.tag == "Text_6")
{
_6Text.SetActive(false);
}
if(other.tag == "Text_7")
{
_7Text.SetActive(false);
}
if(other.tag == "Text_8")
{
_8Text.SetActive(false);
}
if(other.tag == "Text_9")
{
_9Text.SetActive(false);
}
}
}
별거 아닌 코드인데 상당히 길다..
일단 나는 기획 내용과 같이 플레이어와 캐릭터가 함께 리듬을 즐겼으면 좋겠어서
키를 누를때마다 춤을 추는 느낌으로 애니메이션이나 이미지가 바뀌었음 했는데
사실 에셋이 많이 없어서 그런걸 표현하기엔 한계가 있었다..
벽을 타는 애니메이션이나, 점프를 하는 애니메이션 등으로 대체를 했다.
그 부분이 Void Update 부분이다.
키를 누를때마다 사진을 바뀌게 하고 다시 원래 애니메이션으로 어떻게 돌려 놓지? 생각하다가
enabled를 사용하면 다시 애니메이션을 재생 시킬수 있다 해서
키를 누를때마다 애니메이션은 Flase 시키고
public으로 설정해준 이미지로 변경.
떼면은 다시 true로 변경해서 애니메이션을 재생 시킬수 있게 했다.
OnTriggerEnter2D부분은
콜라이더를 이용해서 이 부분을 지나면 텍스트를 활성화 할 수 있게 해주었다.
그리고 result창 또한 마찬가지로
Tag를 이용한 Trigger 설정을 해두었다.
( Trigger 하면 active됨, GameObject엔 active가 되면 result창에 결과를 적용.)
TileMove 😎
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TileMove : MonoBehaviour
{
public float TileSpeed;
void Update()
{
transform.position += Vector3.left * TileSpeed * Time.deltaTime;
}
}
사실 Player를 움직일수도 있었던 거였는데
Tile을 움직이고 Player Idle 애니메이션에 달리기 모션만 주었다.
Vector3가 left방향으로 tileSpeed 속도 만큼 이동한다.
그리고 Time.deltaTime 무조건 곱해주기.
오류가 뜨거나 궁금한 점이 있다면 편하게 댓글 달아주세요.
이 코드를 작성하면서 저도 오류가 많이 떴기 때문에 도와드릴수 있는 부분은 다 도와드리겠습니다 !
'🧩 코딩 > 사용한 코드' 카테고리의 다른 글
UnknownHero 코드 공유 / 오브젝트 360도 회전,아이템 떨어지기 (0) | 2023.05.15 |
---|---|
UNITY MBTI 테스트 앱 코드 / List 사용법 (0) | 2023.04.04 |
Unity2D 모바일 조이스틱을 이용한 움직임 코드 🏃♀️ Transform.localScale을 이용한 이미지 회전 (0) | 2022.10.20 |
우당탕탕 [ 피하기 게임 ] 코드 공유 / Random Range를 이용한 랜덤 오브젝트 생성 / 2D Player 움직임 코드 (2) | 2022.10.13 |
Unity 리듬 게임 1강 - 노트 입력 코드 (3) | 2022.10.06 |