這個教學覆蓋4個部分: 陣列(Arrays),錯誤檢查(Error Checking),訊息盒(Message Box),及使用者介面(User Interfaces).
前次的亂數旋轉有兩個錯誤.
- 如果沒選物件會出錯
- 沒法設定亂數範圍
陣列(Arrays)
簡單的說, 一個陣列就是一列物件. Maxscript中幾乎每個物件都可以被指定為變數, 然後再存入陣列中.
先建立一個空的陣列, 再給一個名稱, 先在Listener 輸入指令並執行...
ourFirstArray = #()
ourFirstArray是陣列名稱, #是Maxscript中的陣列符號, ()括弧中是要放陣列內容, 在這裡是空的.現在要放一些東西到陣列中,會用到一個 append 函數來放東西到陣列中.
append ourFirstArray 1
append ourFirstArray 3
之後再輸入
ourFirstArray
得到 #(1,3), 裡面有兩個元件 1 及 3
我們可以繼續增加陣列內容, 但要如何取得陣列的內容呢? 陣列中每一個元件的編號是以1遞增, 所以要取得ourFirstArray第二個元件, 可以輸入
ourFirstArray[2]
得到之前存入的整數3
陣列還有一個常用的特性(property),名稱叫 .count ,在MaxScript Listener 中輸入
ourFirstArray.count
得到2, 表示陣列長度.
錯誤檢查(Error Checking)
打開之前所寫的程式,
MacroScript Random_Rotate category:"Rhys Tools" buttonText:"Random Rotate" tooltip:"Random Rotate" (
for obj in $ do ( -- 對所選物執行迴圈...
randXrot = random -3.0 3.0 -- 建立X軸旋轉亂數範圍
randYrot = random -3.0 3.0 -- 建立Y軸旋轉亂數範圍
randZrot = random -3.0 3.0 -- 建立Z軸旋轉亂數範圍
rotObj = eulerangles randXrot randYrot randZrot -- 建立尤拉旋轉物件
rotate obj rotObj -- 應用到當前執行物件
)
)
現在已經知道用$可以存取當前所選物件, 另一個方法是存取 "selection", 這是一個MAX內建陣列. 選取場景中多個物件後, 輸入
selection.count
得到現在所選物件的數量.
再輸入...
selection[1]
得到所選的第一個物件資料, 現在不選任何場景物件, 輸入
selection.count
得到 0 , 表示沒有選取任何物件. 所以知道可以增加一小段script來測試是否有選到物件.
MacroScript Random_Rotate category:"Rhys Tools" buttonText:"Random Rotate" tooltip:"Random Rotate" (
if (selection.count > 0) then ( -- 如果所選物大於0,則執行以下...
for obj in $ do (
randXrot = random -3.0 3.0
randYrot = random -3.0 3.0
randZrot = random -3.0 3.0
rotObj = eulerangles randXrot randYrot randZrot
rotate obj rotObj
)
)
)
加上if判斷式後, 就可以避免沒有選取物時執行程式,而出現錯誤.
若再加上一個警告訊息提醒出錯會更好.
訊息盒(Message Box)
這裡會用到 else 語法. 若沒選任何物件, 就執行else的內容, 跳出警告訊息盒.
MacroScript Random_Rotate category:"Rhys Tools" buttonText:"Random Rotate" tooltip:"Random Rotate" (
for obj in $ do -- Loop over currently selected objects (
if (selection.count > 0) then (
randXrot = random -3.0 3.0
randYrot = random -3.0 3.0
randZrot = random -3.0 3.0
rot_obj = eulerangles randXrot randYrot randZrot
rotate obj rot_obj
) else (
messagebox "You must have at least one object selected!" -- 警告訊息盒
)
)
)
加入if/then 及 else 語法及內容後, 我們解決了第一個問題.
使用者介面(User Interfaces)
為了解決第二個問題,必須建立一個介面,讓使用者輸入旋轉的亂數範圍.
執行 Maxscript > visual Maxscript editor
開啟Visual Maxscript Editor, 它可以很簡單的建立介面.
設計好介面後, 存成.vms(Visual Maxscript Editor)格式, 再另存成.ms, 可用來修改程式碼.
用Maxscript Editor開啟之前的.ms 檔, 裡面已經有一些關於介面的程式碼,如下.
rollout RandomRotateRollout "Random Rotate" width:162 height:122
(
groupBox grp1 "Random Rotation Range" pos:[10,12] width:142 height:99
button btn1 "Randomly Rotate!" pos:[19,81] width:125 height:22
spinner spn1 "Minimum value " pos:[22,34] width:122 height:16 range:[-360.0,360.0,0.0]
spinner spn2 "Maximum value" pos:[23,56] width:122 height:16 range:[-360.0,360.0,0.0]
)
再做進一步修改, 將主程式放進 on btn1 pressed do 括號裡面,
rollout RandomRotateRollout "Random Rotate" width:162 height:122 (
groupBox grp1 "Random Rotation Range" pos:[10,12] width:142 height:99
button btn1 "Randomly Rotate!" pos:[19,81] width:125 height:22
spinner spn1 "Minimum value " pos:[22,34] width:122 height:16 range:[-360.0,360.0,0.0]
spinner spn2 "Maximum value" pos:[23,56] width:122 height:16 range:[-360.0,360.0,0.0]
on btn1 pressed do (-- 當btn1被按...
if (selection.count > 0) then ( -- 選取物件數量大於0,才執行...
for obj in $ do (-- 對所選物執行迴圈...
randXrot = random -3.0 3.0 -- 建立X軸旋轉亂數範圍
randYrot = random -3.0 3.0 -- 建立Y軸旋轉亂數範圍
randZrot = random -3.0 3.0 -- 建立Z軸旋轉亂數範圍
rot_obj = eulerangles randXrot randYrot randZrot -- 建立尤拉旋轉物件
rotate obj rot_obj -- 應用到當前執行物件
) else (
messagebox "You must have at least one object selected!"
)
)
)
)
接下來要做一些處理, 用spn1.value 與 spn2.value 取代 -3.0 及 3.0 , 以後最小最大值就由spn1與spn2的輸入值決定.
執行Script時, 發現沒顯示出程式介面, 所以必須加上一行程式, 包裝成一個正式的MacroScript 程式.
createDialog RandomRotateRollout 162 120 -- 寬162, 高120
最後版本如下
MacroScript Random_Rotate category:"Rhys Tools" buttonText:"Random Rotate" tooltip:"Random Rotate" (
rollout RandomRotateRollout "Random Rotate" width:162 height:122 (
groupBox grp1 "Random Rotation Range" pos:[10,12] width:142 height:99
button btn1 "Randomly Rotate!" pos:[19,81] width:125 height:22
spinner spn1 "Minimum value " pos:[22,34] width:122 height:16 range:[-360.0,360.0,0.0]
spinner spn2 "Maximum value" pos:[23,56] width:122 height:16 range:[-360.0,360.0,0.0]
on btn1 pressed do ( -- when btn1 is pressed do...
for obj in $ do ( -- Loop over currently selected objects
if (selection.count > 0) then (
randXrot = random spn1.value spn2.value
randYrot = random spn1.value spn2.value
randZrot = random spn1.value spn2.value
rot_obj = eulerangles randXrot randYrot randZrot
rotate obj rot_obj
) else (
messagebox "You must have at least one object selected!"
)
)
)
)
createDialog RandomRotateRollout 162 120
)
執行後,開啟自訂介面, 將Script以自己喜好方式呈現.
結果如圖所示
MAX Script 教學-4
http://vimeo.com/42498838
回覆刪除請問類似這樣要如何寫
將一個物件貼到另一物件上
並且要復製
或是
線拉升後,分開
謝謝
這個問題有難度,過去沒寫過類似的,目前不知如何回答,有空會去研究研究...謝謝您的提問,雖然幫不了什麼忙...
回覆刪除http://www.softimageblog.com/archives/33
回覆刪除http://www.3dtotal.com/index_tutorial_detailed.php?id=1138#.UOVleXd93To
刪除