忍者ブログ
まったくのプログラミング素人の筆者がC++/HSPを使用してSTG(シューティングゲーム)を作っていく過程を書くブログでしたが最近は脱線気味。プログラミング以外にも、ゲーム関連の記事、日々の戯言など。
先日作った3Dシューティングをベースに2Dシューティングを作ってみようと思って、とりあえず自分で作ってキャラクタに変更してみたのですが、変更した瞬間にすんごく動作が重たくなりました。

なんでかなーと思って変更する前のキャラとの違いを考えると、3Dモデルの頂点数が全然違ったんですよね。元々が頂点数800程度で置き換えた方は4000くらいあったので、これが原因かなーと。
私が今まで制作していたモデルはテクスチャを使わずに素材に直接色を塗っていたので色を塗る為にモデルを分割しており非常に頂点数が多かったんです。なので出来るだけ頂点数を抑えつつモデルに色を付けるとなるとテクスチャを貼る方法が一番良さげなのでモデリングからやり直しましました。

今まではモデリングにメタセコイアを使っていたのですが、UnityはBlenderと連動して動かせるとの事でBlenderを使ってみることに。
Blenderは操作方法が独特なので解説サイトなどで練習してから使うのが良いと思います。感覚的な操作では絶対に思うように動かせません。(リドゥがCtrl+Shift+zとか絶対わからんw)

下記の解説サイト様が丁寧で解りやすく書いてあって良かったです。
https://www.cgradproject.com/archives/category/tutorialtips/
https://blender-cg.net/

モデリングに関してはコレで良かったのですが、悩んだのがUV展開。
とりあえずUV展開する時は普通の展開ではなくスマートUV投影で行います。


UV展開する時は角度制限を89にして島の制限は0.03(大きくすればパーツごとの干渉が避けれます)

展開図をUV配置をエクスポートで保存します。


保存した展開図をGIMP2などで色付けするのですが・・・


ここで問題が。上の画像は色が付いてますが最初は何も色が付いていないので、どのパーツがどこの部品なのか全くわからないんですよね。
でもBlender側で簡単に確認する方法がありました。

画像の丸のボタンを押すと編集モードのモデルと展開図の位置を表示してくれますので、どのパーツがどこの部品なのか一目瞭然です。
あとはパーツ毎に色をつければOK。展開図よりも若干大きく色を塗って置いたほうが綺麗に反映されるようです。

尚、展開図の着色方法については、もっと良い方法があるかもしれませんが忘却録として書いておきました。

展開図が着色出来たら編集モードでマテリアルを新規追加します。


テクスチャを追加して画像または動画を読み込めるようにして展開図を読み込めばテクスチャが反映されると思います。

この方法で色付すると頂点数が劇的に減らせたので良かったです。

それにしてもテクスチャの書き込みって難しいですねぇ。線とか文字とか書き込んでみたのですが、なんか馴染まないというか嘘っぽくなってしまってイマイチなんですよね。検索してみても人物のテクスチャの書き方は沢山出てくるのですが、メカっぽいテクスチャの書き方ってあんまりないんですよねぇ。何か良い方法がないものかと思っております。
PR
3Dモデルの表示をやってみたら意外と簡単だったので試しに簡単な3Dシューティングゲームを作ってみました。


簡単な敵と自機が出て来て当たったら爆発させて消去する感じ。
作成するのに下記のサイト様が非常に役に立ちました
プログラミング初心者でも簡単!Unity5で3Dシューティングゲーム開発!!

本当は2.5Dで作成したかったんですが参考にさせて頂いたサイトさんのが3Dだったので、とりあえず3Dで作ってます。

作ってみて感じたのは、本気の3Dゲームを作るわけではないので基本的な考え方は2Dと同じなのですが3D表示の場合はカメラの位置とか画面サイズなどをどうすれば良いのかがイマイチ良くわからないんですよね。。。

この作成した3Dシューティングのカメラを上から見下ろせば3D表示の2Dシューティングに見えますが、それで良いのか?とか思ったり。
そして3D表示だと2D表示と比べて沢山オブジェクトを動かすと重たくなるんですよね。
今回は弾幕シューティングを作ろうとしている訳ではないので、それほど沢山のオブジェクトを動かすことは無いと思うのですが動作は軽い方が良いです。でも背景グルグル回る演出とかやってみたいので3Dもありかなーと思ったり。

それとUnityにはアセットストアと言うキャラクターや背景を購入出来るサイトがあって、今回初めて使ってみたのですが、無料の物でもクオリティ高いものが沢山あって凄いなぁと思いました。(今回作った3Dシューティングの素材は全てアセットストアで無料ダウンロードした物です。)

こんなキャラクターや宇宙の背景も無料で使えるとか凄いです。

とりあえず、この作成した3Dシューティングを見下ろす感じのカメラ角度にして2.5Dシューティングとして作ってみようかなと思ってます。
Unityで3Dモデルを表示したいなーと思ったのですが、私が今まで使っていた3Dモデリングソフトはメタセコイアなので無償版だと出力ファイルがmqoになるんですよね。
でもUnityはmqoファイルには対応していないので対応したファイル形式に変換する必要がありました。
ググってみるとBlenderでmqoを読み込んでUnityに対応しているfbxで出力すると良いっぽいので実践してみました。

まずはメタセコイアでmqoファイルを出力します。


Blenderは標準ではmqoファイルの読み込みに対応していませんので、読み込めるようにプラグインをインストールします。
https://onedrive.live.com/?id=CE4C74EDA2A73245%21276&cid=CE4C74EDA2A73245
こちらのページにあるmqo_script_268.zipをダウンロードします。(Blenderのバージョンによってダウンロードするファイルは変わります。Readme参照)
製作者の方に感謝です。

Blenderのファイルメニューからユーザー設定(User Preferences)を開きます。
アドオンタブ(Add-Ons)を開いてファイルからインストール(Install an addon)を選択して先程ダウンロードしたファイルを選ぶと出てくるImport-Export: Import-Export Metasequoia Forma t(.mqo)にチェックを入れたらユーザー設定の保存をおして完了。
ファイルメニューのインポートにmqoが追加されているはずです。


ファイルメニューのエクスポートでfbxに変換します。


fbxで出力したらUnityで読み込むのですが、ここで問題がおきました。


読み込んだモデルのマテリアルが半透明になってる部分があるんですよね。
解決方法をググってみるとマテリアルのインスペクタにあるレンダリングモードをTranceparentからOpaqueにすれば良いのですが変更する部分が何故か灰色になっていて変更出来ません。


どうしたもんかと思って更に調べるとマテリアルのLocationをUse Embedded MaterialsからUse External Materials(Legacy)に変更してApplyボタンを押すと上手く出来るようになりました。


マテリアルのレンダリングモードをTranceparentからOpaqueに変更すると上手く表示されました。

ついでにテクスチャも貼ってます。インスペクタのAlbedoにテクスチャファイルを指定すればOKです。

【Unity】自機を表示して移動させる【簡単な2DSTGを作ってみるNo.1】

【Unity】自機弾を発射する(プレハブ化する)【簡単な2DSTGを作ってみるNo.2】

【Unity】敵のアニメーション表示と移動(プレハブ化する)【簡単な2DSTGを作ってみるNo.3】

【Unity】自機狙い弾を発射させる【簡単な2DSTGを作ってみるNo.4】

【Unity】背景の表示とオブジェクトの表示順位【簡単な2DSTGを作ってみるNo.5】

【Unity】当たり判定の追加【簡単な2DSTGを作ってみるNo.6】

【Unity】爆破アニメーションの追加【簡単な2DSTGを作ってみるNo.7】

【Unity】タイトル画面の追加(シーン移行)とテキスト表示【簡単な2DSTGを作ってみるNo.8】

【Unity】ボスの追加【簡単な2DSTGを作ってみるNo.9】

最終回です。ボスを追加して弾幕を3つ作りました。


これまでのソースファイルと画像ファイル、プロジェクトセッティングなどはコチラ↓
テストシューティングダウンロード

Zipファイルになっていますので展開したらtestshooting.unitypackageとProjectSettingsフォルダが入っています。
このプロジェクトを実行させるためにはUnityでTemplateを2Dにして新規プロジェクトを作成します。


ファイルメニューのAsset→Import Package→Custom Packageを選択してtestshooting.unitypackageを読み込みます。
ProjectSettingsフォルダは作成したプロジェクトにあるProjectSettingsフォルダに上書きします。
Gameタブにあるアスペクト比を4:3にすればOK。再生ボタンを押すとゲームが開始されると思います。
動かすとこんな感じ↓


ボスに関しては本体と回転する羽に分けて表示して羽画像だけを回転させています。
羽画像を本体の小要素とするだけで移動や削除などは本体の方のスクリプトを引き継いでくれるので便利です。

上記のファイルにソースファイルもありますがボスに関しては下記の2つのファイルで制御しています。
boss0_bullet_move.cs


boss0_move.cs


ボス移動用のスクリプト(boss0_move.cs)で敵弾を発射したい時間(shot_time)の時にboss0_bullet_move.csスクリプトのCreate_rad_ds_bu_ex_ey()関数に発射角度、スピード、弾画像種類、発射位置x、発射位置yを引数として渡して敵弾を生成しています。

ここで悩んだのがInstantiateで生成したオブジェクトに引数を渡したいって事でした。
Instantiateで渡せる引数は座標と画像回転角度だけなので、弾のスピードとか発射角度は渡せないんですよね。
で、色々検索するとコチラで良い方法が掲載されていました。
【Unity】Instantiateで生成したGameObjectのScriptに引数を渡す方法
引数を渡す用の関数を作って別のスクリプトから読み込む感じかな。
boss0_bullet_move.csのpublic void Create_rad_ds_bu_ex_ey(float direction, float speed, int bullet, float ex, float ey)が引数を渡すようの関数です。
引数(発射角度、スピード、弾画像種類、発射位置x、発射位置y)

弾の移動に必要な要素は角度とスピードなのですが弾の画像や発射位置も制御したかったので5つの引数を入れました。
こうすることでスクリプトは一つですが色んな画像の色んな弾を表現出来ます。

例えばboss0_move.cs側で下記のように書けば1フレームに1回、8方向に回転しながら弾幕が発射されます。
 for (rad = 0f; rad < 6.28f; rad += 0.8f)//弾発射角度が6.28になるまで発射、6.28で一回転(3.14の2倍)青弾用
                {
                    GameObject shot = Instantiate(boss0_bullet_prefab, transform.position, transform.rotation) as GameObject;//敵弾生成
                    boss0_bullet_move s = shot.GetComponent <boss0_bullet_move >();//boss0_bullet_moveスクリプトを取得
                    s.Create_rad_ds_bu_ex_ey(rad + rad2, 0.1f, 0, 0, 0);//boss0_bullet_moveスクリプトのCreate_rad_ds_bu_ex_ey関数に弾の初期情報を渡す
                }

それと、ややこしくなるので自機とボスの当たり判定は行っていません。
自機弾とボスのみ当たり判定を行って、倒したら最初に戻るようにしました。

以上、稚拙な内容ですがどなたかの役に立てば幸いです。
このプログラム、画像は自由に使って頂いて構いませんが著作権は放棄していません。
本プログラムを使用したことで発生した如何なる不都合に対して、作者は責任を追いかねますのであらかじめご了承ください。ソースファイルの改変などはご自由に行って頂いて結構です。
【Unity】自機を表示して移動させる【簡単な2DSTGを作ってみるNo.1】

【Unity】自機弾を発射する(プレハブ化する)【簡単な2DSTGを作ってみるNo.2】

【Unity】敵のアニメーション表示と移動(プレハブ化する)【簡単な2DSTGを作ってみるNo.3】

【Unity】自機狙い弾を発射させる【簡単な2DSTGを作ってみるNo.4】

【Unity】背景の表示とオブジェクトの表示順位【簡単な2DSTGを作ってみるNo.5】

【Unity】当たり判定の追加【簡単な2DSTGを作ってみるNo.6】

【Unity】爆破アニメーションの追加【簡単な2DSTGを作ってみるNo.7】

【Unity】タイトル画面の追加(シーン移行)とテキスト表示【簡単な2DSTGを作ってみるNo.8】

【Unity】ボスの追加【簡単な2DSTGを作ってみるNo.9】

タイトル画面を追加して得点表示などを行います。
まずはタイトル画面の追加から。

UnityはScene機能で現在の画面を管理しているので、このSceneを切り替える事でタイトル画面とゲーム画面を切り替えることが簡単に出来ます。
まずはprojectタブでScenesフォルダの下に新しいフォルダを作成します。今回はMain_SceneとTitle_Sceneの2つを作成しました。
Main_Sceneフォルダに今までScenesフォルダあったファイルを移動します。Title_Sceneの方で右クリック→Create→Sceneで新しいシーンを作成します。名前はTitleとしました。今まであった方のしーんはMainとします。


作成したTitleシーンをダブルクリックするとHierarchyタブがTitleシーンに変わります。(それまでのMain_sceneは消えるので保存してから)
Hierarchyタブで右クリック→Create Emptyで名前はTitleにして空のオブジェクトを作成します。

projectタブで右クリック→Create→C# Scriptでスクリプトを作成。名前はtitle_sceneとして下記のコードを入力します。
title_scene.cs

Zキーが押されるとSceneManager.LoadScene("main");でmainシーンを呼び出しています。
LoadScene関数を使用するために最初にusing UnityEngine.SceneManagement;の宣言が必要です。
スクリプトを保存したらHierarchyタブのTitleオブジェクトにアタッチします。

(画像では文字も出ていますが実際は現時点では出ません(表示方法については後述))

FileメニューのBuild Settingsを選択します。


追加したいシーンをScene in Buildにドラッグ・アンド・ドロップします。

これで準備は完了。この欄の一番上のシーンがビルド時に最初に読み込まれるシーンとなりますので一番上にタイトルシーンを持ってきておきます。

この状態で再生ボタンをおすと何も表示されていない画面からスタートしてZキーを押すとゲーム画面に移行したと思います。
画面に何も表示されていないのは寂しいのでテキストでタイトル文字を表示してみます。

Hierarchyタブで右クリック→UI→TextをクリックするとCanvasとTextが作成されます。
Textの名前をTest Shootingにしておきます。


HierarchyタブのCanvasをクリックしてInspectorのCanvas Scaler内のUI Scale ModeをScale With Screen Sizeに、Screen Match ModeをExpandに設定します。
(画面サイズを変更しても良い感じにスケールを合わせてくれるようにする設定です)


HierarchyタブのTest Shootingを選択してRect Transformを0,-150,0に。
テキストエリアに
Test Shooting Game
Press the Z key to start the game
と入力。
Font sizeを50にして色を白にします。
(この辺は自分の好きなように設定して良いと思います。)
文字が切れたりするようならSceneタブの大きさを変更します。
これで簡単ですがタイトル画面が出来ました。


次にスコア、ゲームオーバー、自機残数表示をしてみます。
まずはHierarchyタブをMainに切り替えます。右クリック→UI→TextをクリックするとCanvasとTextが作成されます。Textの名前をSCOREにしておきます。
同じように、もう2つTextを作成します。名前はGAME OVERとship
細かいセッテングなどは上のTest Shootingと同じようにして位置などを決めます。


projectタブで右クリック→Create→C# Scriptでスクリプトを作成。名前はUIcontrollerとして下記のコードを入力します。
UIcontroller.cs

    public void AddScore()
    {
        this.score += 50;
        scoreText.GetComponent< Text >().text = "SCORE:" + score.ToString("D5");
    }
敵が倒された時にAddScore()関数を呼び出してscore変数に50点を足しています。
score.ToString("D5");のD5は整数の5桁を表示するって意味です。
外部スクリプトから関数を呼び出す時は
GameObject.Find("Canvas").GetComponent<UIcontroller>().AddScore();
このような書き方で呼び出せるようです。
CanvasオブジェクトのUIcontrollerコンポーネントにあるAddScore関数を実行せよって感じかな?

自機の残り数もスコアと同じような表示方法です。
    public void ship_num()
    {
        ship = time_table.ship_num;
        this.shipText.GetComponent< Text >().text = "Ship:" + ship.ToString("D2");
    }

time_tableスクリプトで自機が死んだ時にship_num()を呼び出してship_num変数を表示させています。
 GameObject.Find("Canvas").GetComponent<UIcontroller>().ship_num();

ゲームオーバー表示の
this.gameOverText.GetComponent< Text >().text = "GAME OVER" + "\n" + "Press the X key to return to the title";
ですがテキストを改行させるのは+ "\n" +で出来ました。

上記を踏まえたスクリプトが下記となります。
ship_move.cs


time_table.cs

        if(ship_num == 0)
        {
            GameObject.Find("Canvas").GetComponent< UIcontroller >().GameOver();
            if (Input.GetKey(KeyCode.X))
            {
                SceneManager.LoadScene("title");
            }
        }
このファイルで自機数が0になったらGAMEOVERを表示してXキーが押されたらタイトル画面に戻る処理をしています。

enemy0_move.cs



とりあえずこれでゲームとして動くようにはなったと思いますので、最後にボス的な物を追加して実行ファイルやソースファイルなどを入れたものをダウンロード出来るようにしようと思っています。
カウンター
Twitter
カレンダー
10 2018/11 12
S M T W T F S
2 3
4 5 6 8 9 10
11 12 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30
最新コメント
[11/24 kt.]
[11/24 kt.]
[11/24 NONAME]
[11/23 NONAME]
[10/05 tejas]
プロフィール
HN:
kt.
HP:
性別:
男性
自己紹介:
STG大好きな45歳。
プログラミング経験は昔ファミリーベーシックでちょっとさわったくらい。
好きなSTGは、怒首領蜂大往生、エスプガルーダ(2)等の弾幕STGやら雷電シリーズなんかの非弾幕、バトルガレッガ、グラディウスシリーズ、R-TYPE等、STGなら何でも好きです。
音楽がカッコイイSTGが特に好きで、並木学氏は最高!
ブログ内検索
忍者ブログ [PR]