フィルタをかけると画面全体が拡大されてしまう

概要

以下のようなpixi.jsのオーバーレイフィルタをピクチャにかけると画面全体(マップ全体)が拡大されてしまう現象があるそうで、その解析をしていました。

1
$gameScreen.picture(1)._blendMode = PIXI.BLEND_MODES.OVERLAY;

フィルタかける前

フィルタかけた後

ただ発生するのはスペックの低めのPCだけであり、通常は発生しないようです。
手持ちのPCで発生するのが一台あり、簡単なスペックは以下です。

1
Windows 7 Home Premium 32-bit 
2
Core(TM) i5 CPU M 520
3
Intel(R) HD Graphics

オーバーレイについて

pixi.jsはデフォルトでは以下にコメントされているようにオーバーレイは利用できず、pixi-picture.jsを読み込むことによって利用できます。
ファイルはツクールMVのlibフォルダに存在していて自動的に読み込まれています。

1
IMPORTANT - The WebGL renderer only supports the NORMAL, ADD, MULTIPLY and SCREEN blend modes.
2
Anything else will silently act like NORMAL.

フィルタをかけると

ピクチャのblendModeをOVERLAYに変えると最終的に以下の箇所の処理が大きく変わります。
細かいことはおいといて、最終的にstageにvoidFilterが適用されるようになります。
ここでいうstageはScene_Mapです。
このvoidFilterは何もしないフィルターのはずですが、なぜかこれが適用されると拡大されます。
Scene_Mapに適用されるので画面全体が拡大されてしまいます。

1
Sprite.prototype._speedUpCustomBlendModes = function(renderer) {
2
    var picture = renderer.plugins.picture;
3
    var blend = this.blendMode;
4
    if (renderer.renderingToScreen && renderer._activeRenderTarget.root) {
5
        if (picture.drawModes[blend]) {
6
            var stage = renderer._lastObjectRendered;
7
            var f = stage._filters;
8
            if (!f || !f[0]) {
9
                setTimeout(function () {
10
                    var f = stage._filters;
11
                    if (!f || !f[0]) {
12
                        stage.filters = [Sprite.voidFilter];
13
                        stage.filterArea = new PIXI.Rectangle(0, 0, Graphics.width, Graphics.height);
14
                    }
15
                }, 0);
16
            }
17
        }
18
    }
19
};

ためしに、コンソールからSceneManager._scene.filters = [Sprite.voidFilter]と実行すると拡大されるのでOVERLAYフィルタの問題ではなく、このvoidFilterの影響だと考えられます。

voidFilterのpadding?

pixi.jsのfilterにはpaddingというメンバがあります。これはデフォルトで4に設定されていて、このpaddingを0に変えると拡大がなぜか直ります・・・。

pixi.jsのバージョンについて

この現象ですが最新のchromeでゲームをブラウザで起動しても発生します。
また、pixi.jsの4.7.1以降だと発生せず、4.7.0だと発生します(MVは4.5.4)。

解決策

paddingを0にするプラグインを作成しました。私のPCではこれで解決します。
また、これを適用してリリースして頂いたプロダクトは特に問題の報告もないようです。

VoidFilterPadding.js

コンフィグ画面を右クリックで戻るようにするプラグイン

はじめに

セーブやロード画面は右クリックで前の画面に戻れるのですが、独自に作ったコンフィグ画面に関してはそうはなりません。
コンフィグ画面も右クリックで戻れるようにしたいとの要望で作ったプラグインです。
ティラノスクリプト バージョン471bで動作を確認しています。

概要

コンフィグ画面から右クリックで戻るを実現するには、右クリックを押した時に、画面上の戻るボタンが押されたのと同じ動作をすれば良いです。そのためのプラグインを作りました。

ダウンロードはこちら
いろいろ入っていますがrightClickButtonというフォルダが今回のプラグインです。

画面上のボタンのnameにrightClickButtonを設定すると、右クリック時にそのボタンが押されたのと同じ動作になります。

設定例

1
[button graphic="back.png" name="rightClickButton" fix=true target="backtitle" x=800 y=100]

すでにname属性を使用している場合は、以下のように,で区切って指定してください。
name="test,rightClickButton"

ライセンス

Released under the MIT license

メニューとマップのスクリーンショットについて

メニューの背景のマップ画像

以下の画像のようにメニューの背景にはマップが映っています。
しかし、この画像は実際のマップではなくただの画像です。
メニューを開く瞬間にスクリーンショットが撮られ、それをぼかして表示しているだけです。

メニューの裏に表示されているマップ

ツクールはシーンが2つ以上存在するような構造になってなく、別のシーンに遷移したときに前のシーンは破棄されます。
マップからメニューやショップ、メニューからスキル画面やアイテム画面に遷移したとき、シーンは破棄され、戻った時に作り直されます。
もちろんマップからメニューなどに遷移するときはそのマップの情報(キャラの位置、歩行ルートの進行状況、使用しているピクチャの情報など)は保持されますが、戻った時はその情報をもとにマップを組み立て直します。

イベントのテストでエラーになるプラグインのケース

イベントのテストとは

ツクールMVにはイベントのテストという機能があります。
以下のようにイベントコマンドを右クリックすると表示される「テスト」です。

イベントのテスト

自分でプラグイン作っていてもテストするとき考慮が漏れるのですが、このイベントのテストを使用時のみエラーになるケースがあり、何度か対応しています。

普通の場合と何が違うか

マップのメモ欄が取得できません。
$dataMap.metaundefinedのため、metaが存在する前提で作るとエラーが発生します。
そのため、metaの存在チェックをする必要があります。プラグインを作る際、これに注意が必要です。

ロードした結果が異なる場合がある

発生条件

この動画のようにセーブしてすぐにロードするとイベントの位置は変わらないですが、一度ゲームを落としてエディタを保存してからロードするとイベントの位置が元に戻ります。VXAceも同様です。

昔のツクール(RPGツクール3とか)だとイベントの位置は保存されないので、ロード時にイベントの位置が元に戻るのに違和感はないかもしれませんが、今回のように場合によって結果が異なるのはどういうことかと。

解説

実は内部でバージョンを管理していて、保存をすると作成中のゲームのバージョンが上がります(System.jsonのversionIdです)。
バージョンといってもランダムな7桁の数字で、例えば77819147だったり2368236だったりします。  
このバージョンが肝で、バージョンが変わったらロード時にマップを初期化し直すということをします(マップ移動し直すと同じ挙動)。

  • バージョンが変わらない例 セーブ→すぐにロード
    この場合バージョンは変わらないのでマップは前回保存時のものをそのまま使用します。
  • バージョンが変わる例 セーブ→ゲームを落とす→エディタで保存→ゲーム起動してロード
    この場合、バージョンは変わるのでマップは前回保存時をリセットし、読み込み直します。

なぜ、バージョンが変わったらマップを読み込み直すのか?
新しくイベントを追加した場合、ロード時にそれを読み込みたいからか?

エディタで保存したらバージョンは変わるので、デプロイしたあとは意識しなくて良いかと思ったのですが、アップデートしたときにバージョン変わるので注意が必要です。

最近作ったティラノスクリプトのプラグインとマクロ

はじめに

最近頼まれて作ったティラノスクリプトのプラグインとマクロたちをまとめました。
限定的な用途のものも結構あります。
ティラノスクリプト バージョン471bで動作を確認しています。

自動的に喋っているキャラが前面に来るプラグイン

chara_configタグを使うと喋っているキャラの明るさを変えるような演出はできます。
それに加えて、喋っているキャラを前面にする機能を追加します。
喋っているキャラのz-indexをキャラ内で最大にします。

ダウンロードはこちら
targetFocusZIndexというフォルダが自動的に喋っているキャラが前面に来るプラグインです。

導入するだけで機能は有効になりますが、On、Offする機能があります。
・OFFにしたいとき
[offTargetFocusZIndex]

・OFFからONにしたいとき
[onTargetFocusZIndex]

アニメーション待ちのカウントを0にしてフリーズを抑止するマクロ

前にアニメーション待ちのwaタグでフリーズするケースで説明しました。
waタグはアニメーションしている数が0になるまで待つタグですが、そのアニメーションしている数が0にならないケースが存在し、フリーズします。
そこで、強制的にこの数を0にするのがこのマクロです。
シーンの遷移時に呼ぶことによって、アニメーションが完了しない不慮の事態を別のシーンに持ち越すことがなくなります。

1
[macro name="clearAnimCount"]
2
[eval exp="TYRANO.kag.tmp.num_anim=0"]
3
[endmacro]

cmだとbuttonが全て消えてしまうので、一部だけ消すマクロ

buttonタグはすべてフリーレイヤーに配置され、cmタグを呼ぶことによって消去されます。
しかし、一部のボタンだけ消したいケースがあったため、buttonタグのnameを指定してbuttonを消すマクロを用意しました。

1
[macro name="cfl"]
2
[iscript]
3
var fl = TYRANO.kag.layer.getFreeLayer();
4
if(mp.include) {
5
  fl.find("." + mp.include).remove();
6
}else if(mp.exclude){
7
  fl.find(":not(." + mp.exclude + ")").remove();
8
}
9
[endscript]
10
[endmacro]

例えば、以下のようなbuttonタグがあったとき、group1のボタンだけ消したい場合は、
[cfl include="group1"] とします。
逆にgroup1以外を消したい場合は、
[cfl exclude="group1"] とします。

1
[button graphic="button1.png" x="100" y="100"  target="t1" name="btn1,group1"]
2
[button graphic="button1.png" x="100" y="200"  target="t2" name="btn2,group1"]
3
[button graphic="button1.png" x="100" y="300"  target="t3" name="btn3,group2"]
4
[button graphic="button1.png" x="100" y="400"  target="t4" name="btn4,group2"]

キャラのz-indexを変えるマクロ

chara_showでキャラを登場時にz-indexを指定することはできますが、途中で変えたいという要望に対応したマクロです。

1
[macro name="charaZIndex"]
2
[iscript]
3
if(mp.name && mp.z){
4
  $("." + mp.name).css('z-index', mp.z);
5
}
6
[endscript]
7
[endmacro]

マクロは以下のように使います。
[charaZIndex name="akane" z=10]

buttonホバー時にx,y座標を変えるプラグイン

buttonタグのホバー時にx,y座標を変更するプラグインです。
buttonタグのパラメータに enterimgXとenterimgYを追加。
座標は現在座標からの相対位置になります。

使用例:
[button x=100 y=150 graphic="button1.png" target="gamestart" enterimg="button2.png" enterimgX="-20" enterimgY="-10"]

ダウンロードはこちら
enterimgExtensionというフォルダがbuttonホバー時にx,y座標を変えるプラグインです。

すべてのボタンのクリックを抑止するプラグイン

画面に透明な壁を作り、ボタンなどのクリックを吸収し、すべてのボタンに対するクリックを無効にします。

[preventClick] で発動し、[preventClick off=true] で解除です。

ダウンロードはこちら
preventClickというフォルダがすべてのボタンのクリックを抑止するプラグインです。

ボタンクリック時にウェイトを挟むので、その間ボタンを連打できなくするプラグイン

ボタンをクリックしてすぐに遷移するのではなく、アニメーションをしてから遷移したいというニーズに対応したときに作ったプラグイン。
以下のようにアニメーションしてウェイト挟んでからjumpするようなイメージ。
この場合、ウェイト中にボタンをクリックすると何度もイベントが発行されてしまい困るということです。

1
[anim name="anim" left="+=300" opacity="255" effect="jswing" time=1000]
2
[wait time=1000]
3
[jump storage=scene.ks]

waitと同じ機能でbuttonタグのクリックを無効にするwaitNoClickタグを追加しました。
ただし、role指定のbuttonには対応していません。

1
[anim name="anim" left="+=300" opacity="255" effect="jswing" time=1000]
2
[waitNoClick time=1000]
3
[jump storage=scene.ks]

ダウンロードはこちら
waitNoClickというフォルダがウェイト中にボタンを連打できなくするプラグインです。

ライセンス

Released under the MIT license

Vectrosityを使ってUGUI上で線や円のアニメーションをする

Vectrosity

アセットストアで販売されているVectrosity - Asset Storeを使うと、UGUI上に線や円といった図形を描画することができます。
今回はVectrosityを使ってアニメーションを作成します。
例えば、以下のように円の大きさを変えてみたり、

Sound

線の終点を変えてレーダーのような表現といったことができます。

レーダー

ちなみにUGUI上に線や円を描くのに「uGUI でプリミティブな図形を描画できる「UIGraphicAPI」紹介」にあるようにGithubで公開されているものもあります。最初これを使っていたのですが、アニメーションしようとするとパフォーマンスがすごい落ちるのでVectrosityに変えました。

Vectrosityのオブジェクトを作る

アセットをインポートしたら、Create->UI->VectorLineでオブジェクトを作成できます。

UI VectorLine

作成するとCanvasが作られ、中にLineオブジェクトが作られます。Canvasは普通のUGUIのCanvasなのでここで重要なのはLineの方です。

VectorCanvas

LineオブジェクトにはVectorObject2Dコンポーネントがついていて、これをいじって線にしたり円にしたりアニメーションしたりします。スクリプト側からいじりますが、線の太さや色などデフォルトで決めておきたい場合は設定しておいても良いです。

VectorObject2D

円のアニメーション

小さい円からだんだん大きくなる円をつくります。
以下のソースコードで示すとおりです。

1
using System.Collections.Generic;
2
using UnityEngine;
3
using Vectrosity;
4
5
public class MakeCircle : MonoBehaviour {
6
7
  VectorObject2D line;
8
9
  void Start() {
10
    var points = new List<Vector2>();
11
    //20は円の頂点の数。多くすればよりなめらかになる。
12
    //ここでは位置を考えずに頂点を作成するだけ。
13
    for (var i = 0; i < 20; i++) {
14
      points.Add(Vector2.zero);
15
    }
16
    line = GetComponent<VectorObject2D>();
17
    //VectorObject2d.vectorLineが線の情報を持つ本体。頂点情報をここで代入
18
    line.vectorLine.points2 = points;
19
  }
20
21
  void Update() {
22
    //MakeCircleの引数は、原点、半径、頂点数。頂点数は上で作成した数-1を指定する
23
    line.vectorLine.MakeCircle(Vector3.zero, Time.time * 10, line.vectorLine.points2.Count - 1);
24
    //再描画
25
    line.vectorLine.Draw();
26
  }
27
}

線のアニメーション

線に関しては頂点の位置を自由に変えればいいだけなので、特に書くことはない。
デフォルトで頂点は2つ作られているので以下のようにすれば線は引ける。

1
lLine.vectorLine.points2[0] = new Vector2(0, 0);
2
line.vectorLine.points2[1] = new Vector2(100, 100);
3
line.vectorLine.Draw();

プラグインの使用状況を出すプラグイン

概要

pluginsフォルダに入っているプラグインの使用状況を以下のように出力します。

  1. 「プラグイン管理」に登録してないONでもOFFでもない、pluginsフォルダに入っているだけのプラグイン
  2. ON状態のプラグイン
  3. OFF状態のプラグイン

使用状況

ダウンロード

動作バージョン: RPGツクールMV1.6以上

こちら

導入して起動するとコンソールに出力されます。

ライセンス

Released under the MIT license

装備を記憶、ロードするプラグイン

概要

アクターの装備を一度記憶し、それをロードできるプラグインを作りました。
使用例としては、着せ替えゲームを作ったときにコーディネートを複数保存するということができます。
あるいは敵に装備を奪われ、取り返したときに復元するみたいなこともできます。

仕様

変数の管理みたいに保存領域を用意します。
例えば、1番にはアクター1の装備を保存、2番にはアクター3の装備を保存ということができます。
記憶したアクター1の装備をアクター3にロードするということができるようにします。
ロード時に所持品に該当装備があれば装備し、ない場合は装備なし状態になります。
ただし、パーティにそれを装備しているアクターがいた場合、それを奪うかどうか設定できます。
当然、アクター1の装備をアクター3にロードしたとき、装備できない装備は装備されません。
ゲームのセーブ・ロードに対応。

プラグインコマンド

記憶

  • SaveEquips arg0 arg1

    arg0はアクター番号、arg1は保存先番号
    例: SaveEquips 1 1
    引数には変数の制御文字が使えます。
    例: SaveEquips \V[3] \V[4]

ロード

  • LoadEquips arg0 arg1 arg2

    arg0はアクター番号、arg1は保存元番号、arg2は所持品に装備がない場合にパーティの装備を奪うか(0か指定なしは奪わない、1は奪う)
    例: LoadEquips 1 1
    例: LoadEquips 1 1 1
    引数には変数の制御文字が使えます。
    例: LoadEquips \V[3] \V[4]

ダウンロード

RPGツクールMV1.6以上にのみ対応。1.5は対応していません。

こちら

ライセンス

Released under the MIT license