フォントファイルをダウンロードしたらttfとotfの2つ入っていた話

えにあです。

ボードゲームを作成するにあたり、タイトル画面を作ろうとしています。 ゲームタイトルをデフォルトフォントのArialで描いたのでは味気ないですよね。

そこで、フリーのフォントを探していたところ、Phenomenaフォントが気に入りました! www.fontfabric.com

このサイトからフォントをダウンロードしたところ、.ttfと.otfの二つのファイルが含まれていました。 私はどちらを使えばよいのでしょう、というのが今回の話です。

.ttfと.otf

ttfはTrue Type Fontの略で、otfはOpen Type Fontの略です。

TrueTypeFontとOpernTypeFontの違いは下記のサイトに詳しく載っています。 fontnavi.jp

Unity自体はttfとotfのどちらもサポートしています。 タイトル文字に使うだけなれば、正直どちらでも問題ないと思われます。 私はttfファイルのほうを利用しました。

フォントのインポート

ttfファイルそのままではUnityで使うことができず、フォントをUnityのアセットに変換してあげる必要があります。

トップメニューから「Window」->「TextMeshPro」->「FontAssetCreator」を選択します。 f:id:enia:20210329102939p:plain

以下のウィンドウが起動するので、SourceFontFileに利用したいフォントのttfファイル、またはotfファイルを指定します。 Atlas Resolutionは大きい数字にしておいたほうが良いらしいですが、意味はよくわかってません。

ここまで設定したら、Generate Font Atlasを押下します。 f:id:enia:20210329102415p:plain

少し待つと、Save Asが押せるようになるので、任意の名前で保存しましょう。 私の場合、Assets/Resources/Fontsの下に保存しました。 f:id:enia:20210329102535p:plain

以下のようにフォントのアセットファイルが作成されています。 f:id:enia:20210329103156p:plain

Unityでシーン遷移時に画面が暗くなる問題への対応

SceneManager.LoadSceneを使って、別のシーンに移動した際に、 移動後のシーンで画面が暗くなってしまうの対処方法です。

移動後のシーンを開いている状態で、「トップメニュー」->「Rendering」->「Lighting」を選択します。
f:id:enia:20210328084145p:plain

開いたウィンドウで、「Sceneタブ」の下部にある「AutoGenerate」のチェックを外した状態で、「Gemerate Lighting」をクリックします。 f:id:enia:20210328085251p:plain

これで変更後のウィンドウでも画面が明るくなります。

猫でもわかるUnity入門(第22回 Photon PUN2を使ったマルチプレイゲームチュートリアル 最終回)

f:id:enia:20210228230354p:plain えにあです。 前回に続きUnit + Photon Pun2を使ったオンラインマルチプレイゲーム作成のチュートリアルを進めていきます。 二つのアプリで

スクリプトのアタッチ

シーン上に作成した空のオブジェクト「PhotonController」に、前回作成したスクリプト「RandomMatchMaker」をアタッチします。 アタッチの方法はスクリプトをオブジェクトにドラッグアンドドロップすればOKです。

PhotonControllerをインスペクターで表示します。 RandomMatchMakerスクリプトコンポーネントとして追加されています。 スクリプトで定義したPhotonObjectプロパティが表示されていますね。 ここに、Unityちゃんのプレハブをアタッチします。プレハブの方をアタッチしますので、プロジェクトビューから「Assets」->「Demos」->「Resources」->「unitychan_dynamic_locomotion」を選択してアタッチしてください。 f:id:enia:20210312084122p:plain

この状態で一度実行してみましょう。 コンソールに大量のエラーが表示されると思います。 f:id:enia:20210312084754p:plain

NullReferenceException: Object reference not set to an instance of an object
UnityChan.ThirdPersonCamera.setCameraPositionNormalView () (at Assets/unity-chan!/Unity-chan! Model/Scripts/ThirdPersonCamera.cs:57)
UnityChan.ThirdPersonCamera.FixedUpdate () (at Assets/unity-chan!/Unity-chan! Model/Scripts/ThirdPersonCamera.cs:49)

このエラーをクリックして、該当のソースを表示します。 ThirdPersoncCamera.csの、setCameraPositionNormalViewメソッドで、starndardPosがnullになっていることが原因のようです。

void setCameraPositionNormalView ()
{
    if (bQuickSwitch == false) {
        // the camera to standard position and direction
        // ★starndardPosがnullになっている。
        transform.position = Vector3.Lerp (transform.position, standardPos.position, Time.fixedDeltaTime * smooth); 
        transform.forward = Vector3.Lerp (transform.forward, standardPos.forward, Time.fixedDeltaTime * smooth);
    } else {
        // the camera to standard position and direction / Quick Change
        transform.position = standardPos.position;  
        transform.forward = standardPos.forward;
        bQuickSwitch = false;
    }
}

standardPosを設定している箇所を見るとstartメソッドの中でGameObject.Findしていることが分かります。 Unityちゃんをプレハブ化したことで、CamPosが見つからなくなったことが原因のようです。

void Start ()
{
    // 各参照の初期化
    standardPos = GameObject.Find ("CamPos").transform;

    if (GameObject.Find ("FrontPos"))
        frontPos = GameObject.Find ("FrontPos").transform;

    if (GameObject.Find ("JumpPos"))
        jumpPos = GameObject.Find ("JumpPos").transform;

    //カメラをスタートする
    transform.position = standardPos.position;  
    transform.forward = standardPos.forward;    
}

このThirdPersonCameraスクリプトはMain Cameraにアタッチされていて、起動するとすぐにStartメソッドがコールされ、CamPosオブジェクトを探しに行ってしまいます。

今回はサーバに接続されたタイミングでUnityちゃんのインスタンスを作成しているので、そのタイミングでThirdPersonCameraを有効にすればこのエラーは防げそうです。

まず、Main Cameraをインスペクターで開いてThridPersonCameraをオフにします。 これで実行後すぐにこのスクリプトが呼ばれることを防げます。 f:id:enia:20210312085653p:plain

次に、Unityちゃんのインスタンスを作成したタイミングでThridPersonCameraをオンにします。
前回作成した、RandomMatchMakerスクリプトの、OnJoinedRoomコールバックを再度確認してみましょう。 実は、既に入室が完了したタイミングでUnityちゃんのインスタンスを作成し、カメラをオンにするように実装されています。

    public override void OnJoinedRoom()
    {
        PhotonNetwork.Instantiate(
            PhotonObject.name,
            new Vector3(0f, 1f, 0f),
            Quaternion.identity,
            0
        );
        GameObject mainCamera = GameObject.FindWithTag("MainCamera");
        mainCamera.GetComponent<UnityChan.ThirdPersonCamera>().enabled = true;
    }

もう一度実行して、エラーが発生しないことを確認しておきましょう。

マルチプレイ準備

マルチプレイのテストをするためには、最低でも二つの環境から同時にアクセスする必要があります。 PC上でアプリを二つ起動するのが最も簡単な方法なのでPC向けにビルドしておきます。 ビルド対象のシーンが追加されていることと、PC向けになっていることを確認して、ビルドボタンを押します。 f:id:enia:20210312090527p:plain

保存場所は任意です私は「プロジェクトルート」->「Builds」->「PUN2_pc」というフォルダを作成して指定しました。 f:id:enia:20210312090946p:plain

ビルドは完了しましたが、コンソールを見ると大量に警告が出ています。 しかし、文を読んでみるとエラーではなく「deprecated」による警告だけのようですので、ここでは無視します。 f:id:enia:20210312091401p:plain

NOTE
チュートリアルではAutoBlink.csで以下のエラーが発生しています。

error CS0234 The tyep or namespace name 'Policy' does not exist in the namespace 'System.Security' 私の環境ではバージョン差異によるものだと思いますがこのエラーは発生しませんでした。
もし発生した場合は公式のyoutubeチュートリアル22:40あたりを見ると解決策が載っています。

それではアプリを二つ起動していきます。 1つは通常通りUnityから実行します。 この時点ではUnityちゃんは一人しか表示されていませんね。

f:id:enia:20210312092301p:plain

次に、エクスプローラで先ほどBuild結果を格納したフォルダに移動し、PUN2.exeを実行します。 二人目のUnityちゃんが登場しましたね! f:id:enia:20210312092637p:plain

オプション

矢印キーで操作できるので少し動かしてみましょう。 プレイヤー1の方で操作をすると、プレイヤー2のUnityちゃんが微妙に動いているように見えます。 次にこの動きを修正していきます。

プロジェクトウィンドウの検索ボックスに「UnityChanControl」と入力し、表示されたUnityChanControlScriptWithRgidBody.csを修正していきます。 f:id:enia:20210312093102p:plain

まず、継承するクラスをMonoBehaiviourから、Photon.Pun.MonoBehaviourPunに変更します。

public class UnityChanControlScriptWithRgidBody : Photon.Pun.MonoBehaviourPun // ★継承クラスの変更

次にFixedUpdateを修正し、プレイヤーの入力が、他のプレイヤーのUnityちゃんに影響を及ぼさないようにしていきます。 修正は先頭に1行追加するだけです。自身の操作の場合だけFixedUpdateが実行されるようになります。

void FixedUpdate ()
{
    if(photonView.IsMine) return;   // ★追加

さあ、再度Buildして試してみましょう。 確かに他のプレイヤーの影響は受けなくなったように見えますが、私の環境では逆に挙動がおかしくなったような気がします。

この3回で、プレイヤー間でネットワークを経由して位置情報などを共有する方法について学ぶことができました。チュートリアルに含まれなかったロビーの使い方や、部屋を指定して入室する方法などは今後実際にアプリを作りながら学んでいこうと思います。 今回はここまで!

猫でもわかるUnity入門(第21回 Photon PUN2を使ったマルチプレイゲーム作成 その2)

f:id:enia:20210228230354p:plain えにあです。 Unity + Photonを使ったオンラインマルチプレイゲームのサンプル作成の第2回を進めていきます。

**目次

Unityちゃんのプレハブ化

まず、Unityちゃんをプレハブ化しておきます。
ヒエラルキービューで「unitychan_dynamic_locomotion」をドラッグし、プロジェクトビューの「Assets」->「Demos」->「Resources」にドロップします。

プレハブの種類は原型プレハブを選択します。
f:id:enia:20210311192922p:plain

ここまでの手順で、Resourcesの下と、Scenesの下にファイルが作られています。
f:id:enia:20210311193026p:plain

プレハブ化したので、シーン上のUnityちゃんは削除します。
f:id:enia:20210311193133p:plain

ここで一度シーンを保存しましょう。
f:id:enia:20210311193320p:plain

UnityちゃんプレハブへのPhotonコンポーネント追加

プロジェクトビューで、プレハブ化した「unitychan_dynamic_locomotion」を選択し、インスペクターで「プレハブを開く」を選択します。
f:id:enia:20210311220632p:plain

コンポーネントを追加」から以下3つのコンポーネントを追加していきます。

  • PhotonView
  • PhotonTransformView
  • PhotonAnimatorView

f:id:enia:20210311221257p:plain

PhotonVIewを追加します。
f:id:enia:20210311221212p:plain

PhotonTransformViewを追加します。
f:id:enia:20210311221117p:plain

PhotonAnimatorViewを追加します。
f:id:enia:20210312080219p:plain

PhotonViewコンポーネントをUnityちゃんにアタッチすることで、Unityちゃんの位置情報などをネットワーク経由での同期対象に含めることが可能になります。

PhotonViewコンポーネントのObservedComponentプロパティを割り当てることでどの情報を同期するかを指定することができます。 Photon TransformView、Photon AnimatorViewが設定されていることを確認してください。Observable SearchがAuto Find Allになっていれば自動で設定されているはずです。 f:id:enia:20210311224004p:plain

PhotonTransformViewコンポーネントをObservedComponentに割り当てることで、transform(位置情報や回転)の同期が可能になります。

PhotonAnimatorViewコンポーネントをObservedComponntに割り当てることで、animatorのパラメータの同期が可能になります。

インスペクターで「Photon Transform View」を開きます。 「Syncrhonize Options」はどのTransform項目をプレイヤー間で同期するかを表しているようです。
「Position」と「Rotation」にチェックが入っていることを確認します。 おそらく、今回のサンプルではスケールは動的に変更されることがないので同期不要ということでしょう。 f:id:enia:20210311224312p:plain

インスペクターで「Photon Animator View」を開きます。 AnimatorViewでは、項目ごとに3つの同期方法を選択できます。

  1. disable(同期しない)
  2. discrete(非連続的 = 一定間隔で同期)
  3. continuous(連続的 = 常に同期)

ここではdiscreteとcontinuousを使って、Synchronize Parametersを以下のように変更します。 f:id:enia:20210311224712p:plain

オンラインマルチプレイスクリプト作成

Photonを使ったオンラインマルチプレイ用のスクリプトを作成していきます。

シーン上に接続スクリプトをアタッチするための空のオブジェクトを作成します。 トップメニューから「ゲームオブジェクト」->「空のオブジェクトを作成」を選択します。「PhotonControlelr」という名前に変更します。
f:id:enia:20210312072125p:plain

作成したオブジェクトにアタッチするためのスクリプトを作成します。 「Assets」->「Demos」->「Scripts」の下に、RandomMatchMakerという名前でC#スクリプトを作成します。
f:id:enia:20210312072753p:plain

次にスクリプトを開いて編集していきます。 今回のサンプルでは部屋は1つしかありません。 プレイヤーがランダムに部屋に入室するメソッドを用いるのですが、部屋が1つしかないため、全員が1つの部屋に入室することになります。

まずusingにPhoton関連のパッケージを追加します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun; // ★追加
using Photon.Realtime; // ★追加

次に、継承元クラスであるMonoBehaiviourをMonoBehaiviourPunCallbacksに変更します。 「イベントが発生した時」というのは、例えば「サーバに接続した時」、「部屋への入室が完了した時」といったものです。

public class RandomMatchMaker : MonoBehaviourPunCallbacks // ★変更

次に、ゲームオブジェクトを設定するためのフィールドを作成しておきます。 このフィールドは後でインスペクターから設定されます。

    // インスペクターから設定
    public GameObject PhotonObject;

次にStartメソッドを修正します。ConnectUsingSettingsメソッドを使うことで、先ほど設定した「PhotonServerSettings」を用いてサーバに接続することができます。

   void Start()
    {
        PhotonNetwork.ConnectUsingSettings();
    }

Updateメソッドは利用しないので削除します。※コメントアウトにしていますが、削除でOKです。

    // void Update()
    // {
        
    // }

次に、MonoBehaviourPunCallbacksクラスが提供する4つのコールバックメソッドをオーバーライドしていきます。

  1. OnConnectedToMaster
  2. OnJoinedLobby
  3. OnJoinRandomFailed
  4. OnJoinedRoom

ではまず、OnConnectedToMasterメソッドをオーバーライドします。このメソッドは、サーバへの接続が完了すると呼ばれるコールバックです。サーバへの接続が完了したら、ランダムで部屋に入室するように実装します。

    public override void OnConnectedToMaster()
    {
        PhotonNetwork.JoinRandomRoom();
    }

次に、OnJoinedLobbyメソッドをオーバーライドします。このメソッドはロビーへの入室が完了した時に呼ばれるコールバックです。今回のサンプルではロビーは使いませんが、ロビーに入室したら即座に部屋に入室するように実装しています。

    public override void OnJoinedLobby()
    {
        PhotonNetwork.JoinRandomRoom();
    }

次に、OnJoinRandomFailedをオーバーライドします。このメソッドは入室に失敗した時に呼ばれるコールバックです。一人目は部屋がないので、確実に入室に失敗します。そのため、このメソッドの中で部屋を作成しています。

部屋を作成するメソッドはCreateRoomです。第1引数にはルーム名を指定します。ルーム名は部屋を識別する場合に使いますが、今回は部屋が1つしかないのでnullを指定しています。

第2引数にはRoomOptionsを渡します。MaxPlayersを指定することで1部屋の最大に員数を制限することができます。

    // 入室に失敗した場合に呼ばれるコールバック
    // 1人目は部屋がないため必ず失敗するので部屋を作成する
    public override void OnJoinRandomFailed(short returnCode, string message)
    {
        RoomOptions roomOptions = new RoomOptions();
        roomOptions.MaxPlayers = 8; // 最大8人まで入室可能
        PhotonNetwork.CreateRoom(null, roomOptions); //第一引数はルーム名
    }

最後に、OnJoinedRoomメソッドをオーバーライドします。このメソッドは入室が完了した時に呼ばれるコールバックです。この後でインスペクターで設定するPhotonObjectプロパティに指定したオブジェクトの名前と、初期位置と回転を渡すことで、サーバ側にオブジェクトを同期します。

後半のカメラについては後ほど説明します。

public override void OnJoinedRoom()
{
    PhotonNetwork.Instantiate(
        PhotonObject.name,
        new Vector3(0f, 1f, 0f),    //ポジション
        Quaternion.identity,    //回転
        0
    );
    GameObject mainCamera = GameObject.FindWithTag("MainCamera");
    mainCamera.GetComponent<UnityChan.ThirdPersonCamera>().enabled = true;
}

スクリプトの修正は以上です。 今回はここまで!

最終的なスクリプトは以下に記載しておきます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;

public class RandomMatchMaker : MonoBehaviourPunCallbacks
{
    // インスペクターから設定
    public GameObject PhotonObject;

    void Start()
    {
        PhotonNetwork.ConnectUsingSettings();
    }

    public override void OnConnectedToMaster()
    {
        PhotonNetwork.JoinRandomRoom();
    }

    public override void OnJoinedLobby()
    {
        PhotonNetwork.JoinRandomRoom();
    }

    public override void OnJoinRandomFailed(short returnCode, string message)
    {
        RoomOptions roomOptions = new RoomOptions();
        roomOptions.MaxPlayers = 8;
        PhotonNetwork.CreateRoom(null, roomOptions);
    }

    public override void OnJoinedRoom()
    {
        PhotonNetwork.Instantiate(
            PhotonObject.name,
            new Vector3(0f, 1f, 0f),
            Quaternion.identity,
            0
        );
        GameObject mainCamera = GameObject.FindWithTag("MainCamera");
        mainCamera.GetComponent<UnityChan.ThirdPersonCamera>().enabled = true;
    }
}

猫でもわかるUnity入門(第20回 Photon PUN2を使ったマルチプレイゲーム作成 その1)

f:id:enia:20210228230354p:plain えにあです。

今回はPhotonを使ったオンラインマルチプレイゲームの作り方を学んでいきます。 この知識を身に着けることで、一つのゲームを二人で同時にプレイして、協力・対戦できるゲームを作ることができるようになります。 全3回くらいになる予定で、今回はその1回目です。

目次

初めに

今回の学習は、以下のPhoton公式のチュートリアルをベースに進めていきます。 www.youtube.com

Photonとは

Photonについて、公式の説明を以下に抜粋しました。 正直、現時点では2つのソリューションの違いが全く分かりませんでしたが進めていけばわかるのでしょう。

Photonはネットワークエンジンであり、マルチプレイでの同期を担うソリューションと、マルチプレイでのコミュニケーションを補助するソリューションの大きく2つを提供します。 用途に応じて、適切なソリューションを選択することができます。

サーバとクライントSDKがセットで提供されており、ルームやロビー機能を含め、マルチプレイを実現するために必要な機能を一通り搭載しているため、ネットワークの実装を簡単に進めることができます。

今回はUnity上で動作する、Photon Unity Networking 2(PUN2)を利用していきます。 サーバについては、クラウド型とオンプレ型の2種類がありますが、クラウド型のPhoton Cloudを利用していきます。

アカウント作成

まずは公式ホームぺージにアクセスして、Photonのアカウントを作成します。 Unityのアカウントとは別物です。
www.photonengine.com

アカウントがない場合も、右上の「サインイン」を選択します。 f:id:enia:20210311153234p:plain

アカウントがないので「こちらから作成してください」を選択します。 f:id:enia:20210311153417p:plain

メールアドレスを入力し、reCAPTCHAにチェックを入れて、「登録する」を選択します。
f:id:enia:20210311154205p:plain

サインアップ完了のメッセージが表示されます。
f:id:enia:20210311154324p:plain

指定したメールアドレスに確認メールが送信されているのでメールに記載されたURLにアクセスします。アカウントセットアップ画面が表示されるので、パスワードを入力し「アカウントを作成する」を選択します。 f:id:enia:20210311154622p:plain

アカウント作成完了のメッセージが表示されます。
f:id:enia:20210311154856p:plain

アカウント作成は以上です。

AppIDの発行

次に、これから作成するアプリのAppIDを作成します。 TwitterFacebookAPIを利用する場合も同じですが、APIを利用するアプリケーションを識別するためにAppIDが必要になるのでしょう。そうでないと許可なくPhotonを利用されてしまいますからね。

ダッシュボードに以下の画面が表示されているので「新しくアプリを作成する」を選択します。 f:id:enia:20210311155817p:plain

Photonの種別とアプリケーション名を以下のように設定して「作成する」ボタンを押します。

Photonの種別: Photon PUNを選択
アプリケーション名: PUN2-tutorial
アプリケーションの説明: 空欄
URL: 空欄

f:id:enia:20210311160327p:plain

後ほど使うので、生成されたアプリケーションIDをコピーしておきます。
このIDを用いてPhotonサーバを通してクライアント間の通信ができます。
f:id:enia:20210311161045p:plain

AppIDの発行は以上です。

プロジェクト作成とPUN2のインポート

UnityHubでプロジェクトを作っていきます。 テンプレートは3Dを選択します。 プロジェクト名にPUN2と入力し「作成」ボタンを押します。 f:id:enia:20210311161907p:plain

Unityが起動するので、トップメニューから「ウィンドウ」->「アセットストア」を選択します。 f:id:enia:20210311163802p:plain

アセットストアが開くので、検索ボックスに「PUN 2 Free」と入力します。
検索結果のPUN2 - FREEを選択します。
f:id:enia:20210311164022p:plain

「Download」を選択します。数十秒程度かかると思います。
f:id:enia:20210311164205p:plain

ダウンロードが終わったら表示される「Import」を選択します。
f:id:enia:20210311164302p:plain

Importが完了すると、以下の画面が起動します。 デフォルトの設定のまま「インポート」ボタンを押します。 f:id:enia:20210311165121p:plain

PUNのセットアップウィンドウが立ち上がるので、先ほど発行したAppIdを入力して「Setup Porject」を選択します。
f:id:enia:20210311165858p:plain

ウィンドウが開くので「Close」を押します。
f:id:enia:20210311200002p:plain

プロジェクトウィンドウで「Assets」->「Photon」->「PhotonUnityNetworking]->「Resources」-> 「PhotonServerSettings」を選択してみましょう。
f:id:enia:20210311170433p:plain

インスペクターを見ると、AppIDが自動で設定されていることが分かります。 また、ここでFixedRegionに「jp」を設定しておきます。
f:id:enia:20210312071203p:plain

PUN2をimportした際にデフォルトで含まれるデモデータは不要なので、プロジェクトビューで「Assets」->「Photon」->「PhotonUnityNetworking]->「Resources」->「Demos」をフォルダ事削除します。
f:id:enia:20210311191201p:plain

プロジェクト作成とPUN2のインポートに関しては以上です。

Unity-Chanのimport

次にデモアプリで用いるUnityちゃんをインポートしていきます。 Unity-Chanは3Dモデルと、キー入力で動くアニメーションが含まれた便利なアセットです。

先ほどと同じ手順でアセットストアからUnityちゃんをダウンロードしていきます。 トップメニューから「ウィンドウ」->「アセットストア」を選択します。
f:id:enia:20210311163802p:plain

表示されたウィンドウの検索ボックスに「Unity-Chan Model」と入力します。
検索結果の「Unity-Chan! Model」を選択します。 f:id:enia:20210311185309p:plain

「Download」を選択します。 f:id:enia:20210311185532p:plain

「Import」を選択します。 f:id:enia:20210311185642p:plain

インポートが完了すると以下のウィンドウが表示されるのでデフォルトの設定で「インポート」を押します。
f:id:enia:20210311190032p:plain

私の場合、Unityのフッター部に以下のエラーメッセージが表示されました。
原因は分かりませんがいったん放置しています。この後の手順でもし問題がでるようであれば解消します。
f:id:enia:20210311191349p:plain

サンプルプロジェクトの初期設定

プロジェクトウィンドウで「Assets」直下に「Resources」、「Scenes」、「Scripts」の3つのディレクトリを作成します。
f:id:enia:20210311191559p:plain

プロジェクトウィンドウの検索ボックスに「locomotion」と入力し、シーンを検索してダブルクリックでオープンします。
f:id:enia:20210311191932p:plain

シーンビューのシーンタブに以下のような画像が表示されるはずです。
f:id:enia:20210311192237p:plain

このシーンを別名で保存します。
f:id:enia:20210311192338p:plain

Demosという名前で、「Assets」->「Demos」->「Scenes」の下に保存します。
f:id:enia:20210311192554p:plain

これでプロジェクトの初期設定は完了です。

今回はここまで! 次回はサンプルプロジェクトの作成を進めていきます。

エンジニアのためのGoogle検索

えにあです。 エンジニアの皆さん、技術情報をgoogleで検索する際、どのように検索してますか? 特に意識せずに検索しているでしょうか? そうであれば、今回のTipsによって今まで見つけられなかった貴重な情報を発見できるようになるかもしれません。

目次

英語で検索しよう

皆さんはGoogleに技術ワードを入力する際、日本語で入力しているでしょうか。 もしそうであれば、英語で検索することを強くお勧めします。

英語検索のメリットは3つあります。

1. 情報量が多い

英語で検索すれば海外の情報まで含めてヒットしますので、当然情報量が多いです。 例えばドメイン駆動設計の勉強をしていて、集約について調べる場合「DDD 集約」のように入力するでしょう。 その場合の検索結果はわずか66,000件です。 f:id:enia:20210308205911p:plain

次に、集約の英語「Aggregate」を使って「DDD Aggregate」で検索してみます。58,600件見つかりました。 ざっと9倍程度の情報量になるわけです。 f:id:enia:20210308210018p:plain

2. 情報が新鮮

残念ながら、最新の技術書がすぐに日本語化されることはないのが現状です。

例えば、2003年に出版された名著「エリック・エヴァンス」のドメイン駆動設計が日本語化されたのは8年後の2011年です。 結果として、最新の技術情報がインターネット上に広がるのも圧倒的に英語の方が早く、日本語で検索すると古い情報がヒットしてしまうことも多いのです。

昨今の技術は変化のスピードも速いです。 私の場合、フロントエンドの開発でReactを使っていましたが、ReactHooksなどの大きな変更もあり、1年前の情報だとまるで役に立たないことが多々ありました。

3. クラス名やメソッド名の参考になる

メソッド名や変数名は英語でつけるのが基本です。しかし、どんな名前を付ければ良いか悩んでしまうことも多いです。その際、英語で検索してみて、ヒットする件数が多い方を使うといった使い方をよくしています。

java Class つけようと思っているクラス名」などで検索すると、「あまりこの名前は使われていないな」といった判断に利用できます。

英語Googleを使おう

ここまで、英語で検索するメリットをお伝えしましたが、単純に英語で検索するだけではメリットを最大限に生かすことはできません。

「DDD Aggregate」で検索した結果をもう一度見てみます。 f:id:enia:20210308210553p:plain

結局、日本語の記事が一番上に出てきてしまっています。 詳細なロジックは分かりかねますが、Googleがどこの国からアクセスしているかを自動的に判定していて、日本からのアクセスでは日本語の記事を検索していることに起因しているようです。

これを回避するには、英語版のGoogleで検索する必要があります。 以下のURLでGoogleにアクセスします。 https://www.google.com/webhp?gl=us&hl=en&gws_rd=cr&pws=0

もう一度「DDD Aggregate」で検索してみましょう。 業界の巨匠Martin Fowler氏の記事が一番上にでてきますね。 f:id:enia:20210308210936p:plain

さらに、検索結果も586,000件から629,000件に増えています。

結論

https://www.google.com/webhp?gl=us&hl=en&gws_rd=cr&pws=0をブックマークして、英語で検索する癖を身に着けよう。

猫でもわかるUnity入門(第19回 オブジェクトを再利用しよう)

f:id:enia:20210228230354p:plain えにあです。

以前に、オブジェクトの設計図である「プレハブ」を利用しました。 今回はプレハブを継承して、機能を追加した新たなプレハブを作成する方法を学んだので記載していきます。

目次

実現したいこと

以下のように、白と茶色の碁盤のようなものを作成しようとしています。
f:id:enia:20210308152646p:plain  

後々、色を変えたくなるかもしれません。 そのため、白い床と、茶色い床はそれぞれプレハブとして作成したいです。

しかし、白い床と茶色い床には、「床」としての共通機能があります。 例えば、クリックした時に何かしらの処理をする、といった動作です。これを実現しようと思うと、オブジェクト指向における「クラス継承」のような機能が必要です。

「床プレハブ」を継承した「白床プレハブ」と「茶色床プレハブ」を作成することができれば、共通の機能を変更したい場合は「床プレハブ」に変更を加え、茶色を黒に変えたければ「茶色床プレハブ」だけに変更を加えれば良いのです。

この「プレハブの継承」に相当する機能を調べたので記載していきます。

床プレハブの作成

結論から述べますと「プレハブバリアント」という機能を使ってやりたいことを実現することができます。 上述の床の例で試していきます。

まず、厚みのある床を作るためにキューブを作成します。 f:id:enia:20210308155048p:plain

名前をBoardにしてリセットしておきます。 拡大/縮小のY軸を0.1にし、板の厚みを薄くしておきます。 f:id:enia:20210308155326p:plain

ヒエラルキービューからborardをドラッグして、プロジェクトビューにドロップします。 f:id:enia:20210308160554g:plain

これで、「白床プレハブ」と「茶色床プレハブ」の元となるプレハブは完成です。

マテリアルの作成

色床プレハブと茶色床プレハブを作るためには、マテリアルが必要になるので作っておきます。 マテリアル作成は以前もやっていますね。

トップメニューから「アセット」->「作成」->「マテリアル」で作成します。 f:id:enia:20210308161232p:plain

名前をBrownにして、インスペクターから「アルベド」で茶色に変更します。
細かい色はこの記事の本質ではないので、茶色っぽければ何でもよいです。
f:id:enia:20210308161544p:plain

NOTE:
マテリアルの名前の変更方法を忘れてしまいましたか?
マテリアルの名前の変更はインスペクターでは行えません。
プレジェクトビューでマテリアルを選択し、F2を押せば変更できます。

同様の手で「White」という名前で白のマテリアルも作っておきましょう。
ここまでで、Boardプレハブと、Brownマテリアル、Whiteマテリアルの3つが存在する状態になっています。
f:id:enia:20210308162022p:plain

色付きプレハブの作成

今回の本題である、床プレハブを継承した「白床プレハブ」と「茶色床プレハブ」を作っていきます。 まず、ヒエラルキービューにあるBoardプレハブのインスタンスに「茶色マテリアル」をアタッチします。

※もし、床プレハブ作成手順のあとでBoardインスタンスを消してしまった場合は、プロジェクトビューからBoardプレハブをドラッグし、ヒエラルキービューにドロップすればBoardインスタンスを作成できます。 f:id:enia:20210308162717g:plain

ヒエラルキービューで茶色マテリアルをアタッチしたBorardインスタンスを選択し、プロジェクトビューにドラッグアンドドロップします。最初にオブジェクトを作成してプレハブを作ったのと同じように、床プレハブのインスタンスからプレハブを作るということです。

すると、以下のポップアップが表示されるので、プレハブバリアントを選択します。 f:id:enia:20210308163540p:plain

作成されたプレハブをBrownBoardとしておきます。
f:id:enia:20210308163741p:plain

これで、「床プレハブ」を継承した「茶色床プレハブ」ができました。
プレハブの継承手順としてはこの時点で完了しているのですが、このまま碁盤を作っていきます。

同様の手順で「白床プレハブ」を作ります。 ヒエラルキービューに残っている「Board」はいったん削除しましょう。 プロジェクトビューから「床プレハブ」をドラッグし、ヒエラルキービューにドロップして「床インスタンス」を作ります。

Boardという名前でも、色はデフォルトの床の色に戻ってるはずです。
f:id:enia:20210308164150p:plain

プロジェクトビューで「白マテリアル」を選択しBoardにアタッチします。 白マテリアルをアタッチしたBoardをプロジェクトビューに戻し、「白床プレハブ」を作成します。 原型プレハブではなく「プレハブバリアント」を選択するのを忘れずに。 作成したプレハブの名前は「WhiteBoard」に変えておきましょう。

碁盤の作成

あとはWhiteプレハブとBrownプレハブを交互に並べていくだけです。 f:id:enia:20210308164846p:plain

床全体に共通のタグをつけてみます。
その場合は床プレハブを修正すればよいですね。
試しに、床プレハブのタグをPlayerに変更してみます。
f:id:enia:20210308165038p:plain

BrownBoardも、WhteBoardもタグが変わっているのが分かると思います。 f:id:enia:20210308165138p:plain f:id:enia:20210308165229p:plain

次に、BrownBoardに色を黄色に変えてみます。 Yellowマテリアルを作ってBrownBoardにアタッチしてみます。 f:id:enia:20210308165441p:plain

BrownBoard1もBrownBoard2も一度に色が変わるのが分かると思います。 f:id:enia:20210308165506p:plain

NOTE:
プレハブの名前をBrownBoardという名前にしてしまいましたが、それだと色を変えた時に名前と実体が不整合になってしまいます。「色」のような変更される特徴ではなく「機能や役割」で名前を付けるべきでした。 この例だと特に「機能や役割」がないのでBoardA/BoardBでも良いですし、奇数/偶数という意味でOddBoard/EvenBoardのようなつけ方でも良かったかもしれません。

プレハブを継承して機能を追加した新たなプレハブを作成する方法について記載しました。 今回はここまで!