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

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

Unityエラー CommandInvokationFailure: Failed to re-package resources.

エラーの内容

CommandInvokationFailure: Failed to re-package resources.
C:\Users\devel\AppData\Local\Android\sdk\build-tools\23.0.3\aapt.exe package --auto-add-overlay -v -f -m -J gen -M AndroidManifest.xml -S "res" -I "C:/Users/devel/AppData/Local/Android/sdk\platforms\android-25\android.jar" -F bin/resources.ap_

stderr[
AndroidManifest.xml:2: error: Error parsing XML: reference to invalid character number

]
stdout[
Configurations:
 (default)
 v14
 v21
 ldpi-v4
 hdpi-v4
 xhdpi-v4
 xxhdpi-v4
 xxxhdpi-v4

Files:
  drawable\app_icon.png
    Src: () res\drawable\app_icon.png
    Src: (ldpi-v4) res\drawable-ldpi\app_icon.png
    Src: (hdpi-v4) res\drawable-hdpi\app_icon.png
    Src: (xhdpi-v4) res\drawable-xhdpi\app_icon.png
    Src: (xxhdpi-v4) res\drawable-xxhdpi\app_icon.png
    Src: (xxxhdpi-v4) res\drawable-xxxhdpi\app_icon.png
  values\strings.xml
    Src: () res\values\strings.xml
  values\styles.xml
    Src: () res\values\styles.xml
    Src: (v14) res\values-v14\styles.xml
    Src: (v21) res\values-v21\styles.xml
  AndroidManifest.xml
    Src: () AndroidManifest.xml

Resource Dirs:
  Type drawable
    drawable\app_icon.png
      Src: () res\drawable\app_icon.png
      Src: (ldpi-v4) res\drawable-ldpi\app_icon.png
      Src: (hdpi-v4) res\drawable-hdpi\app_icon.png
      Src: (xhdpi-v4) res\drawable-xhdpi\app_icon.png
      Src: (xxhdpi-v4) res\drawable-xxhdpi\app_icon.png
      Src: (xhdpi-v4) res\drawable-xhdpi\app_icon.png
      Src: (xxhdpi-v4) res\drawable-xxhdpi\app_icon.png
      Src: (xxxhdpi-v4) res\drawable-xxxhdpi\app_icon.png
  Type values
    values\styles.xml
      Src: () res\values\styles.xml
      Src: (v14) res\values-v14\styles.xml
      Src: (v21) res\values-v21\styles.xml
]
UnityEditor.Android.Command.Run (System.Diagnostics.ProcessStartInfo psi, UnityEditor.Android.WaitingForProcessToExit waitingForProcessToExit, System.String errorMsg)
UnityEditor.Android.PostProcessor.Tasks.TasksCommon.Exec (System.String command, System.String args, System.String workingdir, System.String errorMsg, Int32 retiresOnFailure)
UnityEditor.HostView:OnGUI()

develはユーザ名です。

これが起こったのは、IOS向けにビルドしてから、再びアンドロイド向けにビルドを走らせたときでした。

原因

 AndroidManifestの二行目がおかしいということだったので、エクスプローラを開いてかくにんしました。[Temp>StagingArea]の中に、ファイルは格納されています。見たところ、android:versionNameの項目がおかしい。1.1.9を入れておいてほしかったのに、よくわからない正規表現みたいな文字がはいっていました。なので、Unity上で再びバージョンを入力しなおしたところ、エラーは出ずにビルド完了!

考察

 考察なんてたいしたものではないですが、IOSAndroidでバージョンのずれがあり、修正しなおした時に何かしらのミスがあったのではないかとおもいます。みなさんはぜひ統一しましょう笑 
 それと、この手のエラーはよくでるようですが、エラーの内容はググってみたところ千差万別で、自分のエラーはネットには載っていませんでした。なので一応ここに書いてみたのですが、エラー内容にしっかりどこの何がエラーなのか教えてくれているので、しっかりそれをみて自分で修正しましょう!(でも今回のエラーほど簡単なミスは普通しないよね笑)

以上。

雑談 Mayaアニメーション作成時の回転攻撃の話&Unityアニメーションのルートノードの話

雑談回です。なんとなく思いついた即席対処法を忘れないようにメモっておきます。

Mayaでのモデル回転アニメーション

 例えば、かっこいいキャラは連携技の最後に一回転して敵を斬ったり、ジャンプ回転キックみたいなことをしたいですよね!(僕が直面したのはふわふわ浮いてる敵の回転攻撃でしたが、、)その時、アニメーションを作成することはさほど難しくはないと思うのですが、回転したら軸が360度のままになってしまうんです。(みんな知ってるかこのくらい笑)
 んで、何が問題かというと、Unityでそのアニメーションを他のものと繋いだ際にきっと0度に戻りながらそのアニメーションに遷移するとおもうんです。(未検証ですが、多分そう)しかし、回転攻撃した後に軸を戻すために今の逆回りのアニメーションを突っ込むのもおかしいですよね。だってカッコよく決めたのに、輪ゴムのねじれを直すみたいな作業を入れるんですから笑

 本当はもっといいやり方があるのかもしれないけれど、今回僕が試した手法は、、、次のフレームに360度回転し直したアニメーションを挟むことです!。。うん。これだけ笑 
 コツとしては”体全体の回転はルートノードだけを使用すること。”,”360度回転し直したフレームのアニメーションに少しずれを持たせてやること”ですかね。

 なんか無理やりな手法ばっかりしか思いつきませんが、これでなんとか乗り切れているので、とりあえずは創意工夫があっていいのではないでしょうか笑

Unityアニメーションのルートノード

 Humanoid骨格以外でのモデルには、ルートノードが設定されていませんでした。おそらく僕の設定し忘れだとは思いますが、、この時アニメーションのBake Into Poseなどが表示されず少し困っていました。Rig項目からルートを設定してあげれば、解決します。


以上。引き続き頑張れ!

Maya オブジェクトのミラーコピーを作る

cgjishu.net


今回はこちらのMELを使用させていただきました。その時のメモ。

準備

 上のサイト様からありがたくダウンロードをさせてもらいましょう。保存場所はmayaフォルダの奥にある scripts フォルダとなります。その後、mayaを起動していたら、再起動して読み込ませてあげます。
 下にMELなるフォームがあるのでそこに読み込ませたEMLの名前+;を打ち込んであげます。(;がなくても起動してくれましたが。。)今回はAriMirrorと打ち込みます。これで、ツールが起動いたしました。

使用方法

 オブジェクトを選択し、ダウンロードしたサイトさんをよく読んで使用しましょう。

 このミラーなどの判定基準は、選択したオブジェクトのピボットを基準としています。よって、ピボットが変な位置にあると、予期しないミラーが生成されます。なので、しっかりピボットの位置を変更してあげましょう。

カスタム ピボット編集モードをアクティブにする | Maya | Autodesk Knowledge Network


こちらにやり方が書いてあります。僕はまず、オブジェクトを選択>移動ツールを選択>キーボードで"d"ボタンを押しっぱなしにする>ピボットが動かせるようになる。と行いました。もし回転などをさせてあげたい場合は、回転ツールを選択すれば良いと思います。


以上。

Maya〜Humanoid骨格で自作のアニメーションを作ってFBXで出力したい

満を辞して登場!ついに因縁のアニメーション制作!ここの部分を打ち込んでいる今、僕はまだ取り掛かっていません!できるかわからないです!


2日後...

こんばんは笑 超時間を費やしました。正確に言うと、一昨日の23時から明け方4時までと、本日8日を丸々使いまして、無事fbx形式のアニメーションを書き出せました!しかもすでにUnityの方で動作確認済み!素晴らしい!ただ、例のごとく参考サイト通りに全く行かず、(今回はひどかった。。)結局自我流となってしまいました。ので、今回もそんなとりあえず動くfbxをとりあえず出力できれば後は自分で頑張れると言う人向けに、頑張って描こうかなと!このように思っています!

[Unityに送信]

 ああ、なんて便利な機能が実装されているのだろう。。そう思ってました。これが元凶で、いざアニメーションをつけて出力すると、Unityには土嚢のような謎の物体しか読み込まれないではありませんか笑 
 このボタンが機能しなかったため、(原因はイマイチわからないけど、自分が悪い)他の方法を探していました。

そもそもなんでfbxで出力したいのか

 僕の知っている知識の中では、アニメーションに好きなタイミングで実行させたい関数を付与できるのがfbx形式のアニメーションのみだとわかっているからです。Eventってことです。例えば、剣を振り終わったら、booleanのAttack変数をfalseにする関数を振り終わったタイミングで呼ぶように指定でき、便利だからです。もし、fbx形式以外でもできるのなら話は変わってきますが、この理由でfbxにこだわっていました。Assets Storeのアニメーションはfbxではなかったりするので、困ってました。

実行環境

Maya2016
MacOS 10.12.1
unity 5.4.1fかな確か。。

Mayaでアニメーションを作成する

まずここはアニメーションに変更してください。
f:id:thinline196:20161209001536p:plain



そしてここがアニメーションを管理する場所となります。
f:id:thinline196:20161209001619p:plain


ここにキーと呼ばれる、アニメーションの途中のポーズをたくさん保存して、それをある程度Mayaの方で補完をしてもらい、アニメーションとなります。



ポーズの変更は基本的にRigを回転で変えていきます。Rigを移動で動かすと体が伸びますので全体のRigを選択して、場所を少し移動させる以外はあまりやらないほうがいいかな思います。とりあえずポーズを決めましょう。
f:id:thinline196:20161209001642p:plain



こんな感じかな。そしたらこれをキーとして保存します。
この下の写真の項目の一番下の3つに分割するビューに変更します。
f:id:thinline196:20161209001711p:plain



そしたらこの右のやつをすべて選択します。(写真はすでに選択している場面で、選択すると黄色くなります。)
f:id:thinline196:20161209001737p:plain



最後に、先ほど見せた時間の帯のような部分でそのポーズを登録したい部分をクリック。そして、上部のメニューより[キー>キーの設定]を実行すると、選択した時間に赤い縦線が入ると思います。これでキーが保存できました。

後はポーズを変えてこれを繰り返し、パラパラ漫画のように作っていきます。まず大まかに流れを作成してから、間に中間のポーズを挿入してくと良いでしょう。最終的にこんな感じになると思います。

f:id:thinline196:20161209001815p:plain



グラフの扱いについては調べれば出てくるのでそれほど困らないと思います。

アニメーションをfbxで出力

 ここからは効率悪い作業になるかもしれません。

まず、出力したいキャラのRigとオブジェクトを選択してください。

[ファイル>選択項目の書き出し...]の四角ボタンからオプションを開いてください。このような画面になります。
f:id:thinline196:20161209002822p:plain



ファイルタイプはfbxを指定してください。[プリセットを編集]ボタンを押します。

[アニメーションをベイク処理]の項目をチェックし、自分のアニメーションの再生フレームを設定します。
f:id:thinline196:20161209002835p:plain



プリセットを保存してください。

これでfbxを書き出し(警告が出るが問題はない)、Unityにインポートすればアニメーション付きfbxとして読み込まれます!!(正確にはオブジェクトと言うべきか)


自分のために書きましたが、もし悩んでいる方の参考になれば幸いです。


あ、このキャラクタを作成するシリーズもあるので、もしよかったら。
thinline196.hatenablog.com
thinline196.hatenablog.com