セキュリティ系の勉強・その他開発メモとか雑談. Twitter, ブログカテゴリ一覧
本ブログはあくまでセキュリティに関する情報共有の一環として作成したものであり,公開されているシステム等に許可なく実行するなど、違法な行為を助長するものではありません.

Unity(雑談) バトルシーンにおける敵と味方のスクリプトについて

どうも!三日間寝込んでおりました。今日は一時間ほどunityに触ってリハビリといったところでしょうか笑 少しいじっていました。


ユーザが触るプレイヤーとその敵のスクリプト

 自分なりにしっかり考えてから制作を始めたつもりだったのですが、やはり詰めが甘いところがボロボロとありますね!どうもその見出しの二人のスクリプトが類似するんですよね。。いや、類似することなんてみんな承知なことなのですが、全てが同じわけではないわけで、僕はやはり今回は分けるべきだなと思ったんです。しかし、コーディングをしていると自分なりに「ここはこうしたほうが流用性があるな、、」って部分が出てくるわけで、そこをいい方向に修正していたら結果的に「あれ、この二人のコントローラほぼ同じになっちゃった」とか「同じコードを二つのスクリプトに追加してるよ」なんてなことがよく出てくるようになりました。

 コーディング中に修正をしていい形に持っていけるようになっているのは素晴らしい成長なんだと自分で思っています。なので、こうやって気づいたとこをここに書き残しておくことで次の制作の時に、さらにレベルアップのきっかけになるんじゃないかと思ってここに書き残します!(ポジティブに考えないとやっていけません!)

・アニメーションコントローラ及び、ダメージや魔法発動エフェクトは敵味方同じものを使用可能
 これは、人間しか登場しない紙芝居ちっくなものなら当然同じコントローラを使いまわせますが、戦闘シーンのようなものであっても攻撃モーションというものがそれぞれにあって、ノックバックのリアクションがあってそれの指示をアニメーターに渡すスクリプトなら使いまわせますねという考えです。使わないモーションを呼び出す関数は使用しなければいい話で。ただこの方法の難点は、関数にモーション名や技名を使用できないことです。つまり万人が一瞬で読んで理解できるスクリプトにはできないです。自分も見返した時に、メモが少なければ理解できない可能性もありますね。技1技2など、企画の時点でしっかりとそのキャラの技名と番号を対応させておくことで、これも回避は可能であると思うので、出てくるキャラやモンスターが多ければ多いほど、この案を僕は推すと思います。


・敵のコントロールスクリプトをまとめて一つのオブジェクトに貼り付け、流用する
 これは敵でなくてもたくさんの種類のモデルを用意して同じスクリプト群を同じように使用したい場合の方法についてです。Unityはpublicな変数にドラッグ&ドロップで直感的に紐付けができるので便利ですが、その操作をどこか一つでもやり忘れると読み込みエラーが起こります。(たまに何故かMissingになるけど)その例えを上げやすいのが、敵モンスターでした。
 で、僕は驚愕の事実を知りました。なんと、Animator は Avatar さえしっかり紐づけてやれば、子オブジェクトのモデルのアニメーション管理もすることができるのです。(これは教えて欲しかった) 何ができたかと言いますと、Animatorやそこに指示をだすアニメーションコントローラ、その他敵を操作するスクリプトは全てまとめて一つのオブジェクトに貼り付けてプレパブ化でもして、後はモデルごとにモデルをそのオブジェクトの子ノードに配置&アバターを紐付けしてあげると、なんといちいち全てチェックしながらスクリプトを貼り付けなくても、簡単に流用ができてしまった!
 少し前の僕は、モデルのオブジェクトに Animator やらスクリプトやらを全て貼り付け、それを新しいモデルのキャラを追加するごとに貼り忘れがないかチェックしながら作っていました。なので、これからはこれをぜひ使っていきたい!というか、偶然このダラダラの記事を読んでいる方がいたら、ぜひ真似してほしいです。


病み上がり&あいかわらずの国語力で、カオスな文になっているかも笑 まぁ、今日は親にLINEのフリーコインを貯めて上げて、ふなっしーのスタンプを購入させてあげることができたので、非常に満足です!(全く記事と関係ない)以上。早く体調良くなれ!!!

Unity パーティクルがspriteの後ろ側に描画される

タイトル通りです。まずは下の画像をみてください。
f:id:thinline196:20161218172507p:plain


これを仮に雷の魔法を放っている場面だとします。どうでしょうか?後ろの柱とカメラに挟まれている部分のパーティクルはしっかり描画されていますが、他の壁と重なった部分は完全に抜けてしまっています。亜空間に削り取られています。

解決法

 この後ろの壁は、イメージとして存在させています。なのでcanvasを通じてこの空間上にあるわけです。なので、イメージではなくcanvasのSorting Layerをいじってやれば、描画順が設定できます。(イメージのソートを変更しても変わらなかった)

canvasに付いているこちらから変更が可能です。
f:id:thinline196:20161218172952p:plain



このDefaultを自分で作成したLayerにして、SortingLayerでDefaultより前に持っていきましょう。これで、OK


結果はこのように、無事雷の魔法になりました。canvasを変更することに気がつけば、さほど問題にはならないかも笑
f:id:thinline196:20161218173144p:plain

雑談 Oculus Touch遊んできた

眠いので日記だけダラダラ書こうかな笑
本日もゲーム制作進みました。Mayaの方でも色々と日々勉強があり、違うマテリアルを読み込んでいるオブジェクトをグループ化してfbxにしてしまうと、Unityの方でMaterialが上手く取得できなかった(頑張ればできるかも?)ため、グループ化を解除してみたり、、、いや今度ネタが尽きた時用にメモ程度にとどめておこう笑


 本日、研究室の方で先輩の研究のお手伝いをしました。結構意見を聞いてくれる先輩で、向こうの方も僕のことを頼りにしてくれているらしく、非常にありがたく楽しく勉強になります。HMDに携帯端末や手を投影して、その使いやすさや違和感などそんなところを調べているのですが、LEAPMOTIONでの手の検出がやはり限界があるように感じました。HMDにLEAPを装着しているため、顔面が向いている方向から計算したLEAPの検出範囲内でしか手が出力されません。これで、VR空間内で体の横に表示された指示書を確認しようとすると、別の作業をしてた手が検出範囲から出てしまい、作業が途中で止まってしまいます。ここは、もう被験者の方にある程度の縛りを与えて実験を行うのがベストだと個人的に思いました。例えば、確認してから出ないと作業ができないとするなど。

 それが終わった後、先日研究室に届いたばかりのOculus Touchを遊ばさせてもらいました!f:id:thinline196:20161215012637j:plain

 感想はよくできたゲーム機だなぁ〜と言った感じです。手での操作感はやはり素晴らしいものがありますが、HMDからの映像が体とリンクしすぎている分、手操作での少しの違和感が目立ってしまうなと感じました。ものを掴む際も、最初は手を全て開いてしまい、コントローラを落としそうになりました笑 そのくらい、没入感は素晴らしいです。ただ、日常やっている動作と違うことをしなければいけないと思った時、やはりゲームだなという印象を持ってしまいました。(ひねくれててごめんなさい)振動などによる手へのレスポンスが受け取れなければいけない以上、コントローラを使用する以外に方法は、電極を体に繋ぐか、実際にその場に物体を出現させるぐらいしかないと思うので、日常動作を捨ててでも、手へのレスポンスは選択すべきなのかもしれませんね。日常動作を求めるなら普通に生きろってはなしです笑
 何はともあれ、Oculus Touchは素晴らしいと思うので、ぜひ機会があれば使ってみてください!

Mayaでパーツごとに別々のimageからテクスチャを作成する&マテリアルのプロパティを動的に変更

やば!どうでしょうが新作だってよ!!!!超嬉しいです笑 まぁここでは関係ないけど!

本日は相方に現在制作中のゲーム内で登場する村人(モブキャラ)の作成を依頼されました。できれば一体ずつ作って行きたいのですが、できれば時間は他のところにつぎ込みたいということで、なるべく使いまわせる村人の制作にチャレンジしました。


服の色*ズボンの色*髪の色*個体数

 これだけの変化をつけられれば文句はないでしょうということで、村人に限れば3種類のモデルを作成することにしました。後は、スクリプトからそれぞれの色を変更すれば見た目にもわかりやすいですね!目の配置なども変更できればと思ったのですが、imageとして後からモデルに手作業で貼り付けるぐらいしか思い浮かばず、またゲーム内容的に目はそれほども立つものでもなかったため、今回は諦めて肌のテクスチャと一緒に書き込んでしまうことにしました。まぁこれは必要な妥協ですよ(というか目を動かすとかまだやったことないのでそのうちに)


 で、色を変える方法としてはこちらを参考にします。
マテリアルのプロパティをスクリプトから変更【Unity】 - (:3[kanのメモ帳]


ググって一番最初に出てきてくれました。Shaderは上のサイト様をみて、プロパティ一覧にcolor系の色をいじれそうなものをチョイスしましょう。とりあえず選んだのはLegacyのself-illunimの一番上の方。skyboxが写り込んでしまうのが嫌だったので、これを選びました。


 で、実際にモデルを作成。Rig付けもしっかり行います。完成したものを、手動で色を変更してみました。

f:id:thinline196:20161214004610p:plain
f:id:thinline196:20161214005005p:plain


しっかり変更できますね!なのでおそらく動的にも変更は可能でしょう!ちなみに、デフォルトは白ベースとなっており微妙に柄も付いております。デフォルトを白とすることで、色の変化が鮮明に出るようになります。ベースが青とかだと変化はとてもわかりにくくなりと思います。靴はそんなに目立つ部分ではないですが、靴がないと全身タイツみたいになってしまうので、黒の靴としました。こうすることで、色で上書きがされずしっかり靴を認知させることができると思います。

相方にgitに載せたことをお知らせしてあげました!もしできなかったよーと返事が来た時は、その原因などをここに追記しようかなと思います。



パーツごとに別々のimageからテクスチャを作成する

Maya初心者にはこれが意外と大変でした。なので今回も自我流です。

そもそも、なぜオブジェクトごとに別のimageを用意しようとしたかと言うと、色を変更するためです。上に書いた通りに実装する場合、服の色とズボンの色などはそれぞれ別の色を指定できた方が見栄えもいいですし、パターンも増えます。(全部一色だとジャージ着てるみたいになっちゃう) ところが、パーツを一つのイメージで作成すると一箇所の色の変更が、他のパーツの色も変更してしまいます。。。(と、思っていたのですが、書いていた時に気づいたけど、Materialを別のものにさえしておけば、一つのイメージから読み込んでも他のパーツに影響しないかも。これは試してみる価値ありですね。)
 まぁなのでとりあえず今回は、最初に思いついた方法を使用しました。


 やり方ですが、単にマテリアルを新たに取り付けてやるだけです。笑 この方法を確立するだけでも大変でしたけど笑
なので次回はぜひ、一つのイメージから別々のマテリアルにテクスチャを渡してみたいと思ってます!(グダグダでごめんなさい)

さて、残り二体の村人も作らなきゃな笑 全くの専門外ですが嫌いな作業ではないです(上手くないけど!)笑
以上。

Unity 動的に別のスクリプトに所持しているメソッドを渡す〜UnityEvent

タイトル通りです。

今回は制作中のゲームの中で少し複雑なことをしようと思い、今回のことをざっと調べました。そのメモを書きます。


docs.unity3d.com


まぁここを読めば全てわかるんですが、、

例えば以下のようなクラスがあったとします。

using UnityEngine;
using System.Collections;
using UnityEngine.Events;

public class EventTest : MonoBehaviour 
{
     public UnityEvent ev;
     
    void CallAnotherMethod(){
         ev.Invoke();
    }
}

それでもって、別のクラスでこのクラスのevにメソッドをわたあしてあげます。

    bool attack=false;

----------何かの関数内---------
         EventTest eTest=GetComponent<EventTest>();
         eTest.ev.AddListener( PrintDeb);
--------------------------------
    void PrintDeb(){
        attack=true;
        Debug.Log("called");
    }

これで、attackをtrueにし、デバッグを吐く関数をev内に渡すことができました。後は最初のスクリプトのCallAnotherMethod()をどこかで読んであげれば、Invoke()によりev内に保存されていたPrintDeb()が呼ばれます。

ちなみに、引数を渡す関数を指定したいときは、EventUnityをオーバーライドしてやれば、引数を渡すことができます。以下は、リファレンスのコピーです。

using UnityEngine;
using UnityEngine.Events;

[System.Serializable]
public class MyIntEvent : UnityEvent<int>
{
}

public class ExampleClass : MonoBehaviour
{
	public MyIntEvent m_MyEvent;

	void Start ()
	{
		if (m_MyEvent == null)
			m_MyEvent = new MyIntEvent();

		m_MyEvent.AddListener (Ping);
	}

	void Update () 
	{
		if (Input.anyKeyDown && m_MyEvent != null)
		{
			m_MyEvent.Invoke (5);
		}
	}

	void Ping (int i)
	{
		Debug.Log ("Ping" + i);
	}
}


僕はこれを、後から任意のタイミングで生成されるオブジェクトが削除されるタイミングを認知するためのフラグの変化に使用しました。(わかりにくい説明)


まぁOnClickなどもこれを使用して呼ばれているらしいので、感覚的にどんなものなのかは、掴みやすいのではないでしょうか?結構小回りが効くものなので役立ちますが、たくさんのところで使用すると複雑なものになってしまうので(動的に紐づけるとバグなどでスクリプトを見返した時に見落としやすい)、用法用量をお守りください。