3
2

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 1 year has passed since last update.

UnityでScriptableObjectを使ってみた、NPOIを使用してExcelデータを読み込んでみた

Posted at

2022.4.27 9日目 昨日の投稿忘れていたので、再開です。

目標

今回はUnityのScriptableObjectというものを使ってマスタデータを作成していきます。

参考資料

https://moon-bear.com/2021/01/02/use-scriptable-object/
https://ymgsapo.com/2021/03/01/unity-scriptable-object/
https://www.urablog.xyz/entry/2017/03/28/235739
https://hiyotama.hatenablog.com/entry/2019/08/27/110000

どんな場面で使用するものなのか

・共通データの管理

→敵キャラの最大HPなど、共通のデータを持つものに対して使用できる

・シーンをまたぐデータの保持

→シーンをまたぐデータを保持したいときは、「DontDestroyOnLoadしたゲームオブジェクトに値を持たせる」方法が見受けられるそうです。
一方で、このような場合にはScriptableObjectを使うと便利です。理由は、
・ScriptableObjectはどのシーンからでも参照することができる
(ゲームオブジェクトのようにシーンに依存しない)
・ScriptableObjectはあらかじめインスペクターに登録することができる(シリアライズが可能)

・イベントの管理

実践

では実際にUnityでScriptableObjectを使用していきます。

assetファイルの作成

どのようなデータを持たせるのかを記載したスクリプトを書いていきます。

//ScriptableObject作成

using System;

//ScriptableObject作成

[CreateAssetMenu( fileName = "MissionInfo")]
public class ScriptableTest: ScriptableObject {
    public List<Mission> missionList = new List<Mission>();
}

[Serializable]
public class Mission {
    //ミッションID
    public int id;
    //次のミッション
    public int nextMissionId;
    //ミッション内容
    public string missionDetail;
}

ここからはスクリプトの説明です。

[CreateAssetMenu( fileName = "MissionInfo")]

スクリプトの説明後にある、Projectを右クリック~ の動作を実現できるのがこの一文らしいです。この一文を追加することで右クリック>Create にスクリプト名(このタブ名は変更可能、とのこと!)が追加され、assetファイルを作成することができるそうです。

public class ScriptableTest: ScriptableObject {

次に、「ScriptableObject」を継承します。
(要は使えるようにします。(私の解釈で申し訳ありません><。)

[Serializable]
public class Mission {

参考にさせていただいたサイトに、[Serializable]とあり、なんぞやと思ったので調べてみると、「ここでのシリアライズは「直列化」と訳され、メインメモリ上に存在しているオブジェクトなどのデータを文字列やバイト列に変換することを指します。これには、ファイルとして保存したり、ネットワークで送受信したりできるようになるというメリットがあります。

逆に、シリアライズされたデータをもとの状態に復元することをデシリアライズと言います。」 だそうです。

クラスの中は、含めたいデータを変数として宣言しておきます!

説明は以上です。

スクリプトを作成したら、Projectを右クリック>Create>作成したスクリプト名 と選択していきます。
bandicam 2022-04-27 12-21-45-101.jpg

すると以下のようなassetファイルが作成されます
bandicam 2022-04-27 14-41-40-334.jpg

これでScriptableObjectの作成はできたかと思います。

別のスクリプト上での呼び出し方

方法はいくつかあるそうですが一番オーソドックスな方法で行きます。

単純にSerializeFieldでInspecterにアタッチして使用する方法です。

[SerializeField] private ScriptableTest m_infomation = null;

(ただアタッチして使用するのは、色々な場所で参照することになると大変そうですね…)

実際に呼び出してみた↓

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

public class MasterDataController: MonoBehaviour {

    [SerializeField] private ScriptableTest m_infomation = null;

    // Start is called before the first frame update
    void Start() {
        foreach( var mission in m_infomation.missionList ) {
            Debug.Log( "ID:" + mission.id + " " + "mission:" + mission.missionDetail + " " + "NextMissionID:" + mission.nextMissionId );
        }
        
    }

    // Update is called once per frame
    void Update() {

    }
}

ScriptableObjectのinspector↓
bandicam 2022-04-27 14-56-45-780.jpg

実行結果↓
bandicam 2022-04-27 14-56-34-136.jpg

となりました。かなり簡単に呼び出しができました。

Excelからデータの読み込み

まずはExcelからデータを読み込んでみます。
今回はNPOIを使用していきます。

準備

NPOIのインポートをしていきます。
ダウンロードすると、拡張子が「.nupkg」となっていると思います。そのままだと解凍できないので、「.zip」とすると解凍できるようになります)

(解凍したフォルダ内lib/net45内のもの全て)

(解凍したフォルダ内lib/net40内のもの全て)

(解凍したフォルダ内lib/net45内のもの全て)

入れると以下のようになっているはずです。
(今回はAsset下にEditer/npoiフォルダを作成して、そこにインポートしています)
bandicam 2022-04-27 17-42-22-993.jpg

これで準備完了です。

Excelデータの読み込み

こちらを参考にさせていただきました。

using System.IO;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using NPOI.HSSF.Util;
using NPOI.SS.Util;
using UnityEngine;

public class ExcelToScriptableObject: MonoBehaviour {

    // Start is called before the first frame update
    void Start() {

        if( !File.Exists( @"C:\StudyUnity\ScriptableObjectStudy\Assets\Script\MissionMasterData.xls" ) ) {
            return;
        }
        //Excelブックを開く
        IWorkbook book = WorkbookFactory.Create( @"C:\StudyUnity\ScriptableObjectStudy\Assets\Script\MissionMasterData.xls" );

        CellReference reference = new CellReference( "B5" );
        IRow row = book.GetSheetAt( 0 ).GetRow( reference.Col );
        ICell cell = row.GetCell( reference.Col );
        var str = cell.StringCellValue;

        Debug.Log( str );

    }

まずは試しに↑のようなコードを書いてみました。(読み込みのみしてみました)A1形式で読み込みをしております。

以下コードの説明です。

using System.IO;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using NPOI.HSSF.Util;
using NPOI.SS.Util;
using UnityEngine;

必要なusingディレクティブを追加します。

if( !File.Exists( @"C:\StudyUnity\ScriptableObjectStudy\Assets\Script\MissionMasterData.xls" ) ) {
   return;
}

ここで読み込むExcelデータがあるかどうかを検索して、無ければ関数を抜ける処理をしています。(必要ないとは思いますが念のためかいてあります)

IWorkbook book = WorkbookFactory.Create( @"C:\StudyUnity\ScriptableObjectStudy\Assets\Script\MissionMasterData.xls" );

読み込むExcelデータを開きます。

CellReference reference = new CellReference( "B5" );

A1形式で読み込むセルを指定します。

IRow row = book.GetSheetAt( 0 ).GetRow( reference.Col );
ICell cell = row.GetCell( reference.Col );

book.GetSheetAt( 0 )→どのシートを指定するか
GetRow( reference.Col )→どのセルか
ICell cell = row.GetCell( reference.Col );→セルの情報を読み込み

var str = cell.StringCellValue;

cell.StringCellValue 今回はStringを読み込んだのでこのように書きましたが、どのような値を読み込むかで変わってくるようです。

これを実行すると以下のようになります。(MasterDataに使用するExcelによって変わります)
bandicam 2022-04-27 18-01-12-536.jpg

明日は続きをやっていきます。

3
2
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
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?