インベーダーゲームのつくりかた

はじめに

以下の動画のようなインベーダーゲームをつくります。

このゲーム制作を通じて、verseのanimation controllerの知識を深めることができます。

animation controllerについては、こちらの知識を前提としております。

あわせて読みたい
animation controllerとは はじめに MoveTo、TeloportToをつかって対象物を動かすことができることは以前にご紹介しました。 https://creanavi.k-idea.jp/2024/02/12/moveto%e3%80%81teleportto%e...

そのほかに学習できることは、外部サイトで入手したアセットのインポート方法や、アセットを複製してカラーを変更する方法などです。

それでは、まいります。

インベーダーのアセットを入手する

BlenderやMayaでモデリングしても問題ありませんが、今回はsketchfabという外部サイトを使用します。

sketchfabは誰でも利用できるアセットのマーケットです。アセットは有料のものや無料のものがあります。商用利用に関しては、各アセットの注意書きを参照してください。各自アカウントをつくり利用します。

今回はこれを使います。この下から説明する方法を参考にしながらダウンロードしてください。

1.下画像の黄色枠部分の青いボタンをクリックする

2.Download 3D Modelをクリックする

3.アカウントを作成する

はじめてsketchfabへアクセスする方はこちらでアカウント作成を求められます。下画像の黄色枠部分から新規アカウント作成をおこないます。グーグルアカウントなどと紐づけてアカウント作成可能なため、簡単にアカウントを作成できます。

4.アカウント作成後、さきほどのダウンロード画面へ戻ります

もう一度、Download 3D Modelをクリックして、fbxという項目のDOWNLOADをクリックします。ダウンロードしたファイルの保存場所を決定すると、自動的にzipファイルがダウンロードされます。

5.zipファイルを解凍します

いまダウンロードしたファイルはzip形式のため、解凍する必要があります。解凍しておきましょう。

※今回ご紹介するインベーダーアセットだけでもsketchfabにはいろいろあります。どれでも好きなものを選んでみてください。

アセットをインポートする

UEFNをひらきます。テンプレートは「シンプル」で問題ありません。

コンテンツブラウザに新規フォルダ「Invader」をつくります。

Invaderフォルダに先ほどダウンロードして解凍したfbxファイルをドラッグ&ドロップします。

FBXインポートオプションが登場するので、下の2枚の画像を参考に設定してから、全てインポートという青いボタンをクリックします。

無事にインポートされました。

メッセージログが登場することがありますが、消して問題ありません。

ブループリントに変換する

インポートされると2つアセットがならびます。

そのうち、スタティックメッシュのほうに注目します。

スタティックメッシュを右クリックして、「スクリプト化されたアセットアクション」→「Convert To Prop」→「Wood」をクリックします。

そうすると、コンテンツブラウザのなかに自動的に「CustomProps」フォルダが生成されて、Prop_Invader(ファイル名)というブループリントができます。

(Invader(ファイル名)というのは、インポートしたfbxのファイル名です。筆者はファイル名をInvaderとしていました。)

Prop_Invaderを右クリックして、「スクリプト化されたアセットアクション」→「Can Be Damaged」→「Enable」とクリックします。

レベルに配置します。

verseで新しい仕掛けをつくる~スクリプト全文~

さきほどのインベーダーにアニメーションをつけてくれる仕掛けを新しくつくります。

Verse Deviceテンプレを選択し、デバイス名をinvader_deviceとします。

以下のスクリプトをコピー&ペーストしてください。

(#ポイント1~#ポイント3は後ほど解説します)

using { /Fortnite.com/Devices }
using { /Fortnite.com/Devices/CreativeAnimation }
using { /Fortnite.com/Devices/CreativeAnimation/InterpolationTypes }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /UnrealEngine.com/Temporary/Diagnostics }

invader_device := class(creative_device):

    @editable
    InvaderProp : creative_prop = creative_prop {}

    OnBegin<override>()<suspends>:void=
        #ポイント1
        AnimateProp()

    #ポイント2
    AnimateProp()<suspends> : void =
        
        MovementKeyFrame: keyframe_delta = keyframe_delta
        {
            
            DeltaLocation := vector3 { X:=0.0, Y:=0.0, Z:=0.0 }
            DeltaRotation := MakeRotationFromYawPitchRollDegrees(0.0, 0.0, 0.0)
            DeltaScale := vector3 { X:=1.0, Y:=1.0, Z:=0.2 }
            Time := 0.2
            Interpolation := EaseOut
        }

        MovementKeyFrame2: keyframe_delta = keyframe_delta
        {
            
            DeltaLocation := vector3 { X:=200.0, Y:=0.0, Z:=0.0 }
            DeltaRotation := MakeRotationFromYawPitchRollDegrees(0.0, -30.0, 0.0)
            DeltaScale := vector3 { X:=1.0, Y:=1.0, Z:=5.0 }
            Time := 0.5
            Interpolation := EaseOut
        }

        MovementKeyFrame3: keyframe_delta = keyframe_delta
        {
            
            DeltaLocation := vector3 { X:=700.0, Y:=0.0, Z:=0.0 }
            DeltaRotation := MakeRotationFromYawPitchRollDegrees(0.0, 30.0, 0.0)
            DeltaScale := vector3 { X:=1.0, Y:=1.0, Z:=1.5 }
            Time := 0.5
            Interpolation := EaseOut
        }

        MovementKeyFrame4: keyframe_delta = keyframe_delta
        {
            
            DeltaLocation := vector3 { X:=700.0, Y:=0.0, Z:=0.0 }
            DeltaRotation := MakeRotationFromYawPitchRollDegrees(180.0, 0.0, 0.0)
            DeltaScale := vector3 { X:=1.0, Y:=1.0, Z:=0.66 }
            Time := 0.5
            Interpolation := EaseOut
        }

        MovementKeyFrame5: keyframe_delta = keyframe_delta
        {
            
            DeltaLocation := vector3 { X:=0.0, Y:=0.0, Z:=0.0 }
            DeltaRotation := MakeRotationFromYawPitchRollDegrees(0.0, 0.0, 0.0)
            DeltaScale := vector3 { X:=1.0, Y:=1.0, Z:=0.2 }
            Time := 0.2
            Interpolation := EaseOut
        } 

        
        MovementKeyFrame6: keyframe_delta = keyframe_delta
        {
            
            DeltaLocation := vector3 { X:=-200.0, Y:=0.0, Z:=0.0 }
            DeltaRotation := MakeRotationFromYawPitchRollDegrees(0.0, -30.0, 0.0)
            DeltaScale := vector3 { X:=1.0, Y:=1.0, Z:=5.0 }
            Time := 0.5
            Interpolation := EaseOut
        } 

        MovementKeyFrame7: keyframe_delta = keyframe_delta
        {
            
            DeltaLocation := vector3 { X:=-700.0, Y:=0.0, Z:=0.0 }
            DeltaRotation := MakeRotationFromYawPitchRollDegrees(0.0, 30.0, 0.0)
            DeltaScale := vector3 { X:=1.0, Y:=1.0, Z:=1.5 }
            Time := 0.5
            Interpolation := EaseOut
        }

        
        MovementKeyFrame8: keyframe_delta = keyframe_delta
        {
            
            DeltaLocation := vector3 { X:=-700.0, Y:=0.0, Z:=0.0 }
            DeltaRotation := MakeRotationFromYawPitchRollDegrees(180.0, 0.0, 0.0)
            DeltaScale := vector3 { X:=1.0, Y:=1.0, Z:=0.66 }
            Time := 0.5
            Interpolation := EaseOut
        }

        if (AController := InvaderProp.GetAnimationController[]):
            FortVaderKeyFrames:[]keyframe_delta = array { MovementKeyFrame,MovementKeyFrame2,MovementKeyFrame3,MovementKeyFrame4,
                                                            MovementKeyFrame5, MovementKeyFrame6,MovementKeyFrame7,MovementKeyFrame8}
            AController.SetAnimation(FortVaderKeyFrames, ?Mode:=animation_mode.Loop) #ポイント3
            AController.Play()
        
        
        Sleep(2.0)

verseコードをビルドし、作成した新しい仕掛けinvader_deviceをレベルに配置します。

配置したら、詳細設定のInvaderProp項目に用意したインベーダーをわりあてます。ゲーム中に表示をオフにします。

セッションを開始すると、以下の動画のように、インベーダーが動き始めます。

verseで新しい仕掛けをつくる~ポイント解説~

#ポイント1では、AnimateProp()という関数を呼び出して実行しています。

繰り返し処理を行うからloop式をつかうのでは?と思うかもしれませんが、#ポイント2で関数AnimateProp()を定義する中で、#ポイント3部分でanimation modeをloopとしているためアニメーションが繰り返し再生されるようになっています。

無理矢理loop式を使おうとすると、設定したキーフレームがうまく作動しなくなります。

このあたりはこちらで確認できます。

あわせて読みたい
animation controllerとは はじめに MoveTo、TeloportToをつかって対象物を動かすことができることは以前にご紹介しました。 https://creanavi.k-idea.jp/2024/02/12/moveto%e3%80%81teleportto%e...
インベーダーを複製してならべる

インベーダーを複製していきます。

shiftキーを押しながら、インベーダーとverseデバイスを同時に選択します。続けて、altキーをおしながらそれらをスライドさせます。複製されました。

インベーダー3つとverseデバイス3つを同時に選択して、複製することも可能です。

この作業を繰り返し好きなだけインベーダーを増やします。

インベーダーの色を変更する

Invaderフォルダでマテリアルというアセットがあるので、クリックして選択します。

ctlボタン+Dボタンで複製します。複製してできたマテリアルの名前をBlueにします。ダブルクリックしてひらきます。

Paramのカラー部分をダブルクリックすると、カラーピッカーが登場します。ここで青色のエリアにピッカーを移動させてOKボタンをクリックします。

※好きな色でも問題ありません!いろいろな色をお試しください。

画面左上の適用と保存をそれぞれクリックします。

作成したBlueマテリアルを複製したインベーダーにわりあてます。ポップアップが登場しますが、OKで問題ありません。

完成

ロケットランチャーを配置して、セッションを開始します。

ロケットランチャーでインベーダーを撃破できることを確認してください。

まとめ

animation controllerや外部サイトで入手したアセットのインポート方法、アセットを複製してカラーを変更する方法などを学習できたと思います。

animation controllerでは、設定したキーフレームの数値を変更して変化を試すことができます。

いろいろなアセットをインポートして、新しいゲームをつくることもできるようになりました。

アレンジをお楽しみください。

それでは。また。

お疲れさまでした。

ご質問やご感想はお気軽にコメント欄まで!

コメントする