유니티 개발자라면 누구나 한 번씩은 다뤄본 유니티짱 패키지 파일을 활용하여 간단한 가위바위보 게임을 만들어 보려고 한다. 기본적인 게임 제작에 앞서, 유니티짱을 터치했을 때 머리/가슴 부위가 서로 다른 상호작용을 하게 세팅해보았다.
먼저 머리/가슴을 클릭하면 반응 할 수 있도록 유니티짱 모델 내 Character1_Head와 J_Mun_root_00에 박스 콜라이더를 추가해주었다. 그리고 각각 Head와 Breast로 태그를 생성해주었다. 그리고 유니티짱 - Animator - Controller에 UnityChan 애니메이터를 연결해주어 기본 세팅을 완료했다.
1. Touch 컨트롤
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Touch : MonoBehaviour
{
public AudioClip voice_01; //univ_1000
public AudioClip voice_02; //univ_1091
private Animator animator;
private AudioSource univoice;
private int motionIdol = Animator.StringToHash("Base Layer.Idol");
void Start()
{
animator = GetComponent<Animator>();
univoice = GetComponent<AudioSource>();
}
void Update()
{
animator.SetBool("Touch", false); //터치 애니메이션 실행 X
animator.SetBool("TouchHead", false);
Ray ray;
RaycastHit hit; //ray를 쏘았을 때 hit된 오브젝트의 정보를 가져온다
GameObject hitObject;
if(Input.GetMouseButtonDown(0))
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(ray, out hit, 100)) // 인자는 (시작점, 방향, 최대거리)
{
hitObject = hit.collider.gameObject;
if(hitObject.gameObject.tag == "Head")
{
animator.SetBool("TouchHead", true); //터치 애니메이션 실행
univoice.clip = voice_01; //터치 효과음
univoice.Play(); //실행
animator.SetBool("Face_Happy", true);
animator.SetBool("Face_Happy", false);
}
else if(hitObject.gameObject.tag == "Breast")
{
animator.SetBool("Touch", true); //터치 애니메이션 실행
univoice.clip = voice_02; //터치 효과음
univoice.Play(); //실행
animator.SetBool("Face_Happy", false);
animator.SetBool("Face_Happy", true);
}
}
}
//재생 도중인 애니메이션이 Idol 애니메이션인지 체크
if(animator.GetCurrentAnimatorStateInfo(0).nameHash == motionIdol)
{
animator.SetBool("Motion_Idle", true);
}
else
{
animator.SetBool("Motion_Idle", false);
}
}
}
여기서 마우스를 클릭할 때 반응한다는 개념을 Raycast로 가져왔다. 특정 부분을 마우스로 클릭했을 때, 즉 ray를 쏘았을 때 hit된 Object의 콜라이더가 반응하게 하여 명령을 호출한다는 스크립트를 작성했다. Head 태그가 걸려있는 부분(머리)을 클릭 시, univ_1000라는 오디오가 생성되면서 UnityChan 애니메이터 내 BaseLayer의 TouchHead 애니메이션이 작동하게 된다. 그리고 Breast 태그가 걸려있는 부분(가슴)을 클릭 시, univ_1091라는 오디오와 함께 Head 애니메이션이 생성되게 된다. 아무런 클릭을 하지 않으면 Idol 기본 애니메이션이 세팅된다. (지금까지 사용한 오디오 소스와 애니메이션은 유니티짱 패키지를 임포트하면 자동적으로 받아진다.)
2. 가위바위보 컨트롤
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class JanKen : MonoBehaviour
{
bool flgJanken = false; //가위바위보 모드 플래그
int modeJanken = 0;
public AudioClip voice_janken_start;
public AudioClip voice_janken_pon;
public AudioClip voice_janken_goo;
public AudioClip voice_janken_choki;
public AudioClip voice_janken_par;
public AudioClip voice_janken_win;
public AudioClip voice_janken_loose;
public AudioClip voice_janken_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 Animator animator;
private AudioSource univoice;
int myHand;
int unityHand;
int flgResult;
float waitTime;
public GUIStyle btStyleMode; //버튼에 이미지 설정
public GUIStyle btStyleGoo;
public GUIStyle btStyleChoki;
public GUIStyle btStylePar;
private void Start()
{
animator = GetComponent<Animator>();
univoice = GetComponent<AudioSource>();
}
private void OnGUI()
{
if(flgJanken == false)
{
if(GUI.Button(new Rect(10, Screen.height - 110, 100, 100), "가위바위보", btStyleMode))
{
flgJanken = true;
}
}
if(modeJanken == 1)
{
if(GUI.Button(new Rect(Screen.width/2 - 120, 400, 100, 100), "바위", btStyleGoo))
{
myHand = GOO;
modeJanken++;
}
if (GUI.Button(new Rect(Screen.width / 2, 400, 100, 100), "가위", btStyleChoki))
{
myHand = CHOKI;
modeJanken++;
}
if (GUI.Button(new Rect(Screen.width / 2 + 120, 400, 100, 100), "보", btStylePar))
{
myHand = PAR;
modeJanken++;
}
}
}
void Update()
{
if(flgJanken)
{
switch(modeJanken) //가위바위보 모드
{
case 0:
UnityChanAction(JANKEN);
modeJanken++; break; //가위바위보 시작
case 1:
animator.SetBool("Janken", false);
animator.SetBool("Aiko", false);
animator.SetBool("Goo", false);
animator.SetBool("Choki", false);
animator.SetBool("Par", false);
animator.SetBool("Win", false);
animator.SetBool("Loose", false);
break; //플레이어의 입력을 기다림
case 2:
flgResult = -1;
unityHand = Random.Range(GOO, PAR + 1);
UnityChanAction(unityHand);
if (myHand == unityHand) flgResult = DRAW;
else
{
switch(unityHand)
{
case GOO: if (myHand == PAR) flgResult = LOOSE; break;
case CHOKI: if (myHand == GOO) flgResult = LOOSE; break;
case PAR: if (myHand == CHOKI) flgResult = LOOSE; break;
}
if (flgResult != LOOSE) flgResult = WIN;
}
modeJanken++;
break; //판정
case 3:
waitTime += Time.deltaTime;
if(waitTime > 1.5)
{
UnityChanAction(flgResult);
waitTime = 0;
modeJanken++;
}
break; //결과
case 4: flgJanken = false;
modeJanken = 0;
break;
}
}
}
void UnityChanAction(int action) //유니티찬의 액션
{
switch(action)
{
case JANKEN:
animator.SetBool("Janken", true);
univoice.clip = voice_janken_start; break;
case GOO:
animator.SetBool("Goo", true);
univoice.clip = voice_janken_goo; break;
case CHOKI:
animator.SetBool("Choki", true);
univoice.clip = voice_janken_choki; break;
case PAR:
animator.SetBool("Par", true);
univoice.clip = voice_janken_par; break;
case DRAW:
animator.SetBool("Aiko", true);
univoice.clip = voice_janken_draw; break;
case WIN:
animator.SetBool("Win", true);
univoice.clip = voice_janken_win; break;
case LOOSE:
animator.SetBool("Loose", true);
univoice.clip = voice_janken_loose; break;
}
univoice.Play();
}
}
먼저 OnGUI() 메서드를 가져와 버튼을 제작했다. 보통은 UI - Button을 통해서 버튼 UI를 직접 제작하지만 그런 과정 없이 스크립트만으로도 제작할 수 있다. OnGUI()메서드가 기본적으로 제공하는 세부 변수들이 많기 때문에 해당 함수를 가져와서 다양한 인자를 설정할 수 있다. 먼저 bool 형식과 if문을 활용하여 가위/바위/보 조건을 세팅하고 , 가로세로 10짜리 정사각형 rec과 포지션, 그리고 btStyleMode를 오버로딩해주어 버튼 이미지까지 추가해주었다. 그리고 유니티짱이 내는 가위바위보는 unityHand라는 변수와 random.range() 함수를 선언해 주었고, 플레이어와의 승부 결과 승/패/비김 은 switch case문으로 하나씩 설정했다.
추가적으로 UnityChanAction()메서드를 새로 생성해주어 각각의 승부 결과마다 다른 애니메이션 Action과 Voice를 보여주도록 설정했다. 참고로 JanKen(가위바위보), Goo(가위) ,Choki(바위), Par(보), Aiko(비김)을 의미한다.
스크립트 작성 후 인스펙터 창의 스크립트 빈 공간에 다음과 같이 연결해주었다. BtStyleMode에서 Normal(기본 배경), Hover(마우스 커서를 버튼에 올려놓은 경우), Active(클릭한 경우)를 다음과 같이 이미지로 연결해주었다. 그리고 이렇게 할 경우 각각 버튼에 이미지와 함께 "가위바위보/가위/바위/보" 글자가 남겨지는데 이를 제거해주기 위해 인스펙터 하단 부분에 위치한 image position에서 image only로 변경해주면 된다.
아래 bt Style Goo / bt Style Choki / bt Style Par도 위와 동일하게 이미지를 연결해주고 Image Only 세팅을 해주면 끝난다.
최종적으로 다음과 같은 UI가 나오고 게임을 진행하면 설정했던 애니메이션과 오디오가 함께 출력될 것이다
'게임 프로그래밍 > 유니티 프로젝트' 카테고리의 다른 글
[VR 개발]유니티 VR환경 기본 세팅(OVRPlayerController, OVRCameraRig, LocalAvatar) (0) | 2021.09.03 |
---|---|
[VR 개발]유니티를 활용하여 POLY & TILT BRUSH 툴킷 세팅 및 glb 파일 임포트하기 (2) | 2021.09.03 |
[VR 개발]Meta QUEST2 연결하기(개발자 모드, 링크, 캐스팅) (0) | 2021.08.20 |
유니티를 활용한 3D 적 피하기 게임 만들기(2) (0) | 2021.08.11 |
Vuforia를 활용하여 유니티 AR 카메라 만들기 (1) | 2021.07.31 |