iTween のStop ではまる

iTween のエラーで処理が止まる

Unity のアセットのiTweenは超便利ですが、使い方ミスってすごくハマった話。

現象としては、iTween.Stop() でエラーになる。
1回目の呼び出しは大丈夫なんだけど、いろいろゲームをプレイしたあと、iTween.Stop()をするとエラーになるというもの。

MissingReferenceException: The object of type ‘GameObject’ has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.

というわけで、参照がなくなっていると出る。

原因と対策

原因は、iTween.MoveTo 実行中に、そのGameObjectを削除したためだった。
極端な例↓

1
2
iTween.MoveTo(gameObject, new Vector2(10f, 10f), 5f);
Destroy (gameObject);

こうすると、iTween内で使用しているリストiTween.tweensのGameObjectが残ったままになるっぽい。
事実、 iTween.Count() すると、いつまで経っても カウントが0にならなかった。

一度、こうなるといつまで経っても残ったままになってしまう。しかもシーンをまたいでもそのままになってしまうので、かなり痛い。
iTween.tweens.Clear() をすればクリアすることができるのでこれを使うことにした。

post_typeによって生成する画像を変える

Wordpressでは画像をアップロードすると、設定のメディアで指定したサイズに画像を縮小してくれる。
サムネイル、中、大と3つ作られるのだが、post_typeによってはサムネイルだけ作りたかったり、そもそも別のサイズの画像を作る必要がなかったりするケースがある。

post_typeによって作る画像のサイズを変えるには intermediate_image_sizes をフックする。
これには作られる画像のサイズの名前がarrayで渡ってくる。 例: array(‘thumbnail’, ‘medium’, ‘large’)
このarray を書き換えることによって画像を生成するかどうか変更できる。

1
2
3
4
5
6
add_filter( 'intermediate_image_sizes', function ( $image_sizes ){
if($_POST['post_type'] == 'some_post_type' ){
return array('thumbnail'); //サムネイルだけ作る
}
return $image_sizes;
}, 999 );

参考
Removing Image Sizes for Custom Post Type

post_name に連番を付与する

あるpost_typeに限り、1から始まる連番を付与したい。
やり方としては、name_save_preをフックしてやる。保存されているpost_nameの最大値+1を保存していけば、連番になる。
これなら途中で削除などされた場合も問題なく連番(穴抜けは生じるが)になるだろう。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
add_filter('name_save_pre', function($title) {
global $wpdb, $post;
if($_POST['post_type'] =='some_post_type')){
//公開にしたときだけ連番を付与したいので、これらは除外
if(in_array($_POST['post_status'], array( 'draft', 'pending', 'auto-draft' )))return $title;
//すでにpost_nameが設定されていたらそれを返す
if($post->post_name != "") return $post->post_name;

//post_nameはstringなのでcastする。
$max = $wpdb->get_var($wpdb->prepare("SELECT MAX(cast(post_name as unsigned)) FROM $wpdb->posts WHERE
post_type = %s;", $_POST['post_type']));
//念のため、必ずuniqueのpost_nameになるwp_unique_post_slug を通す
return wp_unique_post_slug($max + 1, $_POST['ID'], $_POST['post_status'], $_POST['post_type'], $post->post_parent );
}

return $title;

});

metaboxをドラッグしたり折りたためなくする方法

はじめに

wordpressの投稿画面の各メタボックス(公開とかフォーマットとかカテゴリとか)はドラッグで移動可能だし、クリックすると折りたたむことができる。
今回はそれを無効化したい。

ネットで調べると、以下のようにpostboxスクリプトをwp_deregister_script しているコードが見受けられる。しかし、これだと、公開状態を変える際のjs処理も除外されてしまい、まともに動かなくなってしまった。

1
2
3
4
function remove_postbox() {
wp_deregister_script('postbox');
}
add_action( 'admin_init', 'remove_postbox' );

JavaScript と CSS で無効化

仕方ないので、JavaScriptとCSSでこの機能をなくすことを目指す。
とりあえず、管理画面でbodyの終わりにjsファイルを読むのようにしてjsファイルをbodyタグ終わりで読み込む。

そして、以下のようにして無効化する。

1
2
3
4
5
6
7
8
jQuery(function($){
//metaboxのドラッグを無効にする
$('.meta-box-sortables').sortable({
disabled: true
});
//metaboxのクリックで折りたたむのを無効にする
$('.postbox h3').unbind('click.postboxes');
});

見た目の修正

最後に、このままだとポインターを合わせた時にカーソルが変わってしまうので、それを元に戻す。あと折りたたみの▲ボタンも消す。
これはcssから行うので、管理画面のいらないものを消すのようにしてcssファイルを読めるようにして、そちらに記述する。

1
2
3
4
5
6
7
8
9
10
/*metaboxのカーソルをデフォルトに戻す*/
.js .postbox .hndle,
.js .postbox h3{
cursor:default;
}

/*▼の表示を消す*/
.js .postbox .handlediv {
display: none;
}

管理画面でbodyの終わりにjsファイルを読む

WordPressの管理画面で独自のjsファイルを読み込むテクニックとして、admin_head をフックしてそこで jsファイルを読むというのがある。
ただ、これだとヘッダで読み込まれるため、WordPressで使用されている他のjsファイルの前に読み込まれてしまい、ちょっと困った。
できれば、bodyタグの終わりにjsファイルを読みたい。

そこで、wp_enqueue_scriptを使う。
れの引数に $in_footer というのがあり、これをtrueにすると bodyタグの終わりのところで読み込んでくれる。

こんな感じに使う。

1
2
3
add_action( 'admin_enqueue_scripts', function() {
wp_enqueue_script('admin-js', get_bloginfo('template_directory').'/js/admin.js', array(), '1.0', true);
});