ADVANCED TECHNIQUES
Keeping Things Moving
基本的なzscriptでは、ZBrushは順番にコマンドを順番に実行しますが、プログラムで作業している人は、他のものが最初に実行された後にのみ可能なことを認識しています。より複雑なzscriptを書くときは、ZBrushが入る状態を予測することが重要です。そのため、スクリプトアクションを実行しようとする試みは失敗しません。 ZBrushインターフェイスの状態を確認することは、zscriptを動かすことができる1つの方法です。 さまざまな状況に対処できるようにコードを整理したいという理由があります。ユーザーに選択肢を与えます。ユーザーがファイルを選択できるようにする必要があるかもしれません。次に、選択されたファイルを処理する場所と、ユーザーが気を変えてファイルを選択しないように対処する2つの状況を処理するコードを記述する必要があります。
If… this Happens then Do That
これが何を意味するのかは、 'これが起これば、コードはこれをしなければならない。そうでなければ、それをしなければならない'という一般的な表現である。 Ifコマンドは、これらの状況に最適です。それはかなり簡単です:
[If,/*condition to check goes here*/,
/*commands if condition true go here*/
,//else
/*commands if condition false go here*/
]//end of if command
一連のコマンドを実行する前に、編集モードでモデルが存在するかどうかをチェックしたいとします。 [変換]パレットの[編集]ボタンは、モデルが編集モードのときにのみ表示されるため、これをチェック条件として使用できます。しかし、私たちのコードでそれをどのようにテストするのですか?さて、まずEditボタンの状態について調べる必要があります。これを行うために、ノートを使用することができます。
Spreading the Word: Notes and Messages
zscriptがユーザーにメッセージを表示する方法はいくつかあります。一番便利なのがノートコマンドです。 (これはすでにzscriptのチュートリアルで説明しているかもしれません)。基本的な形式は次のとおりです。
[Note,"message to user" ,, display duration ]
(メッセージと期間の間に2つのカンマがあることに注意してください)。
ユーザーに何かを伝えたいときはいつでもノートを使うことができます。唯一の要件は、ボタンや他の 'container'タイプのコマンドの中にラップする必要があることです。
メモはメッセージを表示するので、ZBrushインターフェイスに関する情報を表示するのに使用できます。つまり、編集ボタンの状態を調べるためのテストzscriptを書くことができます。これは私たちのやり方です:
[VarDef,editMode,0] //defines a variable to store Edit mode
[IButton,"Test Edit","Test Edit button for its State", //beginning of button code
[VarSet,editMode,[IGet,Transform:Edit]] //gets value of Edit button
[Note,editMode,,3] //displays the value of Edit button for 3 seconds
] //end of button
このzscriptを試してみると、編集ボタンがオンになっているときに値が1で、オフになっているときに値が0になっていることがわかります。これを見つけたら、コードでこれらの値を使用できます。ですから、先ほど見たIfコマンドでは、次のように書くことができます:
[VarDef,editMode,0] //defines a variable to store Edit mode
[IButton,"EditMode","Display Edit Mode to User", //button start
[VarSet,editMode,[IGet,Transform:Edit]] //gets value of Edit button
[If,editMode = 1, // test value
[Note,"Edit is ON",,3] //commands for when Edit is on
, //else (when editMode is 0 and Edit button is off)
[Note,"Edit is OFF",,3] //commands for when Edit is on
]//end of If command
]//end of button
Loops – Just Keep Doing It!
あなたがzscriptを書くのに多くの時間を費やしたら、遅かれ早かれあなたは何度も繰り返したいコードを少し持っています。これを行う方法は、Loopコマンドを使用することです。ここにあります:
[Loop,/*number of times*/,
/*commands go here*/
]//end of Loop
私たちがやる必要があるのは、繰り返したいコマンドの周りにループをラップし、コードを繰り返す回数を指定することだけです。ここに例があります:
[VarDef,counter,0] //defines a number variable called counter
[Loop,10, //loop set to 10 times
[VarSet,counter,(counter+1)] //adds 1 to the value of counter variable
[Note, counter,,1] //displays value of counter for 1 second
] //end of Loop
Spreading the Word: Strings
前に議論したときから覚えているように、変数には2つのタイプがあります。数字を格納する変数と文字列を格納する変数です。
文字列は、単語やフレーズなどの文字の単なるグループです。変数は空の文字列と呼ばれる文字列を255文字まで格納することができます。文字列内の文字を数えたときにもスペースを数えておくことが重要です。 "Hello World"というフレーズには10文字ではなく11文字があります。単一の文字列で255の制限を超えた場合、ZBrushはエラーメッセージを表示し、zscriptは失敗します。 zscriptで文字列を使うときはいつでも、 "これと同じように"二重引用符で囲むことをお勧めします。これはそれを文字列として識別するだけでなく、ZBrushがスペースを表示する際にスペースを無視しないようにします。
文字列変数を定義するには、単純に空の文字列( "")を初期値として設定します。
[VarDef,myString,""]
ある時点では、おそらく2つ以上の文字列を結合したいと思うでしょう。これは、StrMergeコマンドを使用して実行できます。StrMergeコマンドは、その名前が示すように、文字列をマージします。
[StrMerge, //first string, //second string]
コンマで区切られた最大12文字の文字列を一度にマージできますが、マージされた文字列は255文字以内でなければなりません。 ループサンプルの新しいバージョンを書くことができます:
[VarDef,counter,0] //defines a number variable called counter
[VarDef,message,""] //defines a string variable called message
[Loop,10, //loop set to 10 times
[VarSet,counter,(counter+1)] //adds 1 to the value of counter variable
[VarSet,message,[StrMerge,"The counter is now at : ",counter]] //merges string with value of counter and stores it in message variable
[Note, message,,1] //displays message for 1 second
] //end of Loop
ノートを表示したいが、メッセージの長さが255文字を超える場合があります。この問題を解決する簡単な方法があります。表示期間が-1のノートは次のノートと結合されるので、メッセージを255文字以下のチャックに分割し、チャンクを複数のノートに広げるだけです。
[Note,"This message will be displayed at the top of the next Note.",,-1]
[Note,"\nThis is the end of the message.\nThe combined Note displays for 5 seconds.",,5]
(注:上で使用された特殊文字の組み合わせ\ nは改行を作成します)。
Apples, Pears, Oranges – the Joy of Lists
一連の値を保存したい場合、ZScript言語はリスト変数を提供します。これは、さまざまなテクスチャ幅やファイル名のリストなどを格納するのに非常に便利です。変数は次のように定義されます:
[VarDef,textureWidth(10),0]//defines a list variable of 10 numbers
[VarDef,fileName(10),""]//defines a list variable of 10 strings
次のように、リストの1つの値を設定します。
[VarSet,textureWidth(9),1024]//sets value of list variable at index9
[VarSet,fileName(0),"Franks_Head.ztl"]//sets value of list variable at index 0
上記の例では、インデックス0の変数があることに気づいたでしょう。これはかなり正しいです。多くのプログラミング言語と共通して、ZScriptはインデックスを0から開始します。したがって、10番目のアイテムは実際にはインデックス9を持つ変数です。したがって、インデックス10はありません(10個のリスト変数の場合)、ZBrushを使用しようとするとエラーを返します。
Economy Time – Routines
ここまでで、zscriptingの本質を掴み、かなり複雑なzscriptを書くことができるようになりました。あなたが実験したことがあれば、コードの一部を複製する必要があることが分かっているでしょう。たとえば、異なるコマンドを実行する前に、編集モードでモデルがあるかどうかを確認するためのボタンがいくつかあるとします。ルーチンは、この種のコードの重複を減らす方法を提供します。このプロセスでは、zscriptを分かりやすくして、問題が起こったときに修正しやすくします。また、何かを変更しなければならない場合は、ルーチン内で1回だけ実行する必要があり、時間と労力を大幅に節約できます。
[RoutineDef,routine name,//defines a routine
/*commands go here*/
]//end of Routine
[RoutineDef,CheckEditButton,//defines a routine called CheckEditButton
//start of command block (a series of commands run one after another)
[VarSet,editMode,[IGet,Transform:Edit]] //gets value of Edit button
[If,editMode = 1, // test value
[Note,"Tool is in Edit mode. ZScript aborted",,3] //commands for when Edit is on
[Exit]//exits the zscript
]//end of If command
//end of command block
]//end of Routine
Save/Load stuff – Using Files
ファイルを扱うことができれば、zscriptの能力に大きく貢献します。ファイル操作には多くの異なるコマンドがありますが、ここではそれらのうちのいくつかしか調べません。
FileExistsは、名前付きファイルが実際にユーザーのコンピュータに存在していることを確認するのに非常に便利です。 Ifコマンドと共にFileExistsを使用することにより、名前付きファイルが存在しない場合にzscriptの停止を回避することができます。使用方法は次のとおりです。
[If,[FileExists,"MyModel.ztl"], / / test to see if file "MyModel.ztl" exists
[Note,"File is present",,3] //commands for when the file is present
, //else file isn't present
[Note,"File is missing!",,3] //commands for when the file is absent
] //end of If command
ファイルが存在するかどうかを確認することは、ファイルを何らかの方法で使用できる場合を除いてあまり役に立ちません。 FileNameSetNextは、必要なコマンドです。次の保存アクションまたはロードアクションのファイル名を設定します。特定のイメージファイルをテクスチャとしてロードするには、次のように記述します。
[FileNameSetNext,"MyTexture.psd"] //sets "MyTexture.psd" as the next file to be saved/loaded
[IPress,Texture:Load] //loads "MyTexture.psd" into the Texture palette
File paths
ファイルを指定するときには、パスを含めることが重要です。単純にファイル名がある場合(パスがない場合)、ZBrushはファイルが実行中のzscriptと同じフォルダにあるとみなします。
パスは相対パスでも絶対パスでもかまいません。相対パスの例は次のとおりです。
"MyZScriptData\Settings.zvr"
実行中のzscriptが存在するのと同じフォルダのサブフォルダである "MyZScriptData"というフォルダ内のファイル "Settings.zvr"を指定します。
絶対パスの例は次のとおりです。
"C:\Program Files\Pixologic\ZBrush3\ZScripts\MyZScript.txt"
絶対パスの問題は、ユーザーのファイルがデフォルトの場所にあることを確認できないことです。幸いにも、ZBrushは特別な形式を使用してこれを克服する手段を提供します:
"ZBRUSH_ZScripts\MyZScript.txt"
これはデフォルトのZBrushフォルダのいずれかに使用できます。
Files and Variables
ファイルパスは変数に格納できます。単純にそれらを文字列型として定義します:
[VarDef,filePath,""]
変数はファイルとして保存することもできます。これは、zscriptが実行されるときにロードできる設定を保存する場合に特に便利です。コマンドのペアは、VarSaveとVarLoadです。 "myVariable"という名前の変数を "mySettings.zvr"という名前のファイルに保存するには、次のコードを使用します。
[VarSave,myVariable,"mySetting.zvr"]
値をロードするには:
[VarLoad,myVariable,"mySetting.zvr"]
(* .zvrはZBrushデータファイルのデフォルトのファイル拡張子です。)
リスト変数は同じ方法で保存/ロードできます。 myListVariable(10)として定義されたリスト変数の場合、リストイング変数の要素のインジケータなしでリスト変数の名前を置くだけで、保存するコードは次のようになります。
[VarSave,myListVariable,"mySetting.zvr"]
Total Recall – Memory Blocks
メモリブロックは、単にコンピュータメモリの塊である。彼らは非常に便利です。たとえば、ファイル形式を理解すれば、zscriptで作成されたメモリブロックを使用してファイルを読み書きすることができ、ファイルデータを直接操作することができます。しかし、これはこの簡単な紹介の範囲を超えています。ここでは、メモリブロックの用途を1つだけ検討します。それが変数の使用とどのように違うのか疑問に思うかもしれません。まあ、メモリブロックの大きな利点は、それらが永続的なものであることです。つまり、削除されない限り、ZBrushセッション全体で利用可能であるということです。変数は永続的ではなく、その値はzscriptが終了するたびにリセットされます。これは、一度に1つのzscriptまたはプラグインのみがアクティブになるため、頻繁に発生します。したがって、後で呼び出すためにzscriptに値を格納させたい場合は、メモリブロックを使用する必要があります。
Store Now, Use Later
ここでは、3Dモデルの位置をキャンバスに保存する例を示します。
まず、値を格納するメモリブロックを作成する必要があります。 zscriptingでは、名前を付けてそのサイズを指定することによってメモリブロックが作成されます。これを行うにはいくつかの方法がありますが、ここでは最も単純なMVarDefコマンドを使用します。このコマンドは実際には 'メモリブロック変数'を作成する単なる方法です。それは数字だけを格納することを覚えておくことが重要です。
メモリブロックの名前を付けるときは、可能な限り固有の名前を使用することをお勧めします。これは、名前が同じになった場合、他のzscriptやプラグインが間違ってメモリブロックにアクセスする可能性があるからです。あなたのイニシャルとzscriptに固有の名前を使用するのがよい方法です。たとえば、あなたの名前がJames Bondで、zscriptがZCasinoと呼ばれる場合、メモリブロックはJB_ZCasinoDataと呼ばれます。
メモリブロック名は、zscriptingの一般的な規則の例外です。大文字と小文字が区別されます。 メモリブロックを作成するためにMVarDefを使用するときには、格納する値の数を指定するだけで済みます。これは1つでも可能ですが、9つの変換値(位置、スケール、回転)があるので、この例では9を使用します。
[MVarDef,JB_ZCasinoData,9]
リスト変数と同様に、各値の 'ボックス'は、最初の値が0から始まるインデックス番号を使用して指定されます。最初のインデックスに '775'を格納するには、次のように書く:
[MVarSet,JB_ZCasinoData,0,775]
そして、9番目のインデックスに格納された値を取得するには:
[MVarGet,JB_ZCasinoData,8]
3Dモデルの変換値を取得するには、TransformGetコマンドを使用することができます。これを使ってメモリブロックの値を取得することもできますが、MTransformGetコマンドを使用する方が簡単です。これにより、値が同じ順番で取得され、メモリブロックに直接格納されます。
[MTransformGet,JB_ZCasinoData]
モデルに格納された値を設定するには、MTransformSetコマンドを使用します。
[MTransformSet,JB_ZCasinoData]
Garbage Collection
終了したメモリブロックはゴミです。それが取り除かれなければ、それは他の場所で必要とされる貴重な資源を使用しています。メモリブロックが終了するとすぐにメモリブロックを削除することをお勧めします。これのコマンドはMemDeleteです。
[MemDelete,JB_ZCasinoData]
ただし、存在しないメモリブロックを削除しようとするとエラーが発生するため、最初にそのブロックが存在するかどうかを確認することをお勧めします。 MemGetSizeコマンド(メモリブロックのサイズを示す)は、メモリブロックが存在しない場合に0を返し、このように使用できます。
[If,[MemGetSize,JB_ZCasinoData], // test for memory block, returns 1 or more if exists
[MemDelete,JB_ZCasinoData]//deletes memory block
, //else (when memory size is 0 and so doesn't exist)
[Note,"No memory block found",,3]
]//end of If command
メモリブロックを作成する場合を含め、すべてのメモリブロックアクションにこのメソッドを使用することをお勧めします。
[If,[MemGetSize,JB_ZCasinoData],
//does nothing - memory block already exists
, //else (when memory size is 0 and so doesn't exist)
[MVarDef,JB_ZCasinoData,9]//creates memory block
]//end of If command
Building Interfaces
zscriptやプラグインを書く貴重な時間を費やすつもりなら、それを使いたいと思うでしょう。ユーザーが自分の望むことをすることができなければ、そのことを書いている点はあまりありません。右のボタンやスライダーを用意するだけでは不十分かもしれません。複雑なzscriptの場合は、すべてのことを理解して使いやすくする何らかの方法でそれらを整理したいと思うでしょう。
インタフェース設計は複雑なテーマですが、ここでは説明しません。 zscriptingの可能性の概要を簡単に説明します。
The ZScript Tutorial Window
チュートリアルウィンドウは、ZBrushインターフェイスの一番下にあります。ハンドルをクリックまたはドラッグするか、ホットキー「H」を押して開きます。 zscriptの録音用の「再生」ボタンがここに表示され、zscriptボタンとスライダのデフォルトの場所になります。
魅力的で機能的なインターフェイスは、チュートリアルウィンドウ用に設計できます。チュートリアルウィンドウのインターフェイスの詳細については、「ZScriptチュートリアルウィンドウのインターフェイス」を参照してください。
ZPlugin Interfaces
zscriptをZPluginにすることで、ZBrushインターフェイスのデフォルトパレットのほとんどすべてにボタンを追加できます。これには多くの利点があります。たとえば、任意のカスタムインターフェイスの配置でzpluginボタンを使用することができます。しかし、zpluginインターフェースは、設計の観点からは幾分制限されています。
ZPluginインタフェースの詳細については、「ZPluginインタフェース」を参照してください。
Note Interfaces
Note Interfaceの例はProjection Masterダイアログです。注記インタフェースは、画像を表示し、ユーザの入力を得るための優れた方法です。背景やボタンに画像を使うことができるので、どのように見えるようにすることもできます。注意インタフェースは単独では存在せず、zscriptまたはpluginボタンから呼び出さなければなりません。
Noteインターフェイスの詳細については、「ZScriptノートインターフェイス」を参照してください。
Where to Next?
あなたがこれを遠くに持っていれば、あなたは熟練したzscripterであることへの道のりです。このセクションでは、知識を広げて才能を伸ばすためのオプションについて簡単に説明します。
Special Text Editors
もしあなたがzscriptingのバグを持っていれば、プログラマのために設計されたテキストエディタを入手することを検討したいかもしれません。多くの便利な機能の中で最も有用なのは、さまざまなコマンドが異なる色で表示される構文ハイライトです。コードの読み取りと編集が非常に簡単です。
UltraEditの例を以下に示します
テキストエディタの選択
- UltraEdit
- テキストエディタや有用な情報については、こことここを参照してください。
- ZScriptコマンドリファレンス
- 約200のZScriptコマンドがあります。各コマンドの説明と使用方法の例については、「ZScriptコマンドリファレンス」を参照してください。