2018年07月12日

進捗3 と日記





 

 

CarTest180705

 

 

こんにちは、 動画のアップロードの仕方を忘れて編集に時間がかかっていますが、なんとか慣れてきました。

制作作業にシフトして ブログの更新が疎かになってしまっているので、生存報告を兼ねての更新です。

まずウェットコンディションの実験(下の動画) 。 動画解像度が荒いのでわかりにくいかもしれませんが、 ガラスに雨がかかるようにディストーションフィルタを作成してみました 映像だと画質劣化してなんだか汚いですが ゲーム画面ではまずまずな出来。 マスクテクスチャを数枚重ねて、時間軸でUVをずらすだけのシェーダですが プレイヤーのスピードと角速度に反応して変化させています。作成は小一時間程度ですがそれなりに雨っぽくなった気がします パラメータ調整は見た目で合わせるのでそれっぽくするのがとても大変。 ちなみに車体の上を流れる雨粒の場合は、車体のUVに添わせてフローマップテクスチャを作成すれば良いのですが それは時間のあるときに対応します。いまのところゲーム進行でそれほどカメラが近くによることもなさそうなので後回しです。 後ろからカメラが追いかけているていなので ワイパーの処理は無いです あくまで味付けで効果としていい感じに仕上がればよいかと思います。

車体のモデルはまだフィックスしていませんが、シェーダが書けないのでとりあえず車体にペイントを追加しました。 車体のカラーチェンジがだいたい問題なくできているようなので 別シーンで作成中の背景モデルを先に仕上げてから細かい調整を入れていきたいと思います。 個人の作業だとアセット作成が基本シングルタスクになるので あとでシーンに纏めてみたら印象がバラバラ 最悪作り直しに ということも起きやすいので全体に手を入れていくような作り方が合理的だったりします。 チーム作成の場合でも企画の方針がぐらついている事がままあるので、序盤でスタッフに見通しを良くする意味でも早めに形に仕上げてしまうのは有効です。

 

 

これが 形になったらキャラクターものがやってみたい ので次はアクションゲームをと考えていたリします。

そういえばフォルダを探っていたら7年前に描いた設定画が出てきました。 ブログのプロフィールは おえかきぶろぐです(大嘘)なので、たまには絵でも載せておくかという シェフの気まぐれメニュー(賞味期限が切れそうな余った材料で作りました のオトナな言い回し)。

キャラクタの名前の部分は 製作時から時間経過とともに、ちょっと気はずかしくなったのでモザイクにしておきます。

 

もっとも 作りたいのはこれ? じゃないんですけどね

 

images1

 

 


 


書き上げる時間がなかったので あとでココらへんに 追記します。

2018 07.12






 

 

 

最近 技術よりの文字多め記事が続いて潤い成分が足りないので、 潤い成分補充動画をピックアップしてみました。 アニメ関連ですが。

以前は毎期ごとに書いていたアニメ感想記事は 最近では数が多すぎて追いきれないというのもあって もうもう長いこと書いていませんが、 10年ぐらい前にネットラジオでガルパンの水島努監督が 「アニメは一話と最終話だけ見とけばいいんですよ〜 」なんて冗談まじりに言っていたのを思い出しました。、これだけ放映数が増えるとそれもありかもと思えてきます。 話題にならない当たり作品があるので、見ないという選択肢は無いですね 手抜きをすると感性が枯れるので。。

 

 

  • 少女終末旅行ED「More One Night」/チト(CV.水瀬いのり)、ユーリ(CV.久保ユリカ)

『少女週末旅行』 原作はアニメ終了後に完結して悲しい未来を暗示させる描写が話題になっていたけれど アニメはOP、EDとてもよい挿入歌も良かったなあ 気に入ったら2期に期待してお布施しましょう。 結末は変わらないと思うが。

 

  • ORESAMA / ワンダードライブ -MUSIC VIDEO- (TVアニメ『アリスと蔵六』OPテーマ)

『アリスと蔵六』 アニメの方は なんだが 曲は良かった です。 ORESAMAのアルバム収録曲のほうはアニメタイアップものだけ確変します。

 

 

ということで それではまた。

米) アビスホライズンの話題について書こうかと思い今回の記事を数日寝かせましたが、 情勢が判明しないので別記事にしましょう



akinow at 10:05|PermalinkComments(0) Clip to Evernote 日記 

2018年06月07日

進捗2 なのか?

 

 


前回に引き続きですが 進捗の2です。

 

今回の動画はAI部分だけを分離して実際にコースを走らせてみるチェックです。 フィジックスの設定が少しおかしくなっているので コースの路面コリジョンの状態によって時々AIカーがポップしていますが、 これは問題ないですね。 ちょっと突っ込みどころを残したほうが、あえてテストっぽさが出るしいいかな?という判断です。 誰が見てもおかしいところは開発者はだいたい把握してますって(笑

シーンレベルのモデルは流用ですが、一応スプラインベンドに対応して背景オブジェとコリジョンが追従するプロシージャルなコンストラクタを作成して これで道具が一通り揃ったので これから背景作成を始められるかなという段階ですね。

Unityでもできなくはないんですけども 全体に描画が重たい...ので 学習も兼ねて今回はUE4で作ってます。 別にUnityをやらないとかUnrealべったりというわけではなく並行していろいろ進めていますけど なんというかこれは頼まれもので、しかもこちらの都合で数年経っているという。 時間のあるときに詰めてしまわないとまた仕事が忙しくなるとテンションが下がってしまうため 今は少しこちらに比重をおいている感じです。

今どきの自動車のメッシュモデルはノーマルマップで見せかけを良くすると言ったごまかしが効かないので (あまりきれいなハイライトが入らない)、ポリゴン数が結構食うんですよね。 最適化しなくても数万ポリゴンのモデルが処理落ちしない これは開発効率いいです。 シーンの容量はでかいですけど許容範囲じゃないかな。

いろいろと触ってみると 作業に対して見え方が変わって効率が上がったりするので、急がば回れです

 

簡単にAI実装のおはなしをしますね

AIは基本スプライン上をclosedポイント(最も近い場所ね)を探索しながら 車体のローテーションを決定してアクセルのボリュームを上げます。

障害物がある場合は左右どちらかにステアリングを切るavoid処理(障害物を避ける)を実行します。進めない場合は一旦バックギアに入れて戻す。

おおまかにはそのようなシーケンスですが、 それだけでは人間の操作ぽさが出にくいので走行スプラインは複数を配列に登録して、ゲームの進行に合わせてそれらスプラインを選択しながら走行します。 ここらへんは人間の思考と同様に状況に応じて複数パターンのラインを使い分けるということです。

そして走行データをすべて記録しておくレコードシステムを実装します。 最速ラップが出るたびにこの記録をもとにスプライン上のウェイポイントを書き換えてデータとして保持します。 ゲーム開発はあまりスケジュールに余裕がないケースが多いため、開発の序盤にレコードシステムを実装してレベルデザインができ次第テストを行いAIを強化していくことになります。 このシステムを流用したものがゴーストカーと呼ばれるもので、開発中のテストモードをそのままオプションに流用しているというか 基本開発はスケジュールがきついのでオプション系は開発に使用したコードの流用など まかないみたいなものが多かった気がします。

ゲームセンターの筐体の場合は電源を落としても基盤内部にランキングなど簡単なデータを残せるバックアップメモリが搭載されていて、この部分だけ電池が入っています。 家庭用のゲームソフトも電池のバックアップが搭載されていたので理解しやすいかと思います。 サーバーに接続していなかった時代はリリース後も筐体内部のメモリーにデータを蓄え続けて、AIが強化され続けるという仕組みになっていました ※ものによります。 ゲームはリアル世界とはどんなに近づけても法則が異なるため プレイヤーが裏技を発見して突然想定外な記録が出る場合がありますが、 そうした場合でもロム交換のようなコストの掛かる方法は回避することができるため 効率が良い実装だったようです。 もちろんメーカーによって差異があるのでどのゲームも同じではないですよ。 ただし筐体の中にデータを持つのでタイムアタックが加熱しているロケーションは敵AIも強めになりますが、過疎っているロケーションであまりプレイヤーがいないと己との戦いになってしまうという 弱点もあります。

ココらへんの昔話は またおいおいしていくとして

 

 

あとUnity感想的なもの

Unity2018からECSとJobSystemという機能がベータ版?として投入されました。 が まだ積極的に移行していないので見当違いの考えかもしれませんが 構造を理解している開発者には メモリ管理が手動でできるようになる スレッドプログラミングが比較的容易になる というのはメリットになるとは思うのですが、当初のゲームエンジンで開発のハードルを下げるという目的からは遠ざかっているような気もします。

開発の利便性を向上させる目的で、構造体に多くのアトリビュート情報を付加してあるのはエンジン側の設計の都合で それで処理の足を引っ張るようならば、そこら辺り考えずに今まで通りのコードの書き方をすれば、ECSやJobSystem使用時と同等の性能が発揮できるようにコンパイル時に最適化されるだけでよいだけでは という気がしなくもないです。 さらなる調整オプションとして使用できる分には良いのですが、 今ひとつ方向性が見えにくくなってきました。 うまく伝わるかわかりませんが、動作が不安定なアプリケーションの改善点が、「新機能のオートセーブがつきました !!」だったような なんとなくですが

今さらですがゲームエンジンもだいぶ市民権を得てきたようで 当初は「ゲームエンジンだけでプログラムの基礎を学ばなければ、ゲームエンジンがなくなったらどうするんだ 」という意見も散見されましたが (長く開発を続けている職人さんね) もうさすがに急になくなるとかは無いでしょう。 スクラッチでゲームエンジンと同等の質と開発スピードに対抗できるならば分かりませんが。 寿司職人さんが、「回転寿司が急になくなったらどうするんですか」といっているようなもので、市場の需要を考えれば、まずないでしょう。

将来 現行ゲームエンジンにとって変わるものが出てきたとして使用するのは人間ですからインターフェースは大きなシェアを持っているツールに寄せてくるでしょうし 導入しやすい似たような環境になると思うので ビッグウェーブに乗っていけば大丈夫ではないでしょうか。

 

問題としてはゲームエンジンは進化が早いので必死に機能をマスターすることを重点にしてしまうとゲームを作れず終わる可能性はあります。しかも割と多いタイプな気がします。 ネットは大量の情報が参照できますけど ゲームはシステムや種類ごとに実装方法が異なるため情報化しにくく ネット上では制作物にぴったりと合った情報が見つけにくいか 見つからない そのため実装して制作ノウハウを蓄積していく必要があってその部分はネットの情報だけでは補強できないからです。

「クックパッドを毎日閲覧して料理の知識を身につけたら いつかはシェフになれるはず!」といった会話を小耳に挟んだとして ナンセンスなのでまずは実際に料理を作ってくださいというアドバイスをすると思いますがどうでしょう。 とりあえず実際に制作してゲーム制作ノウハウを身につけていけば 現行のゲームエンジンが廃れようがどんと来いなので、モノをどんどん作らないとですね。

 

 

ということで、 もうちょっと頑張っていきましょう

ではまた



akinow at 11:12|PermalinkComments(0) Clip to Evernote 日記 | シリーズ講座

2018年05月25日

進捗

 



 


だいぶ更新が空いてしまいましたが すこし進捗をアップしておきます

 

  今回の動画はUE4で作成中のゲーム進捗ですね これは今年の初めあたりの映像で 主な作業は大まかなのゲーム進行の実装とAIの実験です。 現在ではカーセレクトやスコアボードといったシークエンスと マルチプレイに対応して、だいぶ印象は変わっているかと思います。

仕事の合間の息抜きなので まだそれほど進行度は上がっていないですが、基本的な部分は大体押さえられたかと思います。流用できるものは流用して、最終的にはリソースは全部入れ替え予定。

いつも通り開発はじめではデザインは仮でざっくりですけど 見栄えを優先してリソース作成を完成状態に近いところから始めてしまうとゲーム本体に変更があった場合に、修正対応で大きく巻き戻し あるいはそのゲームの売りになるような難易度高めな実装を後回しにした結果 実装できずに作成済みデータが無駄になるといった 開発中にありがちな落とし穴に落ちてしまう危険性があります。

想定される問題は回避せずになるべく序盤で解決にあたっておく。 ゲームエンジンの作りがデータの容易な差し替えを想定した構造になっているので、全体を万遍なく見渡せる この方法がスケジュールを短縮するためにはベストな作り方だと思います。

もっとも ゲームエンジンじゃなくて何かをを作る場合大抵そういう作り方が結果良好なんですけどね。

 

細かい部分のアレコレはまたいずれ解説をしていくとして スケジュールがつまっているので

またしばらくしたら更新します。 ので しばしお待ちを

 

ではまた ☆ミ



akinow at 10:26|PermalinkComments(0) Clip to Evernote 日記 

2018年03月02日

うにばな Editorクラス−Presetsデータへのアクセス

 

 

現在Editorクラスでプリセット周りの実装をしているのですが、古めのスクリプトが仕様の変更で動作しないため しらべている最中です。

Editorクラスの情報は大量に存在しているので需要があるかわかりませんが。せっかくなので今回調べた経過を記事にしておきます。

 

まずUnityのEditorクラスから格納される内部データがどのように格納されているのかとデータへのアクセスのための実装ポイント、を簡単に解説している記事がありました。

 

■Accessing Unity's saved palettes

Q: 1つのパレットを保存する場合、それはスクリプト可能なオブジェクトのように見えるに格納されることに気づいた のですが、そこに保存されている色にアクセスする方法はありますか? できれば本当に便利です!

Screen Shot 2018-01-24 at 5.04.44 pm-CiS9zWDpoW

Screen Shot 2018-01-24 at 5.04.50 pm-VCX4uZJpsD

 

1.クリックしたものの種類を把握するように設定することができます:

  1. public static class EditorCommands {

  2. [MenuItem("Commands/Get Type Of Selected")]

  3. public static void GetTypeOfSelected() {

  4. Debug.Log(Selection.activeObject?.GetType().Name);

  5. }

  6. }

2.これを使用すると、パレットのタイプがColorPresetLibraryであることがわかります。さて、それは私たちが協力できるタイプですか?あなたがそれを行うにはいくつかの方法がありますが、有能なコードエディタがあれば、その名前を検索して、コンパイルされていないバージョンの型を見つけることができます:

  1. namespace UnityEditor

  2. {

  3. internal class ColorPresetLibrary : PresetLibrary

  4.    ...

  5. }

3.まあ内部的なので、スクリプトからアクセスすることはできません。アセットをテキストエディタで開いてその外観を確認してみます。

  1. %YAML 1.1

  2. %TAG !u! tag:unity3d.com,2011:

  3. --- !u!114 &1

  4. MonoBehaviour:

  5.   m_ObjectHideFlags: 52

  6.   m_PrefabParentObject: {fileID: 0}

  7.   m_PrefabInternal: {fileID: 0}

  8.   m_GameObject: {fileID: 0}

  9.   m_Enabled: 1

  10.   m_EditorHideFlags: 1

  11.   m_Script: {fileID: 12323, guid: 0000000000000000e000000000000000, type: 0}

  12.   m_Name:

  13.   m_EditorClassIdentifier:

  14.   m_Presets:

  15. - m_Name:

  16.     m_Color: {r: 1, g: 1, b: 1, a: 1}

  17. - m_Name:

  18.     m_Color: {r: 0.9705882, g: 0.007136685, b: 0.007136685, a: 1}

  19. - m_Name:

  20.     m_Color: {r: 0.13559689, g: 0.4712593, b: 0.5588235, a: 1}

さて、これは簡単に操作できます! そのテキストファイルをつかんで、 "m_Color"で始まるすべての行を探し、色を解析することをお勧めします。それをヘルパーメソッドとして作成するのはかなり簡単です。

 

次にヘルパークラスの実装例を探してみました

ヘルパーメソッドの実装例

 

Unityでプリセット内部変数にアクセスで検索すると上位にくるサイトですが掲載から時間が経過しているためスクリプトは手直しを入れる必要があります。掲載されているHelper関数のスクリプトですが以下のようなメッセージが帰ると思います。

error CS0619: `UnityEngine.Types.GetType(string, string)' is obsolete: `This was an internal method which is no longer used'
unity5以降の仕様変更でこのやり方では内部データにアクセスできないためエラーが返ります。そこで以下のように。
  1. Unityちゃん2Dのインポートのエラー解決(error CS0619)[ver.2017.2.1f1] - Qiita
  2. UnityEngine.Typesが使えなくなりました - FreelyApps
1.のサイトリンクではこのような変更で、エラーの回避ができたということです。
Types.GetType("UnityEditor.AnimationClipEditor", "UnityEditor.dll");
  ? var baseType = Types.GetType("UnityEditor.AnimationClipEditor", "UnityEditor.dll");
  ○ System.Type baseType = System.Reflection.Assembly.Load("UnityEditor.dll").GetType(typeName);
 
 

2.のサイトでは

  •   UnityEngine.Types.GetType(className,"Assembly-CSharp");
  •  System.Reflection.Assembly.Load("Assembly-CSharp").GetType(className);

IDEのサジェストにしたがうとSystem.Reflectionは省略して 良いそうなので

  • Assembly.Load("Assembly-CSharp").GetType(typeName);

このように記述することでエラーは回避できるようです。  さらに以下のような記述があります。

  • System.Type.GetTypeというメソッドでもTypeを取得できるようでした。型の名前を引数にとり、型を返すメソッドです。実行中のアセンブリ(dllと考えていい)かMscorlib.dllに含まれる型であれば名前空間で修飾した型名で型が取れるようです。
  •   System.Type.GetType(className+ ",Assembly-CSharp");

 

 

 

さらに 検索してみたところ以下のようなスクリプトが発見できました、新しめの2018.2月の情報ですが、コメント部分が詳細なので参考にしてみてください。

ColorPresetLibraryCreator.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
using System.IO;
using System.Reflection;
public static class ColorPresetLibraryCreator
{

/*

■1:

Unity creates new preset librarys internally through typed singleton instances of the PresetLibraryManager class.

The two key methods we need to access through reflection are:

public T CreateLibrary(ScriptableObjectSaveLoadHelper helper, string presetLibraryPathWithoutExtension) where T : ScriptableObject

public void SaveLibrary(ScriptableObjectSaveLoadHelper helper, T library, string presetLibraryPathWithoutExtension) where T : ScriptableObject

CreateLibrary does some file path checking before creating the library through the helper object

and registering it with the library cache. SaveLibrary does what it says through the helper object.

In between the two calls is when we can actually add presets to the library.

We could use the helper object directly to save the library but it's probably safer to let the Manager class do it.

*/

    private const string assemblyDef = "UnityEditor.{0},UnityEditor";

    public static void CreateNewLibraryThroughPresetLibraryManager(string name, List colors)
    {

   

//■2:

// The ScriptableSingleton class is public, but because PresetLibraryManager isn't

// we still need to make a generic type and then use reflection to get the static instance property.

// This is assuming that we need the singleton instance for library registration purposes -

// it might not be necessary.


        Type managerType = Type.GetType(string.Format(assemblyDef, "PresetLibraryManager"));
        Type singletonType = typeof(ScriptableSingleton<>).MakeGenericType(managerType);
        PropertyInfo instancePropertyInfo = singletonType.GetProperty("instance", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
        var managerInstance = instancePropertyInfo.GetValue(null, null);

// ■3:

// We create an instance of the save/load helper and then pass it and the path to the CreateLibrary method.

// "colors" is the file extension we want for the library asset without the '.'

 
        Type libraryType = Type.GetType(string.Format(assemblyDef, "ColorPresetLibrary"));
        Type helperType = Type.GetType(string.Format(assemblyDef, "ScriptableObjectSaveLoadHelper`1"))
                              .MakeGenericType(libraryType);
        MethodInfo createMethod = managerType.GetMethod("CreateLibrary", BindingFlags.Instance | BindingFlags.Public)
                                             .MakeGenericMethod(libraryType);
        var helper = Activator.CreateInstance(helperType, new object[] { "colors", SaveType.Text });
        var library = createMethod.Invoke(managerInstance, new object[] { helper, Path.Combine("Assets/Editor", name) });

//■4:

// We can't cast library to the desired type so we get the Add method through reflection

// and add the desired colours as presets through that.

// After that the library can be saved!


        if ((UnityEngine.Object)library != (UnityEngine.Object)null)
        {
            MethodInfo addPresetMethod = libraryType.GetMethod("Add");
            foreach (var color in colors)
            {
                addPresetMethod.Invoke(library, new object[] { color, color.ToString() });
            }

            MethodInfo saveMethod = managerType.GetMethod("SaveLibrary", BindingFlags.Instance | BindingFlags.Public)
                                             .MakeGenericMethod(libraryType);
            saveMethod.Invoke(managerInstance, new object[] { helper, library, Path.Combine("Assets/Editor", name) });
        }

■5:

// The library could be returned as an Object or ScriptableObject reference if that was useful

// I don't know of a way to cast it to the actual ColorPresetLibrary type.

   
    }

// Extension function because why not
    public static void CreateNewPresetLibrary(this List colors, string name)
    {
        CreateNewLibraryThroughPresetLibraryManager(name, colors);
    }
}

※誤訳があるかもしれませんのでスクリプト中のコメントで確認してください。

 1.  Unityは、PresetLibraryManagerクラスの型指定されたシングルトンインスタンスを通じて、内部的に新しいプリセットライブラリを作成します。リフレクションを通じてアクセスする必要がある2つの重要な方法は次のとおりです。

  • public T CreateLibrary(ScriptableObjectSaveLoadHelper helper, string presetLibraryPathWithoutExtension) where T : ScriptableObject
  • public void SaveLibrary(ScriptableObjectSaveLoadHelper helper, T library, string presetLibraryPathWithoutExtension) where T : ScriptableObject


  CreateLibraryは、ヘルパーオブジェクトを通してライブラリを作成する前に、いくつかのファイルパスのチェックを行いライブラリキャッシュに登録します。 SaveLibraryはヘルパーオブジェクトを通して何を言うのかを行います。
2つの呼び出しの間に、ライブラリーに実際にプリセットを追加することができます。
ヘルパーオブジェクトを直接使用してライブラリを保存することもできますが、Managerクラスで行うほうが安全でしょう。

2. ScriptableSingletonクラスはpublicですが、PresetLibraryManagerはpublicではないため ジェネリック型を作成し、リフレクションを使用して静的インスタンスプロパティを取得する必要があります。これは、ライブラリ登録の目的でシングルトンインスタンスが必要であると仮定していますが、必要ないのかもしれません。

3.  セーブ/ロードヘルパーのインスタンスを作成し、それをパスとCreateLibraryメソッドに渡します。"colors"は、ライブラリアセットに必要なファイル拡張子で '.'を必要としません。

4. ライブラリを目的の型にキャストできないため、リフレクションでAddメソッドを取得します プリセットとして必要な色を追加します。その後、ライブラリを保存することができます!
 
5.  有用であれば、ライブラリはObjectまたはScriptableObject参照として返すことができます。 ColorPresetLibraryタイプにキャストする方法はわかりません。
なぜ拡張機能なのでしょう?

 

この解説によればUnityではManagerクラスが用意されているので内部データへのアクセスはそちらを使用することで安全なアクセスができるようです。今回の場合PresetLibraryManagerのコードを参照することになります、

PresetLibraryManageにどのようなクラス定義がされているのか簡単に抜粋してみました

unity-decompiled/UnityEditor/UnityEditor/PresetLibraryManager.cs

 

  • public void GetAvailableLibraries(ScriptableObjectSaveLoadHelper helper, out List preferencesLibs, out List projectLibs) where T : ScriptableObject
  • private string GetLibaryNameFromPath(string filePath)
  • public T CreateLibrary(ScriptableObjectSaveLoadHelper helper, string presetLibraryPathWithoutExtension) where T : ScriptableObject
  • public T GetLibrary(ScriptableObjectSaveLoadHelper helper, string presetLibraryPathWithoutExtension) where T : ScriptableObject
  • public void UnloadAllLibrariesFor(ScriptableObjectSaveLoadHelper helper) where T : ScriptableObject
  • public void SaveLibrary(ScriptableObjectSaveLoadHelper helper, T library, string presetLibraryPathWithoutExtension) where T : ScriptableObject
  • private PresetLibraryManager.LibraryCache GetPresetLibraryCache(string identifier)
  • public List loadedLibraries
  • public List loadedLibraryIDs
  • public LibraryCache(string identifier)
  • public void UnloadScriptableObjects()

 

まだ全体を調べ終わっていないので実装までは時間がかかりそうですが、今回はここまで調べたということでメモ代わりに記事にしておきました。 参考になれば幸いです。 それではまた

 



akinow at 10:27|PermalinkComments(0) Clip to Evernote Unity3d | シリーズ講座