using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Janken : MonoBehaviour
{
public enum voice{
start,
pon,
goo,
choki,
par,
win,
loose,
draw
}
const int JANKEN = 0;
const int GOO = 1;
const int CHOKI = 2;
const int PAR = 3;
const int DRAW = 4;
const int WIN = 5;
const int LOOSE = 6;
private bool _flgJanken;
private int _modeJanken;
public AudioClip [] voice_janken = new AudioClip[8];
private Animator _animator;
private AudioSource _audioSource;
private int _myHand;
private int _unityHand;
private int _flagResult;
private float _waitTime;
public GUIStyle [] btu = new GUIStyle[4]; // 1 바위 2 찌 3 빠
void Start()
{
_animator = GetComponent<Animator>();
_audioSource = GetComponent<AudioSource>();
}
void Update()
{
_animator.SetBool("Win", false);
_animator.SetBool("Loose", false);
if (_flgJanken == true)
{
switch (_modeJanken)
{
case 0: // 시작
UnityChanAction(JANKEN);
_modeJanken++;
break;
case 1: // 플레이어 입력 대기
break;
case 2: // 판정
_flagResult = -1;
_unityHand = Random.Range(GOO, PAR+1);
UnityChanAction(_unityHand);
if (_myHand == _unityHand)
{
_flagResult = DRAW;
}
else
{
switch (_unityHand)
{
case GOO:
if (_myHand == PAR) _flagResult = LOOSE;
break;
case CHOKI:
if (_myHand == GOO) _flagResult = LOOSE;
break;
case PAR:
if (_myHand == CHOKI) _flagResult = LOOSE;
break;
}
if (_flagResult != LOOSE) _flagResult = WIN;
}
_modeJanken++;
break;
case 3: // 결과
_waitTime += Time.deltaTime;
if (_waitTime > 1.5)
{
UnityChanAction(_flagResult);
_waitTime = 0;
_modeJanken++;
}
break;
case 4:
_flgJanken = false;
_modeJanken = 0;
break;
}
}
}
void OnGUI()
{
if (_flgJanken == false)
{
if (GUI.Button(new Rect(10, Screen.height - 110, 100, 100), "가위바위보", btu[3]))
{
_flgJanken = true;
}
}
if (_modeJanken == 1)
{
if(GUI.Button (new Rect(Screen.width / 2 - 120, 400, 100, 100), "바위", btu[0]))
{
_myHand = GOO;
_modeJanken++;
}
if(GUI.Button (new Rect(Screen.width / 2, 400, 100, 100), "가위", btu[1]))
{
_myHand = CHOKI;
_modeJanken++;
}
if(GUI.Button (new Rect(Screen.width / 2 + 120, 400, 100, 100), "보", btu[2]))
{
_myHand = PAR;
_modeJanken++;
}
}
}
void UnityChanAction(int action)
{
switch (action)
{
case JANKEN:
//animator.SetBool("Janken", true);
_audioSource.clip = voice_janken[(int)voice.start];
break;
case GOO:
//_animator.SetBool("Goo", true);
_audioSource.clip = voice_janken[(int)voice.goo];
break;
case CHOKI:
//_animator.SetBool("CHOKI", true);
_audioSource.clip = voice_janken[(int)voice.choki];
break;
case PAR:
//_animator.SetBool("Par", true);
_audioSource.clip = voice_janken[(int)voice.par];
break;
case DRAW:
//_animator.SetBool("Aiko", true);
_audioSource.clip = voice_janken[(int)voice.draw];
break;
case WIN:
_animator.SetBool("Win", true);
_audioSource.clip = voice_janken[(int)voice.win];
break;
case LOOSE:
_animator.SetBool("Loose", true);
_audioSource.clip = voice_janken[(int)voice.loose];
break;
}
_audioSource.Play();
}
}
이번 글은 완성된 프로젝트를 보면서 설명하는 글이 되었다
최종 완성본이다
천천히 코드를 설명하겠다
변수들을 관리하는 시작줄들이다
public enum voice
첫 열거형 voice는 보이스를 재생할때 사용된다 만약 이를 사용하지 않을시 AudioClip을 하나하나 손수 넣는 대참사가 날 수 있으니, 사용법을 알아두면 좋다
public AudioClip [] voice_janken = new AudioClip[8];
유니티짱의 보이스를 담아두는 audioclip배열이다
이를 나중에 voice_janken[(int)voice.원하는보이스 이름]으로 사용하게 된다
각각 유니티짱의 보이스 재생등에 상태를 확인하는 용도의 값들이다
위에서 설명한 열거형을 사용하지 않을시 끔찍한 가독성을 보여준다
이후 Swich문에서 사용된다
첫 flag는 게임 시작을 확인하는 용도의 flag이다
그 다음 mode는 게임의 진행 단계를 나타낸다
hand 변수 2개의 경우 유니티짱과 플레이어의 조작을 확인하는 용도의 value이다
flagresult는 두 hand변수를 비교하여 승리, 패배, 비김을 확인하는 용도이다
waittime의경우 다음 게임을 진행하기 위한 대기 타임이다
public GUIStyle [] btu = new GUIStyle[4]; // 1 바위 2 찌 3 빠
마지막 GUI의 경우 버튼의 이미지를 담기 위한 배열이다
void Update()
{
_animator.SetBool("Win", false);
_animator.SetBool("Loose", false);
if (_flgJanken == true)
{
switch (_modeJanken)
{
case 0: // 시작
UnityChanAction(JANKEN);
_modeJanken++;
break;
case 1: // 플레이어 입력 대기
break;
case 2: // 판정
_flagResult = -1;
_unityHand = Random.Range(GOO, PAR+1);
UnityChanAction(_unityHand);
if (_myHand == _unityHand)
{
_flagResult = DRAW;
}
else
{
switch (_unityHand)
{
case GOO:
if (_myHand == PAR) _flagResult = LOOSE;
break;
case CHOKI:
if (_myHand == GOO) _flagResult = LOOSE;
break;
case PAR:
if (_myHand == CHOKI) _flagResult = LOOSE;
break;
}
if (_flagResult != LOOSE) _flagResult = WIN;
}
_modeJanken++;
break;
case 3: // 결과
_waitTime += Time.deltaTime;
if (_waitTime > 1.5)
{
UnityChanAction(_flagResult);
_waitTime = 0;
_modeJanken++;
}
break;
case 4:
_flgJanken = false;
_modeJanken = 0;
break;
}
}
}
대망의 update 부분이다
시작부터 애니메이터의 값을 초기화 하고 있는데
기본적으로 이런 형태를 하고 있다
즉, win과 lose가 false일시 wait애니메이션 상태를 유지하는 것이다
그후, if문에서 _flgJanken이 true가 되면 게임을 시작한다
이때 이 bool값을 true로 만들어 주는 버튼은
함수에 존재하는 OnGUI이다
OnGUI는 Update와 같이 매 프레임 자동 갱신되는 함수이며, 말 그대로 GUI를 표현하기 위한 메서드이다
이때 첫 if문이
인데 즉, 게임이 시작중이 아니라면 시작버튼을 구현하고 있는 것이다.
이렇게 구현된 버튼을 누를시 _flgJanken이 true가 되어서 update에서 게임을 시작하게 된다
이렇게 update에서 case0을 벗어날시
case1에 다다르게 되는데
겉보기에도 아무것도 없어 보인다...
왜냐하면 이때 사용되는 버튼들이 OnGUI에 구현되어 있기 때문이다
시작버튼을 누르면 묵찌빠 버튼 3개가 등장하게 되어 있다
이때 GUI.(class) (new (도형)(vector3 좌표값), (string text), (gui image))의 형태의 메서드를 사용한다
그래서 각각의 버튼을 누를시, 플레이어의 hand를 저장한뒤 다음 단계로 넘어간다
판정은 간단하다, Random으로 유니티짱의 hand를 결정한뒤, 바로 승리 / 패배 / 무승부를 가리고 다음단계로 넘어간다
case 2에서 얻은결과를 가지고 유니티짱이 반응할 시간을 제공한다
그후 다시 첫 if문으로 돌아가도록 만들어낸다
중간 중간에 존재하는
void UnityChanAction(int action)
의 경우
의 형태로, 유니티짱의 애니메이션, 보이스 재생을 담당한다
'공부 > 유니티' 카테고리의 다른 글
유니티 Cinemachine 테스트 영상 (0) | 2024.11.25 |
---|---|
유니티 잡지식 정리 - 좌표계, Transform, FOV, 은면 제거, 깊이 버퍼, 색상 비트, 팔레트, 더블 버퍼링, 텍스처 UV좌표 및 타일링, 범퍼 맵, 노말 맵, 라이트 맵, 높이 맵 (1) | 2024.10.20 |
유니티3D 공부(Part4) 유니티짱 터치하기, 레이(Raycast)와 충돌처리 (0) | 2024.10.01 |
유니티3D 공부(Part3) 말하는 유니티짱 만들기(효과음 넣기), 세이브, 로드기능 (1) | 2024.10.01 |
유니티3D 공부(Part 2) 마우스로 카메라 이동, 회전, 줌 인, 아웃 (1) | 2024.09.29 |