ブルーノのC#プログラミング & unity勉強日記

プログラミング素人、ブルーノの自主勉強ノートです。他のプログラミングを勉強したい方の助けになれば幸いです。その他趣味の雑記もしていきたいです

お絵かき デッサン7/16

f:id:covory10101101276:20180716223010j:plain

今日のデッサンは腕組みの人です。顔の書き方がいつまでもたっても上手くならないです。体もガッチリしているし指の先や耳など細かいところも丁寧に書かなければいけませんね。

ちなみにモデルはeasy poser というアプリを使って書いています

イージーポーザー Easy Poser

イージーポーザー Easy Poser

  • Park Kiyoung
  • ユーティリティ
  • 無料

 無料版は使えるコンテンツが限られていますが、それでも十分な数のモデルやポーズが揃っています。pro版を買いたくなってしまう...!! ところでこれもUnityで作られてるんですね。すごいなあ

No.002 進捗状況01

6f:id:covory10101101276:20180711153125j:plain

ウーゼドム島

 

みなさんこんにちは🌚

ビーフシチューのルーを買っても豚肉を使うと途端に味がカレーになってしまうことに気づいたブルーノです。さて今回から新しいゲームの開発に取り組んでいこうと思います。

 

まず最初にプランニングをしました。最近流行りのPDACではありませんが、どんな作業も計画をたてておいた方が明確になりますね。私の場合は素材をフルスクラッチできないので、大抵はApp Storeを眺めて面白そうなアセットからアイデアを膨らませる方式を現在は取っています。するとこんなアセットを見つけました。

assetstore.unity.com

有料ではありますが格安ですし、とてもクオリティが高いので今回はこちらのアセットを使った箱庭ゲーのようなものを作っていきたいと思います。

人をたくさん立たせてみたいですね。複数の種類でなおかつあまり容量が大きくならなそうな人のアセットは...

assetstore.unity.com

ちょうど良さそうなのがありました。これを使わせていただこうと思います。

とりあえずインポートしてみました。街を作っていきたいと思います。

f:id:covory10101101276:20180711154729p:plain

f:id:covory10101101276:20180711154843p:plain

建物から道から小道具まで様々な環境が並んでいます。これで200円なら格安ではないでしょうか

f:id:covory10101101276:20180711155143p:plain

道を並べると良かれと思って敷いておいたPlaneと重なってしまっていますね。Planeをほんの少し下げておきます。

f:id:covory10101101276:20180711161132p:plain

少しずつ街を作っていきます。ここでちょっとだけ気をつけたのが、右のヒエラルキーリストのように建物と道を一つのオブジェクトの子にまとめておくときに、親のオブジェクトの座標を全て(0,0,0)にしておくことです。どうやらドラッグ&ドロップ以外の方法でオブジェクトを生成すると(Prefabの場合は座標も与えられてるから影響されない?)シーンビューの真ん中に配置されるようで、まとめるためだけに生成したオブジェクトが座標を持っているせいで子がみんなその影響を受けてスクリプトを書く際に混乱することが最初の時も多々ありました。さてどんどん街を作っていきます。

道路などは縁石と道路など一緒に使うことが多いです。そんな時はよく使うものの位置関係を一つの親にまとめてプレファブ化するとレゴブロックのように作れて効率よくなるような気がします。

f:id:covory10101101276:20180716221635p:plain

f:id:covory10101101276:20180716221647p:plain

こんな感じで😄あー楽チンですねー。これならすぐに街が....

f:id:covory10101101276:20180716221049p:plain

果てしない😱

地道に頑張ります。。

 

今回はここまでにしておきます!

これからもちょくちょく進捗状況をあげていけたらいいなと思います。ゲーム作ってる時間は楽しいですね。ちなみに今回は自由に操作できる箱庭ゲーを作りたいと思っています。

 

そういえばこの前、あるゲーム会社のインターン説明会のようなものに行ってきました。ゲームを作ってお金を実際にもらっている方々の運営体制を聞くことができたのはとても良かったです。どこでもいいからゲーム会社入れたらいいなあ

お絵かき FF12 ヴァン

f:id:covory10101101276:20180711215155j:plain

ちょっとArtRageで画像をトレースして書いてみました。こんだけ書いてから思ったんですがトレースってもしかして元の絵に合わせて修正してくれる機能とかありますかね?こんな私にうまくかけるわけないです😓これじゃ絵の練習にならない...

ちなみに書いたのは今PS4でやっているFF12より主人公のヴァンです。キャラデザインもとても良いですし、設定やストーリーもめちゃくちゃ面白くてガンビットシステムなんか特にずっと考えていられるくらい楽しいです。しかしこのガンビットシステムもそうですがL1ボタンの早送り機能や取り返しのつかない要素が多い点など、結構ゲーム好きな人じゃないととっつきにくいんじゃないかとも感じました。

最新作のFF15はストーリーやキャラクター、丸ボタンだけの戦闘などネットでは叩かれている部分が多いですが私は楽しめました!今日のFFは体験する映画のようなスタイルで作られていて、現実から少し離れたファンタジー体験ができるのが他のゲームとは違う強みではないかと私は思っています。今回のFF15はまさにその体現のような作品で、新規プレイヤーには特に好印象だったんではないでしょうか。どうもヴェルサス13の時の初期案のイメージが尾を引いていて過剰に叩かれているように思えます。もちろん私もとても楽しみにしていましたが、それはキングダムハーツⅢに引き継がれているようなのでそちらに期待しています😆

久しぶりの更新

f:id:covory10101101276:20180711115407j:plain

ロックアイランド - パラオ

 

みなさんこんにちは🌚

梅雨もあけてとても暑い日々かと思ったら豪雨に見舞われたり今年の夏は中々荒れていますね。ある理由でブログの更新をしていなかったブルーノです。

というのもこれが今回の記事のメインで、実はこの2ヶ月の間に私の初アプリを開発、販売していました!🤯🤯🤯🤯もしよかったら遊んでみてください

直リンク

https://itunes.apple.com/jp/app/%E3%81%8A%E3%81%BE%E3%81%A4%E3%82%8A%E3%81%97%E3%82%87%E3%81%86%E3%81%98%E3%82%87/id1406127754?mt=8

本当に対したものではないし、粗が目立ちますが今回の経験の全てが私自身にとって大きな一歩になりました!

2ヶ月の間がありましたが制作期間は実は1ヶ月のみで、あとは販売までの手続きでいろいろ私がヘマをして手間取ってしまい、時間としては倍になってしまいました。でもこれで次からはスムーズに販売まで行ける...はず。作ってる間にも思ったのですが制作のフローをこのブログに載せてその間に起こった問題とその解決方法をここに残しておけばよかったなーと後悔しています笑。次のアプリ制作時にはちょっとやってみようと思います👺

全てが初めてで、これまでの勉強の知識を総動員しても次から次に新たな問題が出てきたので結局ネットでの検索の繰り返しでした。結局あれこれ考えても何もしないのでは意味がないなんて当たり前のことを再認識した2ヶ月です。

これからもどんどんアプリを作って色んな事にチャレンジしてみたいと思います😡😡

Unityスクリプト / レンダラー編

f:id:covory10101101276:20180505092234j:plain

クスコ - ペルー

 

みなさんこんにちは🌚

昨日はディズニーシーに急に思い立って友人と遊びに行ってきたブルーノです。もうファストパスも発券できなかったし乗れた大きなアトラクションはタワーオブテラーくらいだったけどめちゃくちゃ楽しかったです。エンターテイメントの代表的な一角としてゲーム作りの上でキャラクターやアトラクションなど参考にできそうです🤓

さて今回は、あらゆるゲーム画面上に描画されるオブジェクトを我々が視認するのに欠かせないメッシュやマテリアルといったレンダラーについてまとめていきます。

 

メッシュとレンダラー

CreatePrimitive()メソッド等で生成されるオブジェクトも含み、我々がゲームシーン上で目にするオブジェクトにはほとんどの場合Mesh FilterMesh Rendererコンポーネントがついています。この二つはどうやらどちらも欠かすことはできないようです。

f:id:covory10101101276:20180505102315p:plain

メッシュフィルターがその頂点(ポリゴン)情報をもち、メッシュレンダラーがそれを画面上に描写するコンポーネントのようです。そしてこのメッシュレンダラーにマテリアルの情報を送ることでそれを元にポリゴン情報に絵をつけていくといった流れでしょうか。

スクリプトからこのメッシュを追加したり編集するにはUnityEngine.MeshFilterクラスからアクセスします。

そしてメッシュはmeshプロパティで取得または追加できます

meshプロパティ

public Mesh mesh { get; set; }

そして追加したメッシュ情報を描画するためのレンダラーはUnityEngine.MeshRendererクラスを用います。

f:id:covory10101101276:20180507142507p:plain

以前学習した[SerializeField]とコルーチンの機能を使っていますね。外部からは勝手にアクセスされないようprivate修飾子を使いつつもインスペクター上からメッシュを設定できるようにし、コルーチンを使うことでUpdateメソッドを使わずに3秒おきにメッシュ変数m1とm2のメッシュ情報を交互にメッシュレンダラー変数mf1に代入しています。

f:id:covory10101101276:20180507142516p:plain

SerializeFieldによりprivateでもこの欄から設定できます。試しにCubeとCapsuleを入れてみました。

f:id:covory10101101276:20180507142525p:plain

交互にオブジェクトのシルエットが変わりますね。でもこの新たに生成したオブジェクトにはマテリアルの情報がないため色や質がわからず、とりあえずピンクっぽい色で表示されています。

 

マテリアル

 マテリアル(Material)はその名の通りその物質の情報です。ザラザラした感じやツルツルした光沢、色やくすみなどの情報を持っています。先ほど自前で用意したゲームオブジェクトには形の情報があるのにこのマテリアルの情報がなかったためにどこからみても全ての部分が同じピンク色という不気味な物質になってしまっていたんですね。

まあ今までにも何回かこのマテリアルを編集したことはありますがインスペクタービューではこんな形でしたね。

f:id:covory10101101276:20180508230032p:plain

メッシュレンダラーのマテリアルの欄から指定することで使用でき、デフォルトでは真っ白になっています。ではこれをスクリプトから使用・追加するにはどうするのでしょうか

マテリアル関係のオブジェクトはUnityEngine.Materialクラスに属します。

UnityEngine.Materialクラス

public class Material : Object

スクリプトからマテリアルを生成する際には元のマテリアルを複製して使用するか、シェーダーを使うという2パターンがあるそうです。シェーダーについてはまだよくわからないので別の機会に勉強します。MeshRendererオブジェクトからmaterial(s)プロパティにアクセスした場合にマテリアルが初期化されていない場合はデフォルトマテリアルが自動で実装されるそうです。ここから色や質感を指定できるので個人的にはこの機能はポイントだと思います。

色の変更はcolorプロパティから取得もしくは変更します。

colorプロパティ

public Color color { get; set; }

 しかし色だけでは全ての質感を表現するのは難しいです。確かに本物そっくりに陰影をつけたりして見分けがつかない絵などもありますが角度が変わればわかってしまいますね。そのためマテリアルには表面にテクスチャを一緒に貼り付けることが多いです。

MaterialクラスのmainTextureプロパティからテクスチャを設定できます。

mainTextureプロパティ

public Texture mainTexture { get; set; }

 実際に使ってみます

f:id:covory10101101276:20180508232648p:plain

先ほどと似たコードのようですね。空のゲームオブジェクトを作成し、3秒ごとにランダムな色を持たせます。

f:id:covory10101101276:20180508232655p:plain

スクリプトから形状を指定すると

f:id:covory10101101276:20180508232702p:plain

色が変わりましたね!

f:id:covory10101101276:20180508232706p:plain

Default-Materialが生成されているのも確認できます。

メッシュの頂点生成などもあるのですが、スクリプトでこれを制御するのはちょっとコアすぎるのでやめておきます笑

今回はここまでにしておきます。

 

ついに始まったUnite Tokyo 2018!!初日の基調講演から行っているのですがもう全てが最高ですね!!🤩専門的なことは難しいですが実践しながら見せてくれる講演もあって違いが視覚的にわかりやすいし、私でもわかるレベルに噛み砕いてくれる講演も多々あって本当に初心者から上級者まで楽しめるものだと思います!絶対に行く価値がありますよ!

明日最終日もいろんなこと聞いてみて回るかー🙃😙

Unityスクリプト / レンダリング編

f:id:covory10101101276:20180424192438j:plain

モハーの断崖 -アイルランド-

 

みなさんこんにちは🌚

早くゲームを作り始めたいのに他のサイトで情報を仕入れようとするたびに新しいワードや概念が出てきて自分の知識の無さにやきもきしながらも焦燥に駆られているブルーノです。さあ早く今回の分を勉強していきましょう!!

 

今回からはレンダリングについてです。レンダリングとは、ゲームの無機質なデータにあらゆる手法で彩りを持たせることを言います。今回やるのは主に照明やカメラワークについてです。

 

カメラ

カメラはUnityに最初に触れた時からずっと使い続けているコンポーネントですね。プロジェクトを新規に立ち上げた際にデフォルトで用意されているMain Cameraはいわゆるカメラコンポーネントを持ったゲームオブジェクトです。グランツーリスモなど視点が急に切り替わったりするゲームにみられるように、複数配置することができます。

コンポーネントからカメラをコントロールする場合はUnityEngine.Cameraクラスによって表されます。

UnityEngine.Cameraクラス

public sealed class Camera : Behaviour

 ゲーム空間でのオブジェクト同士の当たり判定はそれぞれ3次元座標内で交差しているかどうかで判断できますが、我々が覗いているゲーム画面は2次元です。クリックやタッチがオブジェクトに触れているかどうかを判定するにはスクリーン上の座標から光線を取得するScreenPointRay()メソッドを使用します。

ScreenPointRay()メソッド

public Ray ScreenPointToRay(Vector3 position);

positionパラメータにスクリーン上の座標を指定することでそこから画面奥方向へ向かう光線を取得できるので、PhysicsクラスRaycast()メソッドでそれが何かと衝突しているかを取得できます。ちなみにScreenPointToRay()メソッドの引数はVector3型ですが奥行きのz座標は使われません。

Raycast()メソッド

public static bool Raycast(Ray ray, out RaycastHit hitinfo);

 rayパラメータには先ほどのような光線の情報を入れ、hitinfoパラメータには光線に衝突したオブジェクトの情報を格納するRaycastHit構造体を指定します。引数の変数を変更するためref, outキーワードを使っています。構造体にいちいち値を代入しておかなくてもいいようにoutキーワードの方を使っていますね。

RaycastHit構造体

public static RaycastHit

RaycastHit構造体には衝突したゲームオブジェクトの情報が入っています。

では例を書いてみます。

f:id:covory10101101276:20180424203144p:plain

マウスがおかれている座標から光線を飛ばし(14行目)、それが衝突したオブジェクトの情報をhit構造体に格納し座標を加工して返す(17, 18行目)というものですね。短い中に色々工程が詰め込まれている。。。

f:id:covory10101101276:20180424203404p:plain

マウスがcubeに乗っている間だけ回転する!

 

照明

照明はゲームにおいてもドラマや映画などにおいても非常に重要ですよね。雰囲気から心情や状況の描写まで照明によってその印象は全く違うものになってきます。

UnityのLightコンポーネントには4種類の照明が用意されており、Typeの欄からその種類を変更できます。

f:id:covory10101101276:20180424204246p:plain

Spot :文字通り一箇所を円錐状に照らします。スポットライトですね

Directional :イメージとしては太陽の光のように、光源の座標に関係なくある角度から全てのオブジェクトを照らします。

Point :ある一点から周り全方位を照らします。蛍みたいです。

Area(baked Only) :四角形の範囲で照らす光ですが、演算処理の負荷が大きいらしく、リアルタイムでの描写はできないようになっています。そのため、ベイクしてもう周囲のオブジェクトへ反映のさせ方を決めておく必要があります。しかし柔らかくリアリティのある光が演出できるそうです。

 スクリプトからLightコンポーネントのこれらの種類を変更するにはLightTypeプロパティから取得もしくは変更します。

LightTypeプロパティ

public LightType type { get; set; }

 このtypeはエディター上で設定する時と同じ名前で大丈夫です。

ではプログラムを作成していきます

f:id:covory10101101276:20180504083709p:plain

Start()メソッド内で光を写す床と光源を持ったオブジェクトを用意し、位置を整えます。

そしてUpdate()メソッドでは時間に応じて光がDirectionalとSpotを交互に変えるようになっています。16, 27, 30行目でライトを変更するLighttypeプロパティが使われています。

f:id:covory10101101276:20180505100355p:plain

2秒ごとにスポットライトとディレクショナルライトが切り替わるようになりました。

このようにスクリプトからもエディター上でできる全ての変更を行うことができるんですね。今回はここまでにしておきます。

 

久々の更新です😇今も色々準備やら何やらで忙しいんですがこうして合間を縫って勉強しています。このGWも予定がいっぱいっぱい...Unite Tokyoもいくしお金がかつかつだな笑

Unityスクリプト / Mathematics編

f:id:covory10101101276:20180423211739j:plain

山の羊の群

 

みなさんこんにちは🌚

テニスの錦織がまた最近浮上してきてくれて嬉しいブルーノです。ノーシードのタフさを感じたと言っていましたがやはり一度落ちると調子を取り戻すのは大変のようですね。リスクとの兼ね合いも考えながら頑張って欲しいです🤯

 

さて今回は、今までのものとは少し違い、目に見えないけどゲームやアプリを作る上で欠かせなさそうな数学的要素の取り扱いについて学んでいきたいと思います。

 

乱数

乱数という言葉の存在や仕組みはポケモンのおかげで今やだいぶ普通の人にも浸透してきたのではないかと勝手に推測していますが、乱数とは実行するまで結果が確定できないランダムな値のことを指します。乱数を使うにはUnityEnigine.Randomクラスvalueプロパティから取得します。

UnityEnigine.Randomクラス

public sealed class Random

 

valueプロパティ

public static float value { get; }

このプロパティを使用することで、0.0 ~ 1.0までのランダムな値を取得します。乱数は呼び出すたびに新しいものが用意されます。実際に書いてみましょう

f:id:covory10101101276:20180424164429p:plain

Vector3の各座標を0 ~ 5の値で生成してはその座標にcubeを作るというのを100回繰り返すコードです。結果は以下の通りになります。

f:id:covory10101101276:20180424165527p:plain

なんか綺麗ですね。この結果は再生するたびに違うものになります

f:id:covory10101101276:20180424165609p:plain

先ほどはvalueプロパティの値に色々引いたりかけたりして5という範囲までの数字を得ましたが、それをしなくても同じくRandomクラスのRangeプロパティを使用することで最初から指定した範囲内で乱数を得ることもできます。

Rangeプロパティ

public static float Range(float min, float max);

public static int Range(int min, int max);

minとmaxパラメータにそれぞれの型の数字を入力することでその範囲内の乱数を得ることができます。ちなみにmaxの値は含まれません

 先ほど乱数はランダムな数値と言いましたが、実は完全にランダムではありません。シード値と呼ばれるタネをもとに作られます。基本的にシード値には現在時刻を利用しますが、Randomクラスのseedプロパティを利用すると自分でシード値を設定できます。つまり、シード値を保持しておけばそれを基に同じ乱数を生成することができるのです。

seedプロパティ

public static int seed { get; set; }

 

四元数

我々はUnityの中で角度を扱う場合、一般的にオイラー角を使用します。オイラー角は区間上にX, Y, Z軸のそれぞれの角度を持っていて、Vector3変数でそれを扱うことが多いです。しかしオイラー角ではジンバルロックという問題があり、正確に回転を表現できないことがあります。そこで4番目の数字を使うことでこれを回避しようということで、実際のUnity内部では四元数というものを用いています。まあ難しい解説は私にもわからないのでポイントだけ抑えると、「なぜUnityでは四元数で計算しているのに我々がUnityエディタ等で触れるのはオイラー角だけなのか」ということ。つまり四元数を我々に触れさせる前にオイラー角に直してくれているんですね。

まず四元数はQuaternion構造体を用いて表されます。

Quaternion構造体

public Quaternion(float x, float y, float z, float w);

 そして四元数オイラー角に直すには、Euler()メソッドを使います。

public static Quaternion Euler(Vector3 euler);

public static Quaternion Euler(float x, float y, float z);

 引数にVector3型の情報を入れることでQuatrnion構造体に変換してくれます。これで、Unityが扱う他の空間系のメソッドに使うことができます。

では当然逆のもの、つまりQuaternion構造体からオイラー角を出してくれるメソッドもあるはずですね。それがeulerAnglesプロパティになります。

eulerAnglesプロパティ

public Vector3 eulerAngles { get; set; }

四元数オイラー角間の計算にはコストがかかるため、Updateメソッドなどで連続して使用するのは避けたほうがいいらしいです。

他にも掘り出せばキリがないので、ゲームのときに頻出しそうなコンテンツだけを抜粋してみました。今回はこれで終わります。

 

人の気持ちというのはとても単純で複雑ですね。見方を変えれば全く理解できなかったものの気持ちというのも理解できるもんですね😙そしてそのきっかけは結局自分に回帰するのだと思います😎気の持ちようで周りは変わる

あーきのこスープ飲みたい