본문 바로가기
유니티 최고/유니티 구현

[Unity] 유니티 주사위 시스템 구현 (Dice Roll)

by Lee_story_.. 2024. 7. 12.
728x90

 

모바일 게임을 하나 만들고 난뒤... 이번엔 PC게임을 하나 출시해보고싶어서

또 다시 끄적끄적 시작해보는중에...!

 

퍼즐, 스테이지형 게임을 만들어 보기로 하였습니다!

그러기 위해 그 중 가장 메인부분인 주사위 시스템을 이번글에서 정리해볼 예정입니다.

 

 

그럼 시작! 


주사위 시스템이라고 거창하게 이름 붙였지만, 사실 주사위 오브젝트를 공중에 굴려주기만 하면 끝일거 같네요 ㅎ-ㅎ

필요한것들에 대해서 생각해보면

 

1. 주사위 오브젝트

2. 주사위를 굴리기위한 방법

3. 주사위의 숫자를 판별하는 방법

 

이렇게 3가지만 준비해주면 될 것 같습니다. 

 

 

 

가장 먼저 주사위 오브젝트는 아래의 에셋스토어에서 무료 오브젝트를 사용해 보았습니다.

 

Collection Dice set for role-playing games | 3D 주변환경 | Unity Asset Store

Elevate your workflow with the Collection Dice set for role-playing games asset from Armor and Rum. Find this & other 주변환경 options on the Unity Asset Store.

assetstore.unity.com

 

 

위의 오브젝트를 이제 굴리기 위한 방법에 대해서 생각해 봅시다. 

음... 생각해보면 유니티에서 Rigidbody를 이용하면 중력을 통해 그냥 주사위를 굴릴수 있을것 같습니다....

 

하지만! 단순히 위에서 떨구는 것 보다는

약간 자연스럽게 떨어지면 다시 위로 던져올려 회전하며 떨어지도록! 만들어보았습니다.

 

 

 

 

그럼 먼저 주사위를 굴리는 코드!

 

public class DiceScript : MonoBehaviour {

	static Rigidbody rb;
	public static Vector3 diceVelocity;


	private int[] angles = {0, 90, 180, 270, 360 };

	void Start () {
		rb = GetComponent<Rigidbody> ();
	}
    
	void Update () {
		diceVelocity = rb.velocity; // 움직임이 있는지 확인하기 위한 변수
	}
    
	public void DiceRoll()
    {
    // 회전 랜덤 변수
		float dirX = Random.Range(0, 3000);
		float dirY = Random.Range(0, 3000);
		float dirZ = Random.Range(0, 3000);
        
		// 초기 회전값 (랜덤 부여)
		Quaternion currentRotation = transform.localRotation;
		float randomIndex_x = Random.Range(0, angles.Length);
		float randomIndex_z = Random.Range(0, angles.Length);
        
        // 초기 위치와 회전 초기화
		transform.localPosition = new Vector3(0, 0, 0);
		
        transform.localRotation = Quaternion.Euler(angles[(int)randomIndex_x], currentRotation.eulerAngles.y, angles[(int)randomIndex_z]);
// 윗 방향으로 힘을 가해 공중에 띄우면서, 랜덤한 방향으로 회전
		float ForceRand = Random.Range(200, 300);
		rb.AddForce(Vector3.up * ForceRand);
		rb.AddTorque(new Vector3(dirX, dirY, dirZ), ForceMode.VelocityChange); // 
	}
    
    ...

 

웹상에 많은 주사위 코드들이 있어 참고하였지만,

그대로 실행하니 왜인지 모르겠으나... 같은 면만 나오는...

 

그래서! 좀 더 랜덤한 값을 위해 수정을 진행 했습니다. 

 

가장 먼저 초기 회전 값에 대한 값을 랜덤하게 구성해 주었고,

AddTorque를 이용해서 큐브를 랜덤한 방향으로 힘을 주어 회전 시켜 주었습니다. 

 

주사위 굴리는 부분은 끝! 

 

 

 

그럼 이제 굴린 다이스의 숫자를 출력하게끔 만들어 줍시다. 

 

코드는 아래처럼!

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

using UnityEngine.UI;
using TMPro; // 네임스페이스

public class DiceCheckZoneScript : MonoBehaviour {

	Vector3 diceVelocity;
	public TextMeshPro text;

	// Update is called once per frame
	void FixedUpdate () {
		diceVelocity = DiceScript.diceVelocity;
	}

	void OnTriggerStay(Collider col)
	{
		if (diceVelocity.x == 0f && diceVelocity.y == 0f && diceVelocity.z == 0f)
		{
			switch (col.gameObject.name) {
				case "1":
					text.text = "1";
					break;
				case "2":
					text.text = "2";
					break;
				case "3":
					text.text = "3";
					break;
				case "4":
					text.text = "4";
					break;
				case "5":
					text.text = "5";
					break;
				case "6":
					text.text = "6";
					break;
               }    
           }        
}

 

 

주사위 체크존을 만들고, 체크존에서 더이상의 움직임이 없을때,

바닥면에 붙어있는 면을 보고 주사위의 값을 출력해주는 코드입니다. 

 

 

 

위 코드가 동작하기 위해서는 다이스 오브젝트를 열어 아래처럼 구성해 주어야합니다.  

코드에서 name값을 통해 주사위의 값을 출력하므로, 각 주사위의 면 위에 반대편에 있는 숫자로 이름을 지정해줍시다.

 

 

 

 

 

 

여기까지가 끝...! 

생각보다 단순했던 기능이였습니다.

 

 

 

 

 

결과는 아래처럼!

 

 

 

 

 

 

 

 

틀린점이 있다면 댓 달아주세요!

 

 

 

 

댓글