Raspberlyのブログ

Raspberlyのブログ

Unityネタをメインとした技術系ブログです。にゃんこ大戦争や日常なども。そろそろブログタイトル決めたい

【メタ演出】Windowsのメッセージボックスを出す【Unity】

今回はUnityネタをやっていきます。
ゲームでたまに見るメタ演出を再現する試みで、WindowsのメッセージボックスをUnityから出してみます。

 

メタ演出をやろうと思ったきっかけ

現在Steamで開催中のサマーセールで面白いゲームを見つけました。その名も「OneShot

こちらは斬新な演出が特徴のゲームでメタ演出が盛り込まれています。
プレイ中も「これUnityでできるのかなぁ」といろいろ考えていました。
そこで今回は、ゲーム内の序盤から使われているメッセージボックスをUnityで出してみます

 

※この記事にOneShotのネタバレは含んでいません。

 

 

 

メタ演出とは

いわゆるメタフィクションのことを指します。
簡単に表すとゲーム内で「これはゲームである」ことを表現することです。
ゲームキャラクターが、自分がNPCであることを自覚していたり、第四の壁を越えようとしてくるなど。

おもしろい演出ができる一方、うざがられたりするので全てのゲームで使える演出ではありません

今回扱うメッセージボックスは、
ゲームの主人公ではなく画面の前にいるプレイヤーに直接メッセージを伝えるために使われますね。

 

 

開発環境

Unity 2019.4.0f1
Windows10

 

 

下準備

調べてみたところ、System.Windows.Forms.dllを使うと簡単にメッセージボックスを出せるそうです。
さっそくやってみます。

DLLを探す

C:Windows/Microsoft.NET/Framework64/vX.X/System.Windows.Forms.dll」を探します。

f:id:Raspberly:20200703003324p:plain

PCによって違うと思いますが私はこちらを。

f:id:Raspberly:20200703015855p:plain

 

DLLをPluginsフォルダに格納する

Assets/Pluginsフォルダを作り、そこにSystem.WIndows.Forms.dllを格納します。

f:id:Raspberly:20200703022717p:plain

 

usingに記述

Scriptに「using System.Windows.Forms;」を記述します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Windows.Forms;

public class MsgBox : MonoBehaviour
{
------

 これで使う準備は完了です。

 

 

 

 

メッセージボックスを出す

ここからが本題です。下準備はできたのでメッセージボックスを出していきます。
下記のOpen関数をStart()やOnClick()で呼んであげましょう

最もシンプルなメッセージボックス

テキスト本文が表示され、OKボタンがあるだけの簡単なものです。
OKボタンを押すとそのまま終わります。

    public void Open()
    {
        MessageBox.Show
        (
            "メッセージ"
        );
    }

f:id:Raspberly:20200703224317p:plain

 

 

 

 

キャプション付きメッセージボックス

キャプション(タイトル)がついたメッセージボックスを作ります。
やることは変わらず、MessageBox.Showに第二引数を足すだけです。

    public void Open()
    {
        MessageBox.Show
        (
            "メッセージ",
            "タイトル"
        );
    }

 

f:id:Raspberly:20200703222702p:plain

 

 

 

表示するボタンを変える

表示するボタンを変えてみます。
第三引数にMessageBoxButtonsを追加します。

    public void Open()
    {
        MessageBox.Show
        (
            "メッセージ",
            "タイトル",
            MessageBoxButtons.OK
        );

デフォルトは「OK」です。

f:id:Raspberly:20200703222702p:plain

このMessageBoxButtonsは全部で6種類あります。
自由に組み替えられるものではなく、形式が決まっています。

f:id:Raspberly:20200703225809p:plain

MessageBoxButtons.OKCancel

f:id:Raspberly:20200703230332p:plain

MessageBoxButtons.AbortRetryIgnore

f:id:Raspberly:20200703225947p:plain

MessageBoxButtons.YesNoCancel

f:id:Raspberly:20200703230443p:plain

MessageBoxButtons.YesNo

f:id:Raspberly:20200703230518p:plain

MessageBoxButtons.RetryCancel

f:id:Raspberly:20200703230548p:plain

 

 

 

アイコンを表示する

アイコンを表示してみます。

第四引数にMessageBoxIconを追加します。

    public void Open()
    {
        MessageBox.Show
        (
            "メッセージ",
            "タイトル",
            MessageBoxButtons.OK,
            MessageBoxIcon.None
        );
    }

 デフォルトは「None」です。

f:id:Raspberly:20200703222702p:plain

MessageBoxIconは全9種類ある・・・かと思いきや実は5種類です。

f:id:Raspberly:20200703231200p:plain

MessageBoxIconの定義を見てみるとこんな感じ。
実は同じアイコンが使いまわされています。

namespace System.Windows.Forms
{
    public enum MessageBoxIcon
    {
        None = 0,
        Hand = 16,
        Stop = 16,
        Error = 16,
        Question = 32,
        Exclamation = 48,
        Warning = 48,
        Asterisk = 64,
        Information = 64
    }
}

 

MessageBoxIcon.Hand .Stop .Error

f:id:Raspberly:20200703231341p:plain

MessageBoxIcon.Question

f:id:Raspberly:20200703232326p:plain

MessageBoxIcon.Exclamation .Warning

f:id:Raspberly:20200703232349p:plain

MessageBoxIcon.Asterisk .Infomation

f:id:Raspberly:20200703232140p:plain

 

 

 

 

 

押されたボタンに応じて処理をする

押された結果は、 MessageBox.ShowからDialogResultとして取得できます。
ここではresultに値を格納しています。

    public void Open()
    {
        var result = MessageBox.Show
         (
             "メッセージ",
             "タイトル",
             MessageBoxButtons.AbortRetryIgnore,
             MessageBoxIcon.None
         );

         switch(result){
            case DialogResult.None:
                Debug.Log("基本呼ばれないと思う これいる?");
                break;
            case DialogResult.OK:
                Debug.Log("OKボタンが押された");
                break;
            case DialogResult.Cancel:
                Debug.Log("Cancelボタンが押された");
                break;
            case DialogResult.Abort:
                Debug.Log("Abortボタンが押された");
                break;
            case DialogResult.Retry:
                Debug.Log("Retryボタンが押された");
                break;
            case DialogResult.Ignore:
                Debug.Log("Ignoreボタンが押された");
                break;
            case DialogResult.Yes:
                Debug.Log("Yesボタンが押された");
                break;
            case DialogResult.No:
                Debug.Log("Noボタンが押された");
                break;
        }
    }

 

 

閉じるボタンを押すとどうなるの?

閉じるボタンを押すと何が通知されるのでしょうか?
これはMessageBoxButtonsによって変わります

f:id:Raspberly:20200703234400p:plain

MessageBoxButtons.OKの場合は閉じてもOKが押されたと判定されます
MessageBoxButtons.YesCancelの場合はCancelが押されたと判定されます
MessageBoxButtons.YesNoCancelの場合はCancelが押されたと判定されます
MessageBoxButtons.RetryCancelの場合はCancelが押されたと判定されます

 

MessageBoxButtons.AbortRetryIgnore.YesNoの場合はそもそも閉じれない

f:id:Raspberly:20200703225947p:plain

f:id:Raspberly:20200703230518p:plain

 

全部触ったわけではありませんが、MessageBox.Showはオーバーロードが20個もあるのでいろいろできそう。

 

 

 

 

PCのユーザーネームを取得

次は少し変わった演出、PCのユーザーネームを取得しメッセージボックスで表示してみます。
本名を登録している人はそんなにいないと思いますが、初見の人はびっくりするかも。
ユーザーネームは「Environment.UserName」で取得できます。

    public void Open()
    {
        MessageBox.Show
         (
             "やぁ  " + Environment.UserName + "  見てるかい?"
         );
    }

 

f:id:Raspberly:20200703235808p:plain

 

 

 

まとめ

・System.WIndows.Forms.dllをインポートするとメッセージボックスを出せる
・タイトルとメッセージは自由に設定できるがボタンはある程度固定
・PCのユーザーネームも取れる

 

 

ちなみにSteamサマーセールは7月10日までやっているようなので気になる方は要チェック!
その4日後の7月14日はデスストランディングがSteamでリリースされるのでそっちも気になる・・・

 

 

 

 

参考資料

コガネブログさんの方では、EditorフォルダにDLLを格納していますがうまくいきませんでした。
Alpaca Tech Blogさんの方ではPluginsフォルダに格納していまして、こちらだと動作しました。
もしかしたら環境によって違うのかも。

baba-s.hatenablog.com

alpacatech.hateblo.jp

 

w.atwiki.jp

 

 

Unity外でC#を使ったことがそんなにないのでいろいろタメになったけども、
よくよく考えたらUnityというよりも.NET Frameworkの記事だこれ・・・
C#に詳しい方から見たら内容が初歩的すぎてつまらなかったかも・・・

 

 

間違っている所、わかりにくい所がありましたらコメントまでお願いします。