【Unity】テクスチャインポーターをつくる

インポーターはざっくり言うとアセットのインポート時にフックして、インポート設定や該当アセットに関する何らかの処理を行うことができるものです。
作成は簡単で、AssetPostprocessorを継承したクラスを作成し、処理を行いたい対象に適したメソッドを記述するだけです。
docs.unity3d.com

今回はテクスチャのインポートをフックしたいので、OnPreprocessTextureを実装します 。

続きを読む

【Unity】AnimatorControllerにScriptからStateMachineBehaviourをアタッチする

StateMachineBehaviourを継承したクラスをAnimatorControllerにアタッチすると、Animatorの状態遷移を受け取って処理を実行できるようになります。

詳細はこのあたりを。
qiita.com

GUI上でアタッチする場合はAnimatorウィンドウで任意のレイヤーにD&Dするだけですが、これをスクリプトでやる場合、以下のようになります。

using UnityEditor.Animations;
(略)
var controller = AnimatorController.CreateAnimatorControllerAtPath ("Assets/Resources/TestAnimatorController.controller");
controller.layers [0].stateMachine.AddStateMachineBehaviour<StateMachineExample> ();

StateMachineExampleがStateMachineBehaviourを継承したクラスです。
今回はlayersの0個目を指定しているので、特にいじってなければBase Layerを示します。
自身でレイヤーを追加して、そのレイヤーの状態遷移を受け取りたい場合はindexを変えてあげる感じ。

既存のAnimatorControllerに対して実行するのであれば3行目を以下のように変えてやればよいだけです。

var controller = AssetDatabase.LoadAssetAtPath<AnimatorController> ("Assets/Resources/TestAnimatorController.controller");

うむ。

サーバサイドエンジニアからジョブチェンジして最近Unityを触ってるんですが、このブログでは全然扱ってなかったのでぼちぼち書いていきたいところ。
気まぐれでQiitaにも投稿してたりします。
qiita.com

iOS9.3のSafariでiframeにリファラが送られない問題

タイトルの通りですけど、iOS9.3でiframeにリファラが送られないケースがあるみたいです。
どうやらクロスオリジンリクエストの際に起こるようですが、何度か試行してるとたまに送られるケースもあって謎。

全然報告が見当たらないのでみんな再現してないのかなー困るケースないのかなーと思ったりしてたんですけど、今日改めて調べてみたらバグ報告が上がってました。

Overview:
Safari seems to no longer send a Referer header when loading a page through an iframe in some situations. I'm still trying to isolate the exact cause, but it seems to happen reliably when an external reference, such as a javascript file or css file, is loaded in the document head. Also, the Accept header seems to switch to */* instead of text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

https://bugs.webkit.org/show_bug.cgi?id=155754

バージョンアップで早々に対応してくれるとよいですけど、まだBugzillaのStatusがNEWなのでどうなるやら…。

【2016/4/1追記】
FIXEDになってました
Bug 155754 – REGRESSION (r191180): Safari does not send Referer Header to iframe src in certain situations

構文エラーを起こすHTMLをjsoupで綺麗にする

はい。
半年以上ぶりです。

信頼できないユーザーの入力タグをどうすれば楽にきれいに出来るか考えてみたりしてました。
ある程度まともな動きをしてくれそうなものがあったのでメモを兼ねて。

以前にも書いたjsoupでやってみます。

jsoupでHTMLをパースする - するめとめがね

コードは以下のような感じ。

String str = "<div><a href=\"#1\">aaa<a href=\"#2\">bbb</div></div></div>";
Document doc = Jsoup.parseBodyFragment(str);
doc.outputSettings().prettyPrint(false);
System.out.println(doc.body().html());

prettyPrintってやつはデフォルトtrueなんですが、これがtrueだとhtmlメソッドを使ってStringにしたとき、インデントやら改行やら素敵な感じでやってくれちゃうんですが、今回全く求めてないので問答無用でfalseにします。

結果

<div>
 <a href="#1">aaa</a>
 <a href="#2">bbb</a>
</div>

※prettyPrintがfalseになってるので実際は整形されないんですが、わかりづらいのでtrueの状態を書いてます。

うむ。
割といい感じにきれいになったんじゃないでしょうか。

次に以下で試してみます。

<div><a href="#1">aaa<div><a href="#2">bbb</div>

結果

<div>
 <a href="#1">aaa</a>
 <div>
  <a href="#1"></a>
  <a href="#2">bbb</a>
 </div>
</div>

お、おう。
ちょっと、ちょっと変だな。

そんなかんじで意地悪しすぎるとちょっと想定外の挙動をしますが、ある程度の良識あるちょっと間違っちゃったてへぺろ程度のコードであれば割とよろしくやってくれそうです。べんりですね。

MavenでSpringを含む依存jarごと一つのjarにするときハマった件

タイトルが長い。

さらに詳しく言うなら、
MavenでSpringを含む依存jarごと一つのjarにしてインターネットに出られないサーバでそのjarを実行したときハマった件
です。

まず前提として、Springさんはクラスパス内にapplicationContext.xmlとかで定義したxsdファイルが見つからない場合、そのURLを見に行ってパースするようです。
このxsdファイルは、例えば「http://www.springframework.org/schema/beans/spring-beans-4.0.xsd」で言うと、spring-beans-xxx.jarの中のMETA-INF/spring.schemasの中で

http\://www.springframework.org/schema/beans/spring-beans-2.0.xsd=org/springframework/beans/factory/xml/spring-beans-2.0.xsd
http\://www.springframework.org/schema/beans/spring-beans-2.5.xsd=org/springframework/beans/factory/xml/spring-beans-2.5.xsd
http\://www.springframework.org/schema/beans/spring-beans-3.0.xsd=org/springframework/beans/factory/xml/spring-beans-3.0.xsd
http\://www.springframework.org/schema/beans/spring-beans-3.1.xsd=org/springframework/beans/factory/xml/spring-beans-3.1.xsd
http\://www.springframework.org/schema/beans/spring-beans-3.2.xsd=org/springframework/beans/factory/xml/spring-beans-3.2.xsd
http\://www.springframework.org/schema/beans/spring-beans-4.0.xsd=org/springframework/beans/factory/xml/spring-beans-4.0.xsd
http\://www.springframework.org/schema/beans/spring-beans.xsd=org/springframework/beans/factory/xml/spring-beans-4.0.xsd

のように記載されており、ここにある通り、その実体は同じくspring-beans-xxx.jarの中のorg.springframework.beans.factory.xmlパッケージの中に存在しています。

次に、依存jarごと一つのjarにまとめる場合、よく使うのはmaven-assembly-pluginです。
ということで実際にmaven-assembly-pluginでjarを作って、インターネットに出られないサーバで実行してみます。

WARN  org.springframework.util.xml.SimpleSaxErrorHandler:48 - Ignored XML validation warning
org.xml.sax.SAXParseException: schema_reference.4: 1)ドキュメントが見つからなかった、2)ドキュメントを読み取れなかった、3)ドキュメントのルート要素が<xsd:schema>ではなかったため、スキーマ・ドキュメント'http://www.springframework.org/schema/beans/spring-beans-4.0.xsd'の読取りに失敗しました。

_人人 人人_
> 突然の死 <
 ̄Y^Y^Y^Y ̄

なんぞこれーということでちょっとjarを展開してみます。
META-INFの下にはspring.schemasがありましたが、中身を見てみるとspring-beansの記述が無く、
spring-contextなどの記述がある状態。
いくつかのSpringのjarに依存していたので、どうやらそれぞれのspring.schemasが上書きに次ぐ上書きを繰り返し、最後に上書きされたやつが成果物に含まれている模様。
というわけで色々調べていると、「maven-shade-plugin」というプラグインならうまいこと出来るみたいなので、maven-assembly-pluginの部分と置き換えてみます。

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-shade-plugin</artifactId>
	<version>2.2</version>
	<configuration>
		<finalName>shade-sample</finalName>
		<transformers>
			<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
				<mainClass>com.tm8r.ShadeTest</mainClass>
			</transformer>
			<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
				<resource>META-INF/spring.handlers</resource>
			</transformer>
			<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
				<resource>META-INF/spring.schemas</resource>
			</transformer>
		</transformers>
	</configuration>
	<executions>
		<execution>
  			<phase>package</phase>
			<goals>
			  <goal>shade</goal>
			</goals>
		</execution>
	</executions>
</plugin>

こんな感じ。
「org.apache.maven.plugins.shade.resource.AppendingTransformer」を指定したtransformerを定義してやると、resourceに指定したファイルが複数あったとき、そのファイルに追記をしていくような挙動をしてくれる模様。

というわけでこれでpackageを実行してやると、spring.schemasとspring.handlersに対して、依存jarに含まれる同名ファイルの内容が全て記述されたものが成果物に含まれる形になりました。
めでたしめでたし。

GuavaのSetsでSetの差分をとったりする

えー今更Guava-?キモーイ!Guavaの記事が許されるのは2012年までだよねー!キャハハハ!
みたいな反応が無いかgkbrしながらも、ちょっといじる機会があったので。
いやGuava全然まだ開発されてるんですけども。

AとBのSetがあってAにあってBにないもの、BにあってAにないものを抽出したい、そんなとき使えるのがSetsのdifferenceメソッドさんです。

Set<String> testSet1 = new HashSet<>();
testSet1.add("a");
testSet1.add("b");
testSet1.add("c");
Set<String> testSet2 = new HashSet<>();
testSet2.add("b");
testSet2.add("c");
testSet2.add("d");
testSet2.add("e");
Set<String> diff1 = Sets.difference(testSet1, testSet2);
Set<String> diff2 = Sets.difference(testSet2, testSet1);

このようにすると、以下のような結果が返ってきます。

diff1:[a]
diff2:[d, e]

べんり!

両方に含まれるものを抽出する場合はintersectionメソッドさんを使います。

Set<String> intersection = Sets.intersection(testSet1, testSet2);

結果は以下の通り。

intersection:[b, c]

捗る。やっぱりGuavaさんすてき。

Ansibleのtips的なあれやそれ

Ansibleをごにょごにょしたので覚え書き程度に。

シンボリックリンクをはる

/usr/local/destに対して/usr/local/srcのシンボリックリンクをはる場合、以下のようにします。

- name: create symlink
  action: file src=/usr/local/src dest=/usr/local/dest state=link

Ansible実行サーバからリモートサーバにrsyncする

1.3.xまではlocal_actionを用いてrsyncコマンドを実行する感じでしたが、
1.4.xからはsynchronizeというモジュールが追加されたのでこれで実現できるみたいです。
rsync_pathはrootで実行したいとか、別のユーザーで実行したいといった場合は以下のように指定してあげるとよいみたいです。

- name: sync files
  action: synchronize src=/usr/local/src dest=/usr/local/dest recursive=yes rsync_path='sudo rsync'

同一コマンドを複数のファイルに対して行う

with_itemsを使えばらくちんです。
{{ item }}と書いた部分に対してwith_itemsで指定したファイルが入ります。

- name: change permission
  action: file path={{ item }} owner=tm8r group=tm8r state=directory recurse=yes
  with_items:
   - /usr/local/hoge/
   - /usr/local/fuga/

すてきですねAnsible。

スポンサーリンク