5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

レベルに応じてゲームの難易度を変える実装

Last updated at Posted at 2019-09-28

#UNITYでゲーム作るときに難易度調整するためのデータ作りについて
ScriptableObjectを使います。
このような数値調整をUNITY上でやりたい場合のやり方です。
スクリーンショット 2019-09-29 0.19.43.png

上記の画像にあるデータは、いくつのモノを壊したら、次のレベルに進めるか、そのレベルの難易度はどのぐらいかといったデータを表しています。

#どんなゲームを作った際に使ったものか
まず、Garbagersというゲームを作ったのですが、その際の難易度などに関するデータ作りに関して作ったものです。
https://mosq.xyz/Garbagers/

#まず基本となるデータ
スリーマッチパズルゲームで、多くのゴミを壊すと次のレベルに進み少しづつ難しくなるゲームでした。テトリスのように。
なので、いくつ壊したら次のレベルに進めるか(int)、ゴミが出現するインターバル時間(float)を設定できるようにしました。(GVLevelInfo)
さらに、ゴミがつっかえて溜まってくるとゴミが速く出るようにしました。
横、縦への速度、回転速度、インターバルを指定できるようにしました。(GVPressureInfo)

LevelClasses.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[Serializable]
public class GVLevelInfo
{
	public int NextBlockCount;
	public float SpawnInterval = 0f;
}

[Serializable]
public class GVPressureInfo
{
	public float HorizontalSpeed;
	public float VerticalSpeed;
	public float AngularSpeed;
	public float Interval;
}

[Serializable]アトリビュートをつけておく必要があります。
これらをレベルごとに用意するためリストにします。
それとScriptableObjectにして、UNITY上に置けるデータにします。
(全部publicで書いちゃってますが、UNITYでは[SerializeField]アトリビュートをつけても、シリアライズされます)

#GVLevelInfoのリスト化したScriptableObjectを作る
class宣言以降、三行だけが重要であとはおまけの関数です。

GVLevelInfoList.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class GVLevelInfoList : ScriptableObject
{
	public List<GVLevelInfo> List = new List<GVLevelInfo>();

	public int GetLevel(int breakCount)
	{
		int level = 0;
		foreach(var v in List)
		{
			if (v.NextBlockCount <= breakCount)
			{
				++level;
				continue;
			}
			break;
		}
		return level;
	}

	public float ToNextRatio(int level,int breakCount)
	{
		int prevCount = 0;		
		if (0 <= level-1)
		{
			prevCount = List[level-1].NextBlockCount;
		}
		if (level < List.Count)
		{
			var v = List[level];
			return (breakCount - prevCount) / (float)(v.NextBlockCount-prevCount);
		}
		return 1f;
	}
}

GVPressureInfoのリストも同様に作ります。

GVPressureInfoList.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GVPressureInfoList : ScriptableObject
{
	public List<GVPressureInfo> List = new List<GVPressureInfo>();

	public GVPressureInfo GetPressure(int pressure)
	{
		return List[Mathf.Clamp(pressure,0,List.Count-1)];
	}
}

ということで、データ構造としては用意できました。
あとは、このデータをUNITYプロジェクトの中に追加する方法です。

#Editorフォルダを作ります
UNITYにおいて、Editorフォルダは特別な名前です。
ここに置かれたスクリプトファイルは、UNITYエディタ上でのみ利用され、ビルドして出力したアプリなどには含まれません。
エディタ上で、データを作ったりする際に使います。

LevelInfoMenu.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public static class LevelInfoMenu
{
	[MenuItem ("Create/CreateGVLevelInfoList")]
	static void CreateGVLevelInfoList ()
	{
		var asset = ScriptableObject.CreateInstance<GVLevelInfoList> ();

		AssetDatabase.CreateAsset (asset, "Assets/LevelInfoList.asset");
		AssetDatabase.Refresh ();
	}

	[MenuItem ("Create/CreateGVPressureInfoList")]
	static void CreatePressureInfoList ()
	{
		var asset = ScriptableObject.CreateInstance<GVPressureInfoList> ();

		AssetDatabase.CreateAsset (asset, "Assets/PressureInfoList.asset");
		AssetDatabase.Refresh ();
	}
}

このスクリプトを書くと、UNITYのトップメニューにCreateが追加されています。
実行すると、指定されたパスの場所にデータが追加されます。
インスペクター上で、データを編集することが可能です。

保存場所を選べるようにしたい場合は、下記のような関数を使います。
https://docs.unity3d.com/ja/current/ScriptReference/EditorUtility.SaveFilePanel.html
→プロジェクト内に保存する場合は、こっちでした。
https://docs.unity3d.com/ScriptReference/EditorUtility.SaveFilePanelInProject.html

スクリーンショット 2019-09-29 0.19.43.png

スクリーンショット 2019-09-29 0.31.12.png

これをゲームで使っていきます。

#実際に使う
普通に、MonoBehaviourにインスペクタから設定することができます。

GarbagersSystem.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GarbagersSystem : MonoBehaviour {
	[SerializeField]
	LevelInfoUI _levelInfo;
	[SerializeField]
	GVPressureInfoList _pressureInfo;
...

インスペクタに先ほどのメニューから作ったデータをドラッグ&ドロップすればデータが入るので、使いましょう。

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?