TRPGスタジオでリプレイ動画を作る5-1
長くなったので分割です。
分割元↓
キャラ登録について
どうなるのか
;before
[chara_show storage="chara/カーメン山田/yamada06.png" local_file="yamada06.png" top="10" left="300" time="1000" wait="true" zindex="1" name="カーメン山田" reflect="false" depth="front"]
;after
[chara_show name="ymd" face="kime" top="10" left="300" time="3000"]
↑ぐらい短く簡単になります。
何をするのか
[chara_new]と[chara_face]の登録を自動化し、[chara_show]を短くします。
つまり、ティラノスクリプトで普通に行うキャラ登録を行います。
(★中級者向けでは自動化)
[chara_face]でまとめる
[chara_show]
[chara_mod]
を使っていちいちstorageで呼び出していたものを
[chara_face]で登録することでfaceパラメーターで呼び出せるようにします。
data/scenario/system/chara_define.ksをコピー。
scenarioフォルダ傘下のどっかにコピーしたやつをリネームして置いときます。(chara.ksにした)
以下のように書き換えます。
[chara_new name="カーメン山田" jname="カーメン山田" storage="tomei.png"]
↓
[chara_new name="ymd" jname="カーメン山田" storage="chara/カーメン山田/yamada01.png"]
ここでstorageを透明画像パスから、基本的なキャラの立ち絵画像へのパスへ
変更します。「fgimage」がパスのデフォスタート地点です。
[chara_show]でfaceタグが指定されていない場合、このデフォ画像が
表示されます。face="default"でも呼べます。
nameはその立ち絵を指定した何かをさせる場合に
nameを指定して命令します。([chara_move name="ymd" x=+=10])
jnameは会話ウィンドウに表示される名前です。
さらに以下を書き加えます。
[chara_face name="ymd" face="yryr" storage="chara/カーメン山田/yamada02.png"]
[chara_face name="ymd" face="ahan" storage="chara/カーメン山田/yamada03.png"]
[chara_face name="ymd" face="yatta" storage="chara/カーメン山田/yamada04.png"]
[chara_face name="ymd" face="yane" storage="chara/カーメン山田/yamada05.png"]
[chara_face name="ymd" face="kime" storage="chara/カーメン山田/yamada06.png"]
[chara_face name="ymd" face="zoi" storage="chara/カーメン山田/yamada07.png"]
(キャラ差分があるだけ)
これでface="yryr"のパラメーターがあるname="ymd"の立ち絵命令はyamada02.pngの画像に切り替わって使用されます。
そのシナリオ(.ks)にある[chara_new]が、
実際セッションで使用されたキャラクター一覧と同義なので、
そのキャラの立ち絵差分分だけ表情登録([chara_face])します。
まとめる時のポイント
インデントを揃える(tab)
視認性がよくなるのと、操作の手間が減ります。
具体的には、Atomならctrl+shiftで高さ?の同じ部分にカーソルを増やせる。
矢印キーで移動するときも無駄が減ったりします。
「,」忘れの発見のしやすさにもつながります。
なお、英語なら揃うけど、日本語が混じるとインデントが合わない。
日本語文字列をどうしても入れる場合は一番後ろが良いかも。
同じ名称は省略する
例えばパス。パスは文字列であり、文字列は変数に入れられる。
つまり、より短い変数名の変数の中に長い文字列を入れていく。
[chara_new name="ymd" jname="カーメン山田" storage="chara/カーメン山田/yamada01.png"]
↓
@eval exp="tf.f = 'chara/'"
@eval exp="tf.cp0 ='カーメン山田/yamada'"
[chara_new name="ymd" jname="カーメン山田" storage="&tf.f+tf.cp0+'01.png'"]
この読み込みタグで使う、パスを文字列にしたものは、
一度読み込んでしまえば変数自体が消えても動くので
一時変数(tf.)で記載できます。
ちなみに山田のフォルダ内は
画像名がナンバリングになっているので、
"01.png"のところを変えるだけで画像変更ができます。
(なんなら01部分を変数に変えてしまえば、変数を変えるだけで画像変更ができる)
storageの視認性が悪くなりましたが、上記の変数の宣言で中身が紐づけできますし、コンピューターが読み込むところで人が読むところじゃないのでそんなに気にしなくていいです。
sheet_thumb.pngは
キャラシ表現云々のとこで使います。
キャラシを出すキャラの場合はもうちょい細分して変数に入れた方がいいかも。
ただキャラシ表現云々の画像のパスは固定位置がないので、
相対パスを使えばどこに画像置いてもいいんですよね…。
★中級まとめ:オブジェクト変数
キャラ登録に必要なタグは、ぶっちゃけると2つだけです。
[chara_new]と[chara_face]。
つまり、最低必要行は2なわけですが
[chara_new name="hoge" storage="chara/hoge/smile.png" jname="hoge"]
[chara_face name="hoge" face="angry" storage="chara/hoge/angry.png"]
[chara_face name="hoge" face="n1" storage="chara/hoge/n1.png"]
[chara_face name="hoge" face="n2" storage="chara/hoge/n2.png"]
[chara_face name="hoge" face="n3" storage="chara/hoge/n3.png"]
[chara_face name="hoge" face="n4" storage="chara/hoge/n4.png"]
・・・
上×キャラの数だけ書く
こんだけ書くのめんどい。
ので、変化するところだけ変数にして素材+2行(繰り返し)にします。
f.nameのオブジェクト変数を宣言
f.fileのオブジェクト変数を宣言
キャラの数だけiを繰り返す====>
[chara_new name="&f.name[i]" storage="f.file[i]" jname="f.name[i]"]
iで呼び出されたキャラのfaceの数だけlを繰り返す=>
[chara_face name="&f.name[i]" face="angry" storage="f.file[l]"]
<=
<====
イメージとしてはこんなん。
方法は2つあって、ティラノタグで行うか、javascriptで行います。
この2つのいいとこどりみたいな書き方はバグるのでできません。
■これが中途半端なやつ
=================なんとか.ksに記入===============
[iscript]
tf.nm=[ //name,jname
['gm', 'GM'],
['ymd','カーメン山田'],
]
tf.ps={}
tf.f={}
tf.ps={
gm:'chara/akane/', //keyを変数にする場合は[nm]
ymd:'chara/akane/' //keyを変数にする場合は[nm]
}
tf.f={
gm:{
normal:tf.ps['gm']+'normal.png',
angry :tf.ps['gm']+'angry.png'
},
ymd:{
normal:tf.ps['ymd']+'normal.png',
angry :tf.ps['ymd']+'angry.png'
}
}
for (let i = 0; i < tf.nm.length; i++) {//キャラの数だけ繰り返す
//let i=0
const hrt=Object.keys(tf.f[tf.nm[i][0]])
const cnt=hrt.length
TYRANO.kag.ftag.startTag("chara_new", {
name: tf.nm[i][0],
storage: tf.f[tf.nm[i][0]][hrt[0]],//hrt[0]の0は固定
jname: tf.nm[i][1]
});
for(let l =1; l < cnt; l++){
TYRANO.kag.ftag.startTag("chara_face", {
name:tf.nm[i][0],
face:hrt[l],//tf.nm[i][hrt[l]],
storage:tf.f[tf.nm[i][0]][hrt[l]]
});
}
}
[endscript]
;===========呼び出す=============
[layopt layer="0" visible="true"]
[chara_show name="gm" top="10" left="10" face="default"]
[chara_show name="ymd" top="10" left="300" face="angry"]
[p]
[chara_mod name="gm" face="angry"]
平たくいうと、[iscript]の中で
さらにfor文の中で「.startTag」を使うと、[p]で止まらなくなる。
詳しくはこちら
一応荒治療として
[wait time="500"]
a
[p]
高速処理を一度waitで止めさせて、文字を表示させて[p]で止める
ということができなくないです。
これはマシンスペックで止められないこともあります。
処理内容とスペックでwaitで止める時間を長くする必要あり。
★ティラノでまとめる
セミコロン(;)はあった方がいいですけど、なくても動きます。
=================なんとか.ksに記入===============
[iscript]
tf.nm=[ //name,jname
['gm', 'GM'],
['ymd','カーメン山田'],
]
tf.ps={}
tf.f={}
tf.ps={
gm:'chara/akane/', //keyを変数にする場合は[nm]
ymd:'chara/akane/' //keyを変数にする場合は[nm]
}
tf.f={
gm:{
normal:tf.ps['gm']+'normal.png',
angry :tf.ps['gm']+'angry.png'
},
ymd:{
normal:tf.ps['ymd']+'normal.png',
angry :tf.ps['ymd']+'angry.png'
}
}
[endscript]
@eval exp="tf.i=0"
*cn
[iscript]
tf.hrt=Object.keys(tf.f[tf.nm[tf.i][0]])
tf.cnt=tf.hrt.length
[endscript]
@eval exp="tf.l=0"
[chara_new name="&tf.nm[tf.i][0]" storage="&tf.f[tf.nm[tf.i][0]][tf.hrt[0]]" jname="&tf.nm[tf.i][1]"]
*cf
[chara_face name="&tf.nm[tf.i][0]" face="&tf.hrt[tf.l]" storage="&tf.f[tf.nm[tf.i][0]][tf.hrt[tf.l]]"]
@eval exp="tf.l++"
[jump target="*cf" cond="tf.l<tf.cnt"]
@eval exp="tf.i++"
[jump target="*cn" cond="tf.i<tf.nm.length"]
;===========呼び出す=============
[layopt layer="0" visible="true"]
[chara_show name="gm" top="10" left="10" face="default"]
[chara_show name="ymd" top="10" left="300" face="angry"]
[p]
[chara_mod name="gm" face="angry"]
ごちゃごちゃしてよくわかんねーと思いますが、動きます。
javascriptのfor文をjumpとcondで代用しています。
一番最初の[iscript]内の
tf.ps(storageに使う共通pass)
tf.f(tf.psと組み合わせて使う完成pass)
tf.nm([0]=nameで使う名前)//[1]=jnameで使う名前)
をいくら増やしても対応します。
なお、@と[]は同じ意味です。
私はコードの区切り的な意味なタグや希少なタグは[]、他は@といった感じで使い分けてます。
こちらのやり方の方が正規手順?だし、バグもないです。
ただし見にくい。
★javascriptでまとめる
javascript(以降JS)の場合、.jsファイルに記入してそれを呼び出します。
使用タグは[loadjs]。other傘下に配置と書いてますけど相対パスでもOK。
=================なんとか.ksに記入===============
;====jsを呼び出す====
[loadjs storage="../scenario/macro/chara.js"]
[wait time=50]
;↑!?
;===========呼び出す=============
[layopt layer="0" visible="true"]
[chara_show name="gm" top="10" left="10" face="default"]
[chara_show name="ymd" top="10" left="300" face="angry"]
[p]
[chara_mod name="gm" face="angry"]
[s]
=================chara.jsに記入===============
let nm=[ //name,jname
['gm', 'GM'],
['ymd','カーメン山田'],
]
let ps={}
let f={}
ps={
gm:'chara/akane/', //keyを変数にする場合は[nm]
ymd:'chara/akane/' //keyを変数にする場合は[nm]
}
f={
gm:{
normal:ps['gm']+'normal.png',
angry :ps['gm']+'angry.png'
},
ymd:{
normal:ps['ymd']+'normal.png',
angry :ps['ymd']+'angry.png'
}
}
for (let i = 0; i < nm.length; i++) {//キャラの数だけ繰り返す
const hrt=Object.keys(f[nm[i][0]])
const cnt=hrt.length
TYRANO.kag.ftag.startTag("chara_new", {
name: nm[i][0],
storage: f[nm[i][0]][hrt[0]],//hrt[0]の0は固定
jname: nm[i][1]
});
for(let l =1; l < cnt; l++){
TYRANO.kag.ftag.startTag("chara_face", {
name:nm[i][0],
face:hrt[l],//tf.nm[i][hrt[l]],
storage:f[nm[i][0]][hrt[l]]
});
}
}
ティラノと比べると、毎回「tf.」と記入しないぶんすっきりしてますね。
改行しても大丈夫だし。
letは変数の宣言で、ティラノでいうtf.と大体同じです。大体。
・・・・・・( ^ω^)・・・
/[wait time=50]何してんの?\
はい、やはりfor文の中で「.startTag」を使っちゃったので、非同期云々で[p]で止まらないので[wait]で止めました。
混合に比べると軽いです。500mm秒が50mm秒です。
上の例だと50mm秒ですが、最終的に90mm秒必要でした。
★どっちでまとめるべき?
特に理由なければティラノでまとめた方がいいと思います。
★上の例を使用するときに変更するとこ
tf.ps(storageに使う共通pass)
tf.f(tf.psと組み合わせて使う完成pass)
tf.nm([0]=nameで使う名前)//[1]=jnameで使う名前)
ティラノの場合
[iscript]
tf.nm=[ //name,jname
['gm', 'GM'],
['ymd','カーメン山田'],
['【半角英数字]','【表示する名前]'], ←ここ増やせる。「,」忘れずに。
〃
〃
〃
]
[endscript]
tf.ps={}
tf.f={}
tf.ps={
gm:'chara/akane/', //keyを変数にする場合は[nm]
ymd:'chara/akane/', //keyを変数にする場合は[nm]
【上の半角英数字と同じ】:'chara/[フォルダ名]', ←下に増やすときに「,」忘れずに。
〃
〃
〃
}
tf.f={
gm:{
normal:ps['gm']+'normal.png',
angry :ps['gm']+'angry.png'
},
ymd:{
normal:ps['ymd']+'normal.png',
angry :ps['ymd']+'angry.png'
},
【上の半角英数字と同じ】:{
face名(ここがdefault):tf.ps['[上の半角英数字と同じ】']+'【画像ファイル名(拡張子含む)',
face名2(ここ以降がface登録):tf.ps[~略
}
}
JSの場合
let nm=[ //name,jname
['gm', 'GM'],
['ymd','カーメン山田'],
['【半角英数字]','【表示する名前]'], ←ここ増やせる
]
let ps={}
let f={}
ps={
gm:'chara/akane/', //keyを変数にする場合は[nm]
ymd:'chara/akane/', //keyを変数にする場合は[nm]
【上の半角英数字と同じ】:'chara/[フォルダ名]', ←下に増やすときに「,」忘れずに。
}
f={
gm:{
normal:ps['gm']+'normal.png',
angry :ps['gm']+'angry.png'
},
ymd:{
normal:ps['ymd']+'normal.png',
angry :ps['ymd']+'angry.png'
},
【上の半角英数字と同じ】:{
face名(ここがdefault):ps['[上の半角英数字と同じ】']+'【画像ファイル名(拡張子含む)',
face名2(ここ以降がface登録):ps[~略
}
}
それぞれの配列で入れる順番は同じじゃなくとも対応します。
faceについて
当たり前の話をします。
キャラのface名はなるべく統一しましょう。
def,angry,sad,smile,fight,sp1,sp2…とか。
名前も、「この画像が使いたい」と思い浮かべた絵に紐づいた
名前がいいです。
キャラが登録されたか確認方法
ティラノスタジオの開発タブ>キャラクタータブ
から登録されたキャラクター一覧を見ることができます。
(22/7/27追記)
分割終わり。
分岐元↓