1
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.

インベントリでアイテムプレビューを表示したい!

Last updated at Posted at 2022-01-03

タイトルの通りです。解説している記事が見つからなかったので作ります。

編集 2022/4/12

コルーチンを使用しない簡単な方法による実装。

概要

Unityでゲームを作っているとインベントリなどで「アイテムプレビュー」を表示したいときってあると思います。
しかし、UIに3Dオブジェクトを表示させる方法が分からないかったりするのではないでしょうか。

この記事ではRenderTextureを用いることでアイテムの3Dオブジェクトを画像に変換し、RawImageというUI要素に設定することで3DオブジェクトをUIとして表示する方法について紹介します。

準備

プレビュー用の親オブジェクトを作る

まずはプレビューを作るための環境を準備しましょう
まずヒエラルキー左上の+ボタン>Create Emptyで親となるオブジェクトを作成します。
名前はてきとうに「PreviewShowroom」などにしてください。

アイコン撮影用の3Dモデル、カメラを配置

次にそのオブジェクトを右クリック>Cameraでカメラを配置しましょう。
このカメラがプレビューを表示するためのカメラになります。
カメラを配置したら、てきとうな3Dオブジェクトをカメラに映るような形で配置します。
3Dオブジェクトは2つ以上用意し、「ItemA」「ItemB」という名前にしてください。のちのち役に立ちます。
Screenshot 2022-04-12 21-03-42.png

カメラコンポーネントの変更

カメラコンポーネントをアイコン撮影用に変更します。
背景はいらないのでClear FlagsDepth onlyにします。これを行うことで3Dオブジェクトのみが描画されるようになります。

レイヤーの作成

先ほど作成したカメラで複数の3Dオブジェクトの撮影を行うのですが、そのままではアイテムAのアイコンに関係ないアイテムBのオブジェクトが写りこんでしまいます
カメラに撮影するレイヤーに設定することでアイテム一つづつの撮影が可能になります。
具体的な例で示すと、アイテムAを撮影するときはアイテムAを撮影レイヤーに、アイテムBをそれ以外のレイヤーに。
アイテムBを撮影するときはアイテムBを撮影レイヤーに、アイテムAをそれ以外のレイヤーに設定することで、カメラに特定のアイテムのみを写すことができます。
レイヤーは右上のLyaer>Add Layerから増やすことができます。空いている部分にPreviewレイヤーを追加しましょう。
Screenshot 2022-04-12 20-31-24.png
作成したらカメラに撮影レイヤーを設定します。Culling Maskを一度Nothingにした後、Previewを選択しましょう。
最終的なカメラコンポーネントの値はこのようになります。
Screenshot 2022-04-12 20-58-06.png

アイコンとなるUIの作成

ヒエラルキー左上の+ボタン>UI>Raw Imageを作成しましょう。
UnityはUIはCanvasというオブジェクトの子として作成され、めちゃめちゃでかい空間に配置されます。まぁそういうものだと思ってください。ヒエラルキー上でオブジェクトをダブルクリックすると位置が分かるので、それで調整してください。

これで準備は完了

スクリプト

プロジェクトウィンドウ(ファイルがあるウィンドウ)で右クリック>Create>C# Scriptでスクリプトを作成し、名前を「Preview」にしてください(名前が一致しないと動きません)。ファイル内容は全て消し、以下のコードをコピペ(Shift+A, Ctrl+X, Ctrl+C, Ctrl+V)してください。

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

public class Preview : MonoBehaviour
{
    [SerializeField] ItemType itemToBeIcon = ItemType.ItemA;
    [SerializeField] GameObject itemShowroom;
    [SerializeField] List<RawImage> icons = new List<RawImage>();

    // Start is called before the first frame update
    void Start()
    {
        icons[0].texture = GetItemIcon(itemToBeIcon);
    }

    RenderTexture GetItemIcon(ItemType item)
    {
        const int previewLayer = 3;
        Camera previewCam = itemShowroom.transform.Find("Camera").GetComponent<Camera>();
        Transform tryItem = itemShowroom.transform.Find(item.ToString());
        if (tryItem == null) return null;
        RenderTexture icon = new RenderTexture(250, 250, 24);
        tryItem.gameObject.layer = previewLayer;
        previewCam.targetTexture = icon;
        previewCam.Render();
        tryItem.gameObject.layer = 0;
        return icon;
    }

    public enum ItemType
    {
        ItemA,
        ItemB,
        ItemC,
    }
}

再生

てきとうにScriptと言う名前のGameObjectをつくり、Previewスクリプトをドラッグアンドドロップでアタッチします。
次に変数Item Showroomに「ItemShowroom」オブジェクト、Iconsに先ほど作成したRawImageのiconをドラッグアンドドロップします。
再生すると次のようになります。

ezgif.com-gif-maker.gif

完成!

おつかれさまでした。あとは頑張ってください。
だいたいどうしたらいいかは掴めるはずです。

動かない場合

  • ヒエラルキーの親子関係が間違ってませんか?
  • スクリプトはアタッチしましたか?
  • スクリプトの2つの変数に作成したオブジェクトを割り当てましたか?
  • レイヤーの設定はできていますか?
  • カメラコンポーネントは正しく設定されていますか?
1
2
3

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
1
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?