AviUtl Luaスクリプト完全ガイド:始め方から応用までを紹介
はじめに:AviUtlとLuaスクリプトの世界へようこそ
AviUtlは、その軽量さ、拡張性の高さから、多くの動画編集ユーザーに愛用されているフリーソフトです。特に、多機能な「拡張編集」プラグインと組み合わせることで、プロにも劣らない高度な編集が可能になります。
しかし、AviUtlの真髄とも言える機能の一つが、Luaスクリプトによる拡張です。Luaスクリプトを利用することで、AviUtlの標準機能だけでは実現できない、独自の描画効果、トランジション、フィルタ、さらには高度なアニメーションやデータ処理までもが可能になります。
「スクリプト」と聞くと難しそうに感じるかもしれませんが、Lua言語は比較的学習しやすく、AviUtlでの利用に特化されたAPIもシンプルに設計されています。この記事では、AviUtlのLuaスクリプトを全く知らない初心者の方でも、基本的なスクリプト作成から一歩進んだ応用テクニックまでを習得できるよう、詳細かつ網羅的に解説していきます。
AviUtlでの表現力を飛躍的に向上させたい方、既存のスクリプトを改造してみたい方、あるいは自分だけのオリジナル効果を作ってみたい方は、ぜひこの記事を最後まで読んで、Luaスクリプトの世界に飛び込んでみてください。
第1部:Luaスクリプトを始める準備
AviUtlでLuaスクリプトを扱うためには、いくつかの準備が必要です。まずは必要なソフトウェアの確認と導入、そして開発環境の準備を行いましょう。
1.1 必要なもの
- AviUtl本体: AviUtlの公式ページから最新版をダウンロードしてください。
- 拡張編集Plugin: 必須です。AviUtl本体と合わせてダウンロードし、AviUtlフォルダ内に配置してください。Luaスクリプトの実行環境は拡張編集によって提供されます。
- L-SMASH Works File Reader: 入出力プラグインとして推奨されます。特に、MP4などのモダンな動画形式を扱う際に必要になります。導入方法についてはAviUtl関連の解説サイトを参照してください。
- LuaJIT(推奨): これは必須ではありませんが、Luaスクリプトの実行速度を劇的に向上させる可能性があります。特に複雑な計算や描画を伴うスクリプトでは効果が顕著です。
1.2 LuaJITの導入
LuaJITは、標準のLua処理系よりも高速に動作するJIT (Just-In-Time) コンパイラを内蔵したLua実行環境です。AviUtlの拡張編集は、設定によって標準LuaとLuaJITのどちらを使用するか選択できます。LuaJITを使用するためには、通常、lua51.dll
というファイルが必要です。
- AviUtl同梱版: 最近のAviUtl本体や拡張編集の配布物には、すでにLuaJITに必要なファイル(
lua51.dll
など)が含まれていることが多いです。この場合、特に自分でファイルをダウンロードする必要はありません。AviUtlフォルダ内にlua51.dll
が存在するか確認してください。 - 独自導入: もしAviUtlフォルダに
lua51.dll
がない場合や、特定のバージョンを使用したい場合は、LuaJITの公式ページや配布サイトからWindows用のバイナリを入手し、lua51.dll
をAviUtlフォルダ内に配置します。
導入のメリット:
* スクリプトの実行速度向上:特にループ処理や数値計算が多いスクリプトで効果を発揮します。
* FFI (Foreign Function Interface) の利用:C言語の関数などをLuaから直接呼び出すことが可能になります(これは高度な応用です)。
設定:
拡張編集の設定ダイアログ(AviUtlのメニューから「ファイル」→「環境設定」→「拡張編集設定」)を開き、「システムの設定」タブを探してください。ここに「LuaJITを使用する」といったチェックボックスがあれば、それにチェックを入れることでLuaJITが有効になります。チェックボックスがない場合や、LuaJITが同梱されている最新版を使用している場合は、デフォルトで有効になっているか、特別な設定が不要な場合があります。
1.3 スクリプトファイルの設置場所
AviUtlのLuaスクリプトファイルは、特定のフォルダに配置する必要があります。
- スクリプトフォルダ: AviUtlフォルダ内の
script
フォルダに.lua
ファイルを配置します。拡張編集は、このフォルダとそのサブフォルダを検索してスクリプトを認識します。 - カテゴリ分け:
script
フォルダ内にさらにサブフォルダを作成することで、スクリプトをカテゴリ分けして管理できます。例えば、script/描画/
やscript/フィルタ/
といったフォルダを作成し、関連するスクリプトをそこに格納することで、AviUtlのオブジェクト追加メニューやフィルタメニューで整理されて表示されるようになります。
1.4 開発環境の準備
Luaスクリプトを効率的に記述するためには、適切なテキストエディタを使用することを強く推奨します。
- 高機能テキストエディタ:
- VS Code: 無料で非常に高機能なエディタです。Lua用の拡張機能(Syntax Highlighting, Linting, Debuggingなど)が豊富にあります。「Lua」や「LuaJIT」で検索してインストールしてください。AviUtlスクリプトに特化したシンタックスハイライトや入力補完を提供する拡張機能も存在します。
- Notepad++: 軽量で多機能な無料エディタです。Luaのシンタックスハイライトに対応しています。
- Sublime Text, Atom, Sakura Editorなど: これらも人気のある高機能エディタで、Luaに対応しています。
推奨設定 (VS Codeの例):
1. Lua拡張機能のインストール: VS CodeのExtensionsビューで「Lua」と検索し、評価の高い拡張機能(例: Lua、LuaJIT)をインストールします。
2. コード補完とLinter: 拡張機能の設定で、LuaJIT固有の関数やAviUtlスクリプトの組み込み変数(obj
, track0
など)に対する補完やLinter(構文エラーや怪しいコードを指摘してくれる機能)を有効にできる場合があります。AviUtlスクリプトのAPI定義ファイルを読み込ませる設定があれば、より正確な補完やチェックが可能になります。
3. 文字コード: AviUtlは通常、Shift_JISで動作しますが、LuaスクリプトファイルはUTF-8(BOMなし)で保存するのが一般的です。スクリプト内で日本語文字列を扱う場合は、エンコーディングに注意が必要です。VS Codeなどのエディタでは、ファイルのエンコーディングを簡単に設定できます。
デバッグツール:
簡単なデバッグには、スクリプト内で print()
関数を使って変数の中身や処理の経過をメッセージとして表示させるのが手軽です。AviUtlの拡張編集ウィンドウの右クリックメニューに「スクリプト出力ウィンドウを開く」という項目があり、ここに print()
で出力した内容が表示されます。より高度なデバッグは、専用のデバッグツールが必要になりますが、まずは print()
から始めましょう。
これで、AviUtlでLuaスクリプトを作成・実行するための基本的な準備が整いました。
第2部:Luaスクリプトの基本
Luaはシンプルで軽量なスクリプト言語です。AviUtlのスクリプトとして使用する場合も、基本的なLuaの文法に加えて、AviUtlが提供する特定の変数や関数(API)を組み合わせて記述します。
2.1 Lua言語の基礎の基礎
AviUtlスクリプトを書く上で最低限知っておきたいLuaの基本要素を説明します。
-
コメント:
- 単一行コメント:
--
の後に続く文字列はその行のコメントとして無視されます。
lua
-- これはコメントです - 複数行コメント:
--[[
から--]]
で囲まれた範囲がコメントとして無視されます。
lua
--[[
これは
複数行の
コメントです
--]]
- 単一行コメント:
-
変数: 変数はデータを格納するための名前付きの場所です。型宣言は不要で、代入によって型が決まります。
lua
local x = 10 -- 数値
local name = "AviUtl" -- 文字列
local is_active = true -- 真偽値 (true/false)
local data = { -- テーブル (配列や連想配列)
value = 123,
text = "hello"
}
local nothing = nil -- nil (値がないことを示す)
local
キーワードをつけると、その変数は定義されたブロック内でのみ有効なローカル変数になります。グローバル変数はlocal
なしで定義できますが、意図しない変数名の衝突を避けるため、可能な限りlocal
を使用するのが良い習慣です。 -
データ型:
number
: 数値。整数も浮動小数点数も区別なく扱われます(内部的には主に倍精度浮動小数点数)。string
: 文字列。ダブルクォート"
またはシングルクォート'
で囲みます。boolean
: 真偽値。true
またはfalse
です。table
: テーブル。Luaで最も重要な構造化データ型です。配列、ハッシュテーブル(連想配列)、オブジェクトなど、様々な用途に使われます。{}
で作成します。function
: 関数。thread
: コルーチン。userdata
,lightuserdata
: 外部データ。nil
: 値がないことを示す特別な値。
-
演算子:
- 算術演算子:
+
,-
,*
,/
(浮動小数点除算),%
(剰余),^
(べき乗) - 比較演算子:
==
(等しい),~=
(等しくない),<
,>
,<=
,>=
- 論理演算子:
and
(かつ),or
(または),not
(否定) - 文字列連結演算子:
..
(ドット2つ)
lua
local a = 10
local b = 5
local c = a + b -- 15
local d = "hello" .. "world" -- "helloworld"
local is_greater = a > b -- true
local result = true and false -- false
- 算術演算子:
-
制御構造:
- if文: 条件によって処理を分岐させます。
lua
if score >= 90 then
print("Excellent")
elseif score >= 70 then -- elseif は複数書けます
print("Good")
else
print("Needs improvement") -- else は省略可能です
end - forループ:
- 数値forループ: 指定した範囲で繰り返します。
lua
for i = 1, 5 do -- 1から5まで (iは1, 2, 3, 4, 5 と変化)
print(i)
end
for j = 10, 1, -2 do -- 10から1まで、ステップは-2 (jは10, 8, 6, 4, 2 と変化)
print(j)
end -
汎用forループ: テーブルの要素などを順に処理します。
“`lua
local colors = {“red”, “green”, “blue”}
for index, value in ipairs(colors) do — 配列部分を順に処理 (indexは1, 2, 3)
print(index .. “: ” .. value)
endlocal person = { name = “Alice”, age = 30 }
for key, value in pairs(person) do — 連想配列部分も含めて処理 (順序は保証されない)
print(key .. “: ” .. value)
end
* **whileループ:** 条件が真の間繰り返します。
lua
local count = 0
while count < 3 do
print(“Count: ” .. count)
count = count + 1
end
* **repeat-untilループ:** 条件が真になるまで繰り返します(少なくとも1回は実行されます)。
lua
local i = 0
repeat
print(“i: ” .. i)
i = i + 1
until i >= 5
“`
- 数値forループ: 指定した範囲で繰り返します。
- if文: 条件によって処理を分岐させます。
-
関数: 処理をひとまとめにして名前を付けたものです。
“`lua
function greet(name) — 関数を定義
print(“Hello, ” .. name .. “!”)
endgreet(“Bob”) — 関数を呼び出し (出力: Hello, Bob!)
function add(a, b)
return a + b — 値を返すこともできます
endlocal result = add(3, 5) — result は 8 になります
“`
関数の引数や戻り値は複数指定することも可能です。 -
テーブル: Luaの核となるデータ構造です。配列のようにインデックスでアクセスしたり、連想配列のようにキー(文字列や数値)でアクセスしたりできます。
“`lua
local list = {“apple”, “banana”, “cherry”} — 配列 (インデックスは1から始まる)
print(list[1]) — “apple”
print(list[2]) — “banana”
print(#list) — 要素数 (3)local dict = { name = “Charlie”, city = “Tokyo” } — 連想配列
print(dict[“name”]) — “Charlie”
print(dict.city) — “Tokyo” (キーが文字列の場合はドット演算子も使える)local nested = {
info = { id = 101, status = “active” },
items = {“pen”, “book”}
}
print(nested.info.id) — 101
print(nested.items[1]) — “pen”
“`
2.2 AviUtlスクリプトの基本構造
AviUtlの拡張編集がLuaスクリプトを実行する際には、いくつかの特別な変数や関数が提供されます。スクリプトはこれらの変数や関数を使って、オブジェクトの状態を取得したり、描画を行ったりします。
Luaスクリプトファイルは通常、exedit.lua
(拡張編集のメインファイル) によって特定のタイミングで読み込まれ、実行されます。スクリプトの種類によって実行されるタイミングや目的が異なりますが、基本的には描画オブジェクト1フレームあたり1回実行されるものが最も一般的です(描画スクリプト)。
描画スクリプトの基本的な実行の流れは次のようになります。
1. 拡張編集が描画するオブジェクトを見つける。
2. そのオブジェクトのLuaスクリプトが指定されている場合、スクリプトファイルを読み込む(初回のみ)。
3. オブジェクトの現在のフレームに対して、スクリプトのメイン部分を実行する。
4. スクリプトは obj
テーブルなどを介して、そのオブジェクトの位置、回転、透明度などの情報を取得し、必要であれば描画処理を行う。
5. 次のフレームに進むか、別のオブジェクトの描画に移る。
最も基本的な描画スクリプトの構造を見てみましょう。
“`lua
–[[
@描画
–]]
— スライダーなどのパラメータを受け取る変数
track0 = track0 — スライダー0の値 (デフォルトは0-100)
track1 = track1 — スライダー1の値
track2 = track2 — スライダー2の値
track3 = track3 — スライダー3の値
— obj テーブル: オブジェクトの状態と描画関数を提供する
— obj.ox, obj.oy, obj.oz: オブジェクトの中心座標 (ピクセル)
— obj.zoom: 拡大率 (%)
— obj.rotx, obj.roty, obj.rotz: 回転角度 (度)
— obj.alpha: 不透明度 (0-255)
— obj.blend: 合成モード
— obj.sx, obj.sy, obj.sz: ローカル座標系での拡大率
— obj.rx, obj.ry, obj.rz: ローカル座標系での回転角度
— time 変数: 現在の再生時間 (秒)
— frame 変数: 現在のフレーム数 (0から始まる)
— frame_last 変数: オブジェクトの最終フレーム数
— obj.frame, obj.frame_last も同義として使えることが多い
— ここから描画処理や計算を行うメインのコード
— オブジェクトの位置を操作する例
— obj.ox = obj.ox + math.sin(frame * 0.1) * 10 — 横に揺らす
— 図形を描画する例
— setfigure(“circle”, 0, 0, 50) — 中心(0,0)に半径50の円を描画
— テキストを描画する例
— setfont(“Meiryo UI”, 20)
— drawtext(“Hello, AviUtl!”, 0, 0)
— この部分がフレームごとに実行される
— 何も書かないと、オブジェクト自体(画像など)が通常通り描画される
— スクリプト内で描画関数 (setpixel, drawtextなど) を使うと、
— オブジェクト自体の描画は抑止され、スクリプトによる描画のみになる場合が多い
“`
重要な変数とテーブル:
-
obj
: これがAviUtlスクリプトの中核です。現在のオブジェクトの状態(位置、回転、拡大率、透明度など)を取得・設定するためのプロパティや、描画を行うための関数が含まれています。obj.ox
,obj.oy
,obj.oz
: オブジェクトの中心座標(X, Y, Z)。これらの値を変更すると、オブジェクト全体の位置が移動します。座標系の詳細は後述。obj.zoom
: 拡大率 (%)。obj.rotx
,obj.roty
,obj.rotz
: 回転角度(X, Y, Z, 度)。obj.alpha
: 不透明度(0-255)。0が完全透明、255が完全不透明。obj.blend
: 合成モード(0: 通常, 1: 加算, 2: 乗算, 3: 減算, 4: スクリーン, 5: オーバーレイ, 6: 比較明, 7: 比較暗, 8: 差分, 9: 除外, 10: ハードライト, 11: ソフトライトなど)。obj.disp
: オブジェクトの表示/非表示 (true/false)。obj.layer
: オブジェクトが配置されているレイヤー番号。obj.camera
: カメラ制御が有効かどうか (true/false)。obj.width
,obj.height
: オブジェクトの元のサイズ(画像や動画の場合)。obj.frame
,obj.frame_last
: 現在のフレームと最終フレーム。
-
track0
,track1
,track2
,track3
: これらは拡張編集オブジェクトのパラメータ制御にあるスライダーに対応します。スクリプト冒頭でtrack0 = track0
のように記述することで、スライダーの値をスクリプト内で利用できるようになります。デフォルトでは0~100の範囲ですが、オブジェクト側の設定で範囲を変更できます。 -
time
: 拡張編集のタイムライン上の現在の再生時間(秒)です。オブジェクトの開始時点からの相対時間ではありません。 frame
: 拡張編集のタイムライン上の現在のフレーム数(0から始まる)です。オブジェクトの開始時点からの相対フレーム数ではありません。-
frame_last
: 拡張編集のタイムライン上の最終フレーム数です。オブジェクトの最終フレームとは異なります。obj.frame_last
はオブジェクトの最終フレーム数を示します。混乱しやすいので注意が必要です。通常、オブジェクトの時間に依存する処理はobj.frame
とobj.frame_last
を使います。 -
描画関数:
obj
テーブルの一部として、またはグローバル関数として提供されます(バージョンや設定による)。例:setpixel(x, y, col)
: 指定座標にピクセルを描画。getpixel(x, y)
: 指定座標のピクセル色を取得。setfigure(type, x, y, ...)
: 図形を描画。drawtext(text, x, y)
: テキストを描画。setfont(name, size)
: フォント設定。setcolor(r, g, b, a)
: 描画色を設定。
スクリプトの種類:
Luaスクリプトは、ファイルの冒頭にコメント形式で記述されたタグによって種類が認識されます。
@描画
: 描画スクリプト。オブジェクトの表示内容を生成します。最も一般的です。フレームごとに実行され、setpixel
やdrawtext
などの描画関数を使って出力画像を生成します。@フィルタ
: フィルタスクリプト。入力画像を加工して出力します。画像全体や指定範囲に対してピクセル操作を行うのに使われます。@トランジション
: トランジションスクリプト。二つのオブジェクト間を補間するような効果を作成します。- その他、
@オブジェクト
(カスタムオブジェクト),@メディア
,@出力
などがありますが、これらはより高度な用途になります。
この記事では主に @描画
スクリプトを中心に解説しますが、基本的な考え方は他の種類にも応用できます。
2.3 最初のスクリプトを書いてみる
それでは、実際に簡単なスクリプトを書いてAviUtlで実行してみましょう。
例1: 中心に点を描画するスクリプト
“`lua
–[[
@描画
中心に点を描画するサンプルスクリプト
–]]
— AviUtlのオブジェクトの中心座標は obj.ox, obj.oy で取得できる
— setpixel(x, y, col) で点を描画する
— x, y は描画座標。基準はオブジェクトの中心 (obj.ox, obj.oy)
— col は色。16進数で 0xRRGGBB または 0xAARRGGBB の形式。
local center_x = 0 — オブジェクト中心を基準としたX座標
local center_y = 0 — オブジェクト中心を基準としたY座標
local red_color = 0xFF0000 — 赤色 (FF=R, 00=G, 00=B)
setpixel(center_x, center_y, red_color) — 中心に赤い点を描画
“`
- 上記のコードをテキストエディタにコピー&ペーストします。
- 文字コードをUTF-8 (BOMなし) で保存します。
- ファイル名を
red_dot.lua
とし、AviUtlフォルダ内のscript
フォルダ、またはその中のサブフォルダ(例:script/MyScripts/
)に保存します。 - AviUtlを起動(または再起動)します。
- 拡張編集ウィンドウを開き、タイムライン上の何もない場所を右クリックし、「メディアオブジェクトの追加」→「スクリプト制御」を選択します。
- 追加された「スクリプト制御」オブジェクトを選択し、設定ダイアログを表示します。
- 設定ダイアログの上部にある「スクリプトファイル」のドロップダウンリストを開くと、先ほど保存した
red_dot.lua
が表示されているはずです。これを選択します。 - プレビューウィンドウや拡張編集ウィンドウを確認すると、オブジェクトの中心位置に赤い点が描画されているのが見えます。
このスクリプトは、オブジェクトが配置されている場所(obj.ox
, obj.oy
によって決まる画面上の位置)を中心として、ローカル座標 (0, 0)
に赤い点を描画しています。
例2: 時間によって色が変化する円を描画するスクリプト
スライダー (track
) と時間 (obj.frame
) を使ってみましょう。
“`lua
–[[
@描画
時間とスライダーで色が変化する円
–]]
— スライダー0 (track0) を色の変化速度として使う
track0 = track0 or 0 — track0がnilの場合に0を代入する安全策
— 現在のオブジェクトフレームを取得
local current_frame = obj.frame
local max_frame = obj.frame_last
— フレーム数に基づいて色を計算
— 0からmax_frameまでフレームが変化するにつれて、色が周期的に変化するようにする
— sin関数を使うと、-1から1の間で周期的に変化する値が得られる
local t = current_frame / max_frame — 0から1まで変化する値
— 色の成分を時間によって変化させる
— 例: 赤 -> 緑 -> 青 -> 赤 のように変化させる
local r, g, b
if t < 1/3 then
— 赤から緑へ (t=0 -> t=1/3)
r = 1 – t * 3
g = t * 3
b = 0
elseif t < 2/3 then
— 緑から青へ (t=1/3 -> t=2/3)
r = 0
g = 1 – (t – 1/3) * 3
b = (t – 1/3) * 3
else
— 青から赤へ (t=2/3 -> t=1)
r = (t – 2/3) * 3
g = 0
b = 1 – (t – 2/3) * 3
end
— スライダー0で変化速度を調整する (例: スライダー値 / 100 を掛ける)
— これは色の計算方法によるが、今回は単純に色の強さを調整してみる
local speed_factor = track0 / 100.0
r = r * speed_factor
g = g * speed_factor
b = b * speed_factor
— 色の値を0から1の範囲にクランプする (念のため)
r = math.max(0, math.min(1, r))
g = math.max(0, math.min(1, g))
b = math.max(0, math.min(1, b))
— 色を16進数形式に変換 (0xRRGGBB)
local color = math.floor(r * 255) * 0x10000 +
math.floor(g * 255) * 0x100 +
math.floor(b * 255)
— setcolor関数で描画色を設定
setcolor(math.floor(r * 255), math.floor(g * 255), math.floor(b * 255))
— setfigure関数で円を描画
— setfigure(“circle”, x, y, radius)
local center_x = 0 — オブジェクト中心基準
local center_y = 0
local radius = 50 — 半径50ピクセルの円
setfigure(“circle”, center_x, center_y, radius)
— スライダーの値によって円の大きさを変える例
— local radius = 20 + track1 * 0.8 — スライダー1が0-100なら、半径は20-100になる
— setfigure(“circle”, center_x, center_y, radius)
“`
- 上記のコードを
color_circle.lua
などの名前で保存します。 - AviUtlでスクリプト制御オブジェクトを追加し、このスクリプトを選択します。
- オブジェクト設定ダイアログに「スライダー0」が表示されているはずです。この値を変更したり、タイムラインを再生したりすると、円の色が変化する様子が確認できます。
この例では、Luaの制御構造 (if/elseif/else
)、算術演算、テーブル、そしてAviUtl固有の変数 (obj.frame
, obj.frame_last
, track0
) や関数 (setcolor
, setfigure
) を組み合わせています。
第3部:AviUtlスクリプトの詳細機能と応用
基本的な構造を理解したところで、さらに踏み込んだ機能と応用方法を見ていきましょう。
3.1 オブジェクト操作と座標系
AviUtlのオブジェクトは、位置、回転、拡大率などのプロパティを持っています。スクリプトからこれらのプロパティを操作することで、様々なアニメーションを実現できます。これらのプロパティは obj
テーブルを介してアクセスします。
-
位置:
obj.ox
,obj.oy
,obj.oz
(X, Y, Z座標)。これらの座標の基準は、画面中央を(0, 0)
とした座標系です。Z座標は奥行きを表します。値をフレームごとに変化させることで、オブジェクトを移動させることができます。
lua
-- 横に往復移動する
local move_range = 200 -- 移動範囲
local speed = 0.05 -- 速度
obj.ox = math.sin(obj.frame * speed) * move_range -- sin波を使って滑らかな往復移動 -
回転:
obj.rotx
,obj.roty
,obj.rotz
(X, Y, Z軸回りの回転角度、度数)。回転はローカル座標系(オブジェクトの中心を基準とした座標系)に対して適用されます。回転の中心は(obj.ox, obj.oy)
です。
lua
-- Z軸回りに回転させる
local rotate_speed = 5 -- 1フレームあたりの回転角度
obj.rotz = obj.frame * rotate_speed -- フレームが進むごとに角度を増やす -
拡大率:
obj.zoom
(%)。オブジェクト全体の拡大率です。
lua
-- 大きさを時間によって変化させる
local min_zoom = 50
local max_zoom = 150
local period = 60 -- 60フレームで一周
obj.zoom = min_zoom + (max_zoom - min_zoom) * (math.sin(obj.frame / period * math.pi * 2) * 0.5 + 0.5) -- sin波で滑らかに変化 -
ローカル座標系での拡大・回転:
obj.sx
,obj.sy
,obj.sz
,obj.rx
,obj.ry
,obj.rz
。これらはオブジェクト自体の変形ではなく、スクリプト内でsetpixel
やsetfigure
などの描画関数を使う際に適用されるローカル座標系に対する拡大・回転です。setpixel(100, 0, color)
と書いた場合、これはオブジェクトの中心からX方向に100ピクセル離れた点ですが、obj.sx
が2になっていれば、実際に描画される位置は200ピクセル離れた場所になります。描画スクリプトで複雑な図形を生成する際に便利です。
座標系の理解:
AviUtlの座標系は少し複雑です。
- ローカル座標系: スクリプト内で
setpixel
,setfigure
,drawtext
などを使う際の(x, y)
座標は、デフォルトではオブジェクトの中心(obj.ox, obj.oy)
を基準とした相対座標です。例えば、setpixel(100, 50, color)
は、オブジェクトの中心から右に100、下に50の位置に点を描画します。このローカル座標系はobj.sx
,obj.sy
,obj.sz
,obj.rx
,obj.ry
,obj.rz
の影響を受けます。 - ワールド座標系 (画面座標系): AviUtlのプレビューウィンドウ全体を指す座標系です。画面中央が
(0, 0)
で、右に行くほどX座標が増え、下に行くほどY座標が増えます。obj.ox
,obj.oy
はこのワールド座標系でのオブジェクトの中心位置を示します。 - カメラ座標系: カメラ制御を使用している場合に適用される座標系です。ワールド座標系をさらにカメラの位置や向きによって変換した座標系になります。
描画スクリプトで setpixel(x, y, col)
を使う場合、指定した (x, y)
はローカル座標です。このローカル座標は、obj.sx, obj.sy, obj.sz, obj.rx, obj.ry, obj.rz
によって変換され、さらに obj.ox, obj.oy, obj.oz
によってワールド座標に配置され、最後にカメラ変換が適用されて、最終的な画面上のピクセル位置が決まります。
ほとんどの場合、描画スクリプトではローカル座標 (0, 0)
をオブジェクトの中心として扱い、obj.ox, obj.oy
でオブジェクト全体を動かすという考え方で十分です。obj.sx
などを操作するのは、スクリプトで描画する図形自体を変形させたい場合に便利です。
3.2 描画機能の詳細
AviUtlスクリプトは、様々な描画関数を提供しています。
setcolor(r, g, b, a)
: 次に描画する図形やテキストの色を設定します。各成分は0~255の値です。a
はアルファ値(不透明度)で、0が完全透明、255が完全不透明です。
lua
setcolor(255, 0, 0) -- 赤色 (不透明)
setcolor(0, 255, 0, 128) -- 半透明の緑色setpixel(x, y, col)
: 指定したローカル座標(x, y)
に単一のピクセルを描画します。col
は16進数の色値 (0xRRGGBB または 0xAARRGGBB) です。
lua
setpixel(10, 20, 0xFFFF00) -- ローカル座標(10, 20)に黄色い点を描画-
getpixel(x, y)
: 指定したローカル座標(x, y)
のピクセル色を取得します。色は16進数の0xAARRGGBB形式で返されます。これは主にフィルタスクリプトや、描画スクリプトで前のフレームや他のオブジェクトの情報を利用する場合に使われます。
lua
local pixel_color = getpixel(0, 0) -- オブジェクト中心の色を取得
local alpha = (pixel_color >> 24) & 0xFF -- アルファ成分を取り出す
local red = (pixel_color >> 16) & 0xFF -- 赤成分
-- ... 他の成分も同様に取り出す
ピクセル操作は処理が重くなりがちなので注意が必要です。 -
setfigure(type, x, y, ...)
: 様々な図形を描画します。type
は描画する図形の種類を示す文字列です。"circle"
: 円。setfigure("circle", x, y, radius)
"rect"
: 四角形。setfigure("rect", x1, y1, x2, y2)
(対角線上の2点の座標)"line"
: 線分。setfigure("line", x1, y1, x2, y2)
"poly"
: 多角形(塗りつぶし)。setfigure("poly", x1, y1, x2, y2, x3, y3, ...)
"polys"
: 多角形(線のみ)。同上。"triangle"
: 三角形(塗りつぶし)。setfigure("triangle", x1, y1, x2, y2, x3, y3)
"ellipse"
: 楕円。setfigure("ellipse", x, y, radius_x, radius_y)
"roundrect"
: 角丸四角形。setfigure("roundrect", x1, y1, x2, y2, round)
(roundは角丸の半径)
lua
setfigure("circle", 0, 0, 100) -- 中心に半径100の円
setfigure("rect", -50, -50, 50, 50) -- 中心に一辺100の四角形
setfigure("line", -100, -100, 100, 100) -- 左上から右下への線
setfigure
で描画される図形の色は、setcolor
で最後に設定された色が使われます。 -
setfont(name, size, style)
: 次に描画するテキストのフォントを設定します。name
: フォント名 (例:"Meiryo UI"
,"Arial"
)size
: フォントサイズ (ピクセル)style
: スタイルを示す数値 (0:通常, 1:太字, 2:斜体, 3:太字+斜体)。省略可。
lua
setfont("メイリオ", 30)
setfont("Arial", 40, 1) -- 太字のArial
-
drawtext(text, x, y)
: 指定したローカル座標(x, y)
にテキストを描画します。text
は表示する文字列です。setfont
で設定したフォントと、setcolor
で設定した色が使われます。x
,y
はテキストの左上隅の座標となります。
lua
setfont("MS ゴシック", 24)
setcolor(255, 255, 255) -- 白
drawtext("Luaスクリプトテスト", -200, -100) -- 中心から左上あたりに描画
日本語文字列を扱う際は、スクリプトファイルをUTF-8 (BOMなし) で保存しているか確認してください。 -
obj.drawalpha(alpha)
: オブジェクト全体の透明度を指定します。alpha
は0~255の値です。obj.alpha
と似ていますが、こちらは描画関数内で一時的に透明度を変更したい場合などに使えます。
3.3 画像・動画・音声の取得と処理
AviUtlスクリプトは、現在のフレームの画像データや音声データを取得して利用することができます。
-
getvideo(x, y)
: 指定したローカル座標(x, y)
のピクセル色を取得します。これはgetpixel
と同じように見えますが、getvideo
はスクリプト制御オブジェクトが配置されているレイヤーよりも「下」にあるレイヤーの内容を取得します。これにより、下のレイヤーの画像に対してエフェクトをかけたり、その情報に基づいて描画を変えたりできます。フィルタスクリプトでは入力画像の色を取得するのに使われます。
“`lua
— 下のレイヤーのピクセル色を取得して、それを元に何か描画する例
local px, py = 0, 0 — ローカル座標
local color = getvideo(px, py) — 下のレイヤーの(px, py)位置の色を取得local r = (color >> 16) & 0xFF
local g = (color >> 8) & 0xFF
local b = color & 0xFF— 取得した色を使って円を描画する
setcolor(r, g, b)
setfigure(“circle”, px, py, 10)
``
getvideo(x, y)
フィルタスクリプトでは、スクリプトが適用される範囲の各ピクセルに対して、で元のピクセル色を取得し、
setpixel(x, y, new_color)` で加工後の色を設定するという処理を繰り返すのが基本です。 -
getaudio()
: 現在のフレームの音声データを取得します。返されるデータはテーブルで、左右のチャンネルの音声レベル(振幅)などが含まれます。
“`lua
local audio_data = getaudio()
— audio_data.l は左チャンネルの振幅 (-1.0 ~ 1.0)
— audio_data.r は右チャンネルの振幅 (-1.0 ~ 1.0)
— audio_data.level は平均的な振幅 (0.0 ~ 1.0)— 音量に合わせて円の大きさを変える例
local audio_level = audio_data.level or 0 — 音声がない場合は0にする
local min_radius = 20
local max_radius = 100
local radius = min_radius + (max_radius – min_radius) * audio_levelsetcolor(0, 255, 0) — 緑色
setfigure(“circle”, 0, 0, radius)
“`
これを利用して、音声に合わせてオブジェクトを振動させたり、エフェクトの強さを変えたりといった表現が可能になります。 -
ファイルの読み込み (
io
ライブラリ): Luaの標準ライブラリであるio
を使うと、テキストファイルなどを読み込むことができます。これにより、外部ファイルに保存した設定値や、アニメーション用の座標データをスクリプトで利用するといった応用が考えられます。
“`lua
— 設定ファイル (config.txt) の例:
— speed=5
— radius=50local config = {}
local file = io.open(“C:/path/to/config.txt”, “r”) — ファイルパスは環境に合わせて変更
if file then
for line in file:lines() do
local key, value = line:match(“^(%w+)=(.+)$”) — “key=value” の形式を解析
if key and value then
config[key] = tonumber(value) or value — 数値に変換できれば数値、できなければ文字列として格納
end
end
file:close()
end— 読み込んだ設定値を利用
local speed = config.speed or 1 — 設定がなければデフォルト値1
local radius = config.radius or 30 — 設定がなければデフォルト値30— 例: 設定された速度で回転、半径で円を描画
obj.rotz = obj.frame * speed
setcolor(255, 255, 0) — 黄色
setfigure(“circle”, 0, 0, radius)
“`
ファイルパスの指定には注意が必要です。AviUtlの実行ファイルからの相対パス、または絶対パスで指定します。
3.4 複雑なアニメーションの実装
時間 (obj.frame
, obj.time
), スライダー (track
), Luaの数学関数 (math
ライブラリ) を組み合わせることで、多様なアニメーションパターンを作り出せます。
-
フレーム数と時間:
obj.frame
はオブジェクトの開始フレームを0とした現在のフレーム数です。アニメーションの進行度合いを計算するのに最もよく使われます。obj.frame_last
はオブジェクトの最終フレーム数です。obj.frame / obj.frame_last
でアニメーションの0から1までの正規化された進行度合いが得られます。time
はタイムライン上の現在時間、obj.time
はオブジェクト開始からの相対時間です。フレームベースではなく時間ベースで処理したい場合に利用します。
-
スライダー (
track0
~track3
): これらの値は、AviUtlのGUIでユーザーが直接操作できるパラメータです。スクリプトの動きを外部から簡単に調整できるようにするために不可欠です。-
パラメータ名: スクリプトファイルの冒頭のコメントで
---@param track0 スライダーの表示名: 0~100
のように記述すると、AviUtlのオブジェクト設定ダイアログでスライダーに名前を付けたり、初期値や範囲を設定したりできます。
“`lua
–[[
@描画
—@param track0 X位置オフセット: -500~500
—@param track1 Y位置オフセット: -300~300
—@param track2 拡大率: 10~200
–]]track0 = track0 or 0
track1 = track1 or 0
track2 = track2 or 100— スライダーの値を使って位置と拡大率を調整
obj.ox = obj.ox + track0
obj.oy = obj.oy + track1
obj.zoom = track2— 以下、描画処理…
“`
-
-
数学関数 (
math
ライブラリ): Luaのmath
ライブラリには、三角関数(math.sin
,math.cos
,math.tan
)、平方根 (math.sqrt
)、べき乗 (math.pow
)、乱数(math.random
)、絶対値 (math.abs
)、最小値 (math.min
)、最大値 (math.max
)など、数学的な計算に役立つ関数が豊富に用意されています。アニメーションで滑らかな動きや不規則な動きを作る際に頻繁に利用します。
“`lua
— sin/cosを使った円軌道アニメーション
local radius = 150
local speed = 0.05
local angle = obj.frame * speed — フレーム数によって角度を増加
local move_x = math.cos(angle) * radius — 角度からX座標を計算
local move_y = math.sin(angle) * radius — 角度からY座標を計算setcolor(0, 0, 255) — 青色
setfigure(“circle”, move_x, move_y, 10) — オブジェクト中心からの相対位置に円を描画
lua
— 乱数を使ったランダムな点の描画 (描画範囲は適宜調整)
math.randomseed(os.time()) — 毎回異なる乱数を生成するためにシードを設定 (スクリプト読み込み時に一度だけ実行するのが望ましい)
local num_points = 100 — 描画する点の数for i = 1, num_points do
local rand_x = math.random(-200, 200) — -200から200の範囲でランダムなX座標
local rand_y = math.random(-150, 150) — -150から150の範囲でランダムなY座標
local rand_color = math.random(0xFFFFFF) — ランダムな色
setpixel(rand_x, rand_y, rand_color)
end
``
math.randomseed()` はスクリプトが読み込まれる最初の一度だけ実行されるように工夫すると良いでしょう。例えば、スクリプトファイルの一番上に記述するか、特定のフラグを使って初回実行時のみに行うようにします。 -
テーブル構造の活用: 複雑なアニメーションや複数の要素を扱う場合、テーブルを使ってデータを構造化すると管理しやすくなります。例えば、複数の点の座標やプロパティをテーブルに格納し、ループ処理でまとめて更新・描画するといったことができます。
3.5 フィルタスクリプトの作成
フィルタスクリプトは、入力画像(通常はスクリプト制御オブジェクトより下のレイヤーの画像)の各ピクセルに対して処理を行い、加工後の画像を出力します。ファイルの冒頭に --[[@フィルタ--]]
タグを記述します。
フィルタスクリプトの基本的な処理は以下のようになります。
- 処理対象の範囲を決定する(通常はオブジェクトのサイズや設定された範囲)。
- その範囲内のすべてのピクセルについて繰り返す。
- 各ピクセルの元の色を
getvideo(x, y)
またはgetpixel(x, y)
で取得する。フィルタスクリプトの場合は、getpixel(x, y)
がフィルタ対象の画像ピクセルを返すことが多いです。 - 取得した色に対して、加工処理(色調補正、ぼかし、シャープ、グリッチなど)を行う。
- 加工後の色を
setpixel(x, y, new_color)
で設定する。
例:画像をセピア調にするフィルタ
“`lua
–[[
@フィルタ
画像をセピア調にするフィルタ
—@param track0 セピアの強さ: 0~100
–]]
track0 = track0 or 0
— セピアの強さ (0:なし ~ 1:最大)
local strength = track0 / 100.0
— 処理範囲はオブジェクトのサイズとする
local width = obj.width
local height = obj.height
— 画像の中央を基準とした座標で処理する場合
local center_x = 0
local center_y = 0
— 左上を基準とした座標に変換
local start_x = center_x – width / 2
local start_y = center_y – height / 2
— 各ピクセルを処理
for y = 0, height – 1 do
for x = 0, width – 1 do
— ローカル座標 (オブジェクト中心基準)
local px = start_x + x
local py = start_y + y
-- 元のピクセル色を取得 (0xAARRGGBB)
local color = getpixel(px, py)
local alpha = (color >> 24) & 0xFF
local r = (color >> 16) & 0xFF
local g = (color >> 8) & 0xFF
local b = color & 0xFF
-- グレースケールに変換 (一般的な輝度計算)
local gray = math.floor(0.299 * r + 0.587 * g + 0.114 * b)
-- セピア調に変換 (一般的なセピア変換の計算式)
local sepia_r = math.floor(gray * 0.393 + gray * 0.769 + gray * 0.189)
local sepia_g = math.floor(gray * 0.349 + gray * 0.686 + gray * 0.168)
local sepia_b = math.floor(gray * 0.272 + gray * 0.534 + gray * 0.131)
-- 元のRGBとセピアRGBをブレンド
local final_r = math.floor(r * (1 - strength) + sepia_r * strength)
local final_g = math.floor(g * (1 - strength) + sepia_g * strength)
local final_b = math.floor(b * (1 - strength) + sepia_b * strength)
-- 各成分を0-255の範囲にクランプ
final_r = math.max(0, math.min(255, final_r))
final_g = math.max(0, math.min(255, final_g))
final_b = math.max(0, math.min(255, final_b))
-- 新しい色を作成 (アルファ値はそのまま)
local new_color = (alpha << 24) + (final_r << 16) + (final_g << 8) + final_b
-- ピクセルを設定
setpixel(px, py, new_color)
end
end
“`
このスクリプトは、ループを使ってオブジェクト範囲内のすべてのピクセルを走査し、それぞれの色を取得して計算でセピア調に変換し、新しい色を設定しています。この処理はピクセル数に比例して重くなるため、大きな画像や広い範囲に適用する場合はパフォーマンスに注意が必要です。
3.6 デバッグ方法
スクリプトが意図通りに動かない場合、原因を特定するためにデバッグが必要です。
-
print(...)
関数の利用: 最も簡単で効果的なデバッグ方法です。変数の中身、処理が特定の箇所に到達したかなどを確認するために、print()
関数でメッセージを出力します。出力はAviUtl拡張編集ウィンドウの「スクリプト出力ウィンドウ」に表示されます(右クリックメニューから開けます)。
“`lua
local my_variable = 123
print(“変数my_variableの値:”, my_variable)if some_condition then
print(“条件が真になりました”)
— 処理A
else
print(“条件が偽になりました”)
— 処理B
end
“` -
エラーメッセージの読み方: スクリプトに構文エラーや実行時エラーがあると、AviUtlはエラーメッセージを表示します。メッセージには通常、エラーが発生したスクリプトファイル名、行番号、エラーの種類(例:
attempt to perform arithmetic on a nil value
– nil値に対して算術演算を行おうとした)が示されます。この情報をもとに、エラー箇所を特定して修正します。
script/MyScripts/my_script.lua:25: attempt to perform arithmetic on a nil value
この例では、my_script.lua
ファイルの25行目で、nilの変数に対して足し算や引き算などの計算をしようとしてエラーが発生したことを示しています。 -
デバッグ用変数の表示: スクリプトの実行中に特定の値を確認したい場合、
print
だけでなく、オブジェクト設定ダイアログにデバッグ用のスライダーなどを一時的に追加して、そこに値を表示させることもできます。ただし、スライダーは整数値しか扱えなかったり、範囲があったりするので、万能ではありません。 -
コードを小分けにしてテスト: 一度に大量のコードを書くのではなく、機能ごとに小さな単位で書いてはAviUtlでテストすることを繰り返すのが、エラーを早期に発見し、修正を容易にする良い方法です。
第4部:実践的なスクリプト開発
これまでに学んだ基本と応用を組み合わせて、より実践的なスクリプトを作成したり、開発を効率化したりする方法を見ていきます。
4.1 サンプルスクリプトの紹介と解説
いくつかの典型的な AviUtl Lua スクリプトの例を考え、その構造と応用方法を解説します。
例1:カウンター(テキスト描画)
フレーム数や時間、あるいはスライダーの値などをカウンターとして表示するスクリプトはよく使われます。
“`lua
–[[
@描画
カウンター表示スクリプト
—@param track0 開始番号: 0~1000
—@param track1 終了番号: 0~1000
—@param track2 フォントサイズ: 10~100
–]]
track0 = track0 or 0
track1 = track1 or 100
track2 = track2 or 40
local start_value = track0
local end_value = track1
local font_size = track2
local current_frame = obj.frame
local max_frame = obj.frame_last
— 現在のフレームが全フレームに対してどの位置にあるか (0から1)
local progress = 0
if max_frame > 0 then
progress = current_frame / max_frame
end
— 線形補間によって現在のカウンター値を計算
local current_value = start_value + (end_value – start_value) * progress
— 小数点以下の桁数を制御したい場合は、math.floorやstring.formatを使う
— 例: 整数のみを表示
local display_value = math.floor(current_value)
— 例: 小数点以下1桁を表示
— local display_value = string.format(“%.1f”, current_value)
— 表示するテキストを作成
local display_text = tostring(display_value) — 数値を文字列に変換
— フォントと色を設定
setfont(“Arial”, font_size)
setcolor(255, 255, 255) — 白
— 画面中央にテキストを描画
local text_x = 0
local text_y = 0
— テキストの配置基準を中央にしたい場合
— drawtext関数は左上基準で描画されるため、テキストのサイズを考慮する必要がある
— AviUtlのAPIにはテキストのサイズを取得する直接的な関数は無いが、
— いくつかの方法で近似したり、既知のサイズを使うなど工夫が必要。
— 簡単のため、ここでは中心を基準とした位置に描画するだけに留める。
— もっと正確な中央配置には、複雑な計算や外部ライブラリが必要になる場合もある。
— (このコードでは、シンプルに obj.ox, obj.oy を基準とした相対座標(0,0)に描画)
drawtext(display_text, text_x, text_y)
— オブジェクト自体の位置を画面中央に設定したい場合は、obj.ox, obj.oyを操作する
— obj.ox = 0
— obj.oy = 0
``
string.format` を使えば、小数点以下の桁数を指定して表示することも可能です。
このスクリプトは、オブジェクトの開始フレームから終了フレームにかけて、スライダーで指定した開始番号から終了番号までを線形に補間して表示します。
例2:波打つテキストアニメーション
各文字を個別にアニメーションさせるには、文字の位置を計算して drawtext
で一つずつ描画する必要があります。
“`lua
–[[
@描画
波打つテキストアニメーション
—@param track0 波の速さ: 1~100
—@param track1 波の高さ: 1~200
—@param track2 文字間隔: 10~100
–]]
track0 = track0 or 20
track1 = track1 or 50
track2 = track2 or 40
local speed = track0 * 0.1 — スライダー値を調整
local amplitude = track1 — 波の高さ
local char_spacing = track2 — 文字間隔
local text_to_display = “Wave Animation” — 表示したいテキスト
— フォントと色を設定
local font_name = “メイリオ”
local font_size = 40
setfont(font_name, font_size)
setcolor(255, 255, 0) — 黄色
— 各文字の位置を計算して描画
local current_frame = obj.frame
— テキスト全体の中央を基準とするためのオフセットを計算
— 文字数と文字間隔から全体の幅を概算
local total_width = (#text_to_display – 1) * char_spacing
local start_x = -total_width / 2 — テキスト全体の開始X座標 (ローカル座標系)
for i = 1, #text_to_display do — 1番目の文字から最後の文字までループ
local char = text_to_display:sub(i, i) — i番目の文字を取得
-- 文字の基準位置 (ローカル座標系、波打ち前の位置)
local base_x = start_x + (i - 1) * char_spacing
local base_y = 0 -- オブジェクト中心をY基準とする
-- 波打ちのオフセットを計算 (sin関数を利用)
-- 位置(i)、時間(current_frame)、速さ(speed) を組み合わせて角度を決定
local angle = (i * 0.5 + current_frame * speed) * math.pi / 180 -- 角度は適当に調整
local wave_offset_y = math.sin(angle) * amplitude
-- 最終的な文字の描画位置
local final_x = base_x
local final_y = base_y + wave_offset_y
-- 文字を描画
drawtext(char, final_x, final_y)
end
``
sin
このスクリプトでは、表示したい文字列を1文字ずつ取り出し、それぞれの文字に対して関数を使ったY座標のオフセットを計算しています。オフセットの計算に文字のインデックス (
i) とフレーム数 (
current_frame`) の両方を使うことで、時間と共に文字が順番に波打つアニメーションが実現できます。文字間隔を調整することで、波の見え方も変わります。
4.2 パフォーマンスに関する注意点
Luaは比較的軽量な言語ですが、AviUtlのフレーム描画はリアルタイム性が求められるため、スクリプトの実行速度が重要になります。特に動画出力時など、膨大なフレームに対してスクリプトが実行されるため、処理が遅いと出力に時間がかかったり、編集中にプレビューがカクついたりします。
- ピクセル単位の処理は重い:
getpixel
,setpixel
を使用したピクセル単位のループ処理は、扱う画像サイズが大きくなると非常に重くなります。フィルタスクリプトでは避けられませんが、描画スクリプトでは可能な限りsetfigure
やdrawtext
などの高レベルな描画関数を利用した方が高速です。 - 不要な計算を避ける: ループ内で毎回同じ計算を繰り返すなど、無駄な計算がないか確認しましょう。
- テーブルアクセス: テーブルへのアクセスは、ローカル変数へのアクセスよりもわずかにオーバーヘッドがあります。頻繁に使う値はローカル変数にキャッシュするなどの工夫が有効な場合があります。
- LuaJITの利用: 前述の通り、LuaJITはスクリプトの実行速度を大きく改善します。特に数値計算やループ処理が多いスクリプトでは必須と言えます。AviUtlの拡張編集設定でLuaJITが有効になっているか確認しましょう。
- プロファイリング: より高度な最適化が必要な場合は、Luaのプロファイラツールを使って、スクリプトのどの部分が時間を消費しているかを特定すると良いでしょう。ただし、AviUtl環境でプロファイラを設定するのは少し手間がかかるかもしれません。
4.3 スクリプトの配布と利用に関する注意点
自分が作成したスクリプトを他の人と共有したり、インターネット上で公開されているスクリプトを利用したりする際には、いくつかの点に注意が必要です。
- ライセンス: 自分で作成したスクリプトを公開する場合、どのような条件で利用を許可するのかライセンスを明記しましょう。特に指定がなければ著作権法によって保護されますが、多くの場合はMITライセンスやCC0(パブリックドメイン)など、比較的自由な利用を許可するライセンスが選択されます。他の人が作成したスクリプトを利用する場合は、そのスクリプトに添付されているライセンス条項を必ず確認し、遵守してください。
- 依存関係: 自分のスクリプトが、AviUtl本体、拡張編集、LuaJIT以外の特定のプラグインや外部ファイルに依存している場合、READMEファイルなどにその旨を明記し、必要なものをユーザーが準備できるように案内しましょう。
- 動作環境: スクリプトが動作するAviUtlや拡張編集のバージョン、OS環境など、動作に必要な環境を記載しましょう。
- READMEの作成: スクリプトの使い方、機能、パラメータの意味、インストール方法、ライセンス、連絡先などを記載したREADMEファイルを添付することは、スクリプトを他の人に使ってもらう上で非常に重要です。
第5部:応用テクニックと発展的な話題
ここからは、さらにLuaスクリプトの可能性を広げるための応用テクニックや、発展的な内容に軽く触れます。
5.1 外部ライブラリの利用 (LuaJIT FFIなど)
LuaJITを使用している場合、FFI (Foreign Function Interface) 機能を利用して、C言語の関数やライブラリをLuaから直接呼び出すことができます。これにより、Luaだけでは難しい高速な処理や、特定の外部ライブラリの機能を利用することが可能になります。
例えば、高度な数学計算ライブラリや、画像処理ライブラリの一部機能をLuaから呼び出すといったことが考えられます。しかし、これはC言語やFFIに関する知識が必要となるため、非常に高度なテクニックとなります。AviUtlの標準APIやLuaの標準ライブラリでできることも多いため、まずはそちらをマスターすることから始めましょう。
5.2 複雑なデータ構造とアルゴリズム
複数のパーティクルをシミュレーションしたり、複雑な図形を生成したりする場合、テーブルを使ってこれらの要素の状態(位置、速度、色など)を管理し、フレームごとに状態を更新し、描画するという処理が必要になります。
例えば、シンプルなパーティクルシステムを作成する場合、パーティクル一つ一つをテーブルで表現し、それらをさらにリスト形式のテーブルにまとめて管理します。
“`lua
— パーティクルを表すテーブルの構造
local particle = {
x = 0, y = 0, — 位置
vx = 0, vy = 0, — 速度
life = 1.0, — 寿命 (0から1)
color = 0xFFFFFF — 色
}
local particles = {} — パーティクルのリスト
— 初回スクリプト実行時などにパーティクルを生成
— for i = 1, 100 do
— table.insert(particles, { x = …, y = …, vx = …, vy = …, life = 1.0, color = … })
— end
— フレームごとの更新処理
for i = #particles, 1, -1 do — 後ろからループすると、削除が楽
local p = particles[i]
-- 速度に基づいて位置を更新
p.x = p.x + p.vx
p.y = p.y + p.vy
-- 寿命を減らす
p.life = p.life - 1.0 / 60.0 -- 例: 60フレームで寿命が尽きる
-- 寿命が尽きたらリストから削除
if p.life <= 0 then
table.remove(particles, i)
else
-- 寿命に応じて透明度を変更する例
local alpha = math.floor(p.life * 255)
local particle_color = ((alpha << 24) & 0xFF000000) + (p.color & 0x00FFFFFF)
-- パーティクルを描画
setpixel(p.x, p.y, particle_color)
end
end
“`
このような構造を使うことで、多数の要素を持つシステムをLuaスクリプトで実装することが可能になります。物理計算や群衆シミュレーションなども、同様の考え方で実現できます。
5.3 高度な描画テクニック
- カスタムシェイプ:
drawpoly
やpolys
を使って、任意の頂点を持つ多角形を描画できます。これを応用して、波線や複雑な自由曲線を描画することも可能です。 - 画像生成:
setpixel
をフレーム内の全てのピクセルに対して使うことで、完全にスクリプトだけで画像を生成できます。ノイズパターン、フラクタル図形、シンプルな背景などをプログラムで生成するのに使われます。 - テキスト描画の詳細:
drawtext
はシンプルですが、文字間隔や行間、文字ごとの変形などを細かく制御したい場合は、文字列を1文字ずつ分解してそれぞれの位置を計算し、個別にdrawtext
またはsetfigure
(文字を画像として扱うなど) で描画する必要があります。前述の波打つテキストの例はその一例です。
結論:LuaスクリプトでAviUtlの可能性を解き放つ
この記事では、AviUtlのLuaスクリプトについて、その始め方から基本的な文法、AviUtl固有の機能、そして応用的なテクニックまで、幅広く解説してきました。
Luaスクリプトを習得することで、AviUtlの標準機能や既存のプラグインだけでは実現できなかった、無限とも言える表現の可能性が開かれます。自分だけのオリジナルのアニメーション、フィルタ、描画効果を作成し、動画編集の幅を大きく広げることができるでしょう。
最初はLuaの文法やAviUtlのAPIに戸惑うかもしれませんが、小さなスクリプトから始めて、少しずつ複雑な機能を取り入れていくのが習得への近道です。既存のスクリプトのコードを読んで、どのように機能が実現されているのかを学ぶのも非常に有効です。
この記事が、あなたがAviUtl Luaスクリプトの世界に踏み出し、クリエイティブなアイデアを形にするための一助となれば幸いです。
学習の継続を応援します!
- 公式ドキュメントやリファレンス: AviUtlの拡張編集に同梱されているかもしれないAPIリファレンスや、有志がまとめたドキュメントは、利用できる関数や変数について詳細な情報を提供しています。
- 既存のスクリプト: 公開されている多くのAviUtlスクリプトは、優れた学習資料です。コードを読んで、どのように書かれているのかを解析してみましょう。
- オンラインコミュニティ: AviUtlのユーザーコミュニティやフォーラムでは、他のユーザーと情報交換したり、質問したりすることができます。
AviUtlとLuaスクリプトの組み合わせは、あなたの動画制作をさらに豊かなものにしてくれるはずです。ぜひ、楽しみながら挑戦してみてください!