SkyUI MCMのチュートリアル
イントロダクション
Mod Configuration Menu (MCM)は名前の通りModの調整メニューを追加します。
これは自分自身でModのメニューをとりあえず作れるようになるためのチュートリアルです。
ある程度Papyrusに触ったことがある方向けです。最低限CK wikiのスクリプトチュートリアルは済ませましょう。
これは自分自身でModのメニューをとりあえず作れるようになるためのチュートリアルです。
ある程度Papyrusに触ったことがある方向けです。最低限CK wikiのスクリプトチュートリアルは済ませましょう。
準備
SkyUI wikiからSkyUI SDKを入れます。
この解説はSkyUI SDK 3.1時のものです。基本的な流れは変わりません。
ダウンロードしたファイルを解凍してScriptフォルダをDataフォルダに入れます。
そしてSkyUI本体も入れておきます。
この解説はSkyUI SDK 3.1時のものです。基本的な流れは変わりません。
ダウンロードしたファイルを解凍してScriptフォルダをDataフォルダに入れます。
そしてSkyUI本体も入れておきます。
あなたのModのespをCKで開いてから、Object WindowからQuest項目を選びます。
右クリックしてNewを選択し新しくクエストを作ります。
Quest DataタブでIDを入力(例: aaaxxMCMQuest)。
Start Game Enabledはチェック、Run at onceはチェックを外す。
一旦OK押して閉じます。
右クリックしてNewを選択し新しくクエストを作ります。
Quest DataタブでIDを入力(例: aaaxxMCMQuest)。
Start Game Enabledはチェック、Run at onceはチェックを外す。
一旦OK押して閉じます。
再度作成したクエストを開いて、Quest Aliasタブを開きます。
右クリックしてNew Reference Aliasを選びます。
左上AliasにAliasの名前を入力(例:MCMPlayerAlias)
Fill TypeをSpecific Referenceを選んで、Select Forced Referenceボタンを押します。
cellは(any)、RefはPlayerRef('Player')です。
右クリックしてNew Reference Aliasを選びます。
左上AliasにAliasの名前を入力(例:MCMPlayerAlias)
Fill TypeをSpecific Referenceを選んで、Select Forced Referenceボタンを押します。
cellは(any)、RefはPlayerRef('Player')です。
次に画面右側Scripts欄のAddボタンを押します。
Filterにskiとうって検索を絞りSKI_PlayerLoadGameAliasを選びます。
これでAliasは終了ですのでAliasのウィンドウをOKして閉じます。
Filterにskiとうって検索を絞りSKI_PlayerLoadGameAliasを選びます。
これでAliasは終了ですのでAliasのウィンドウをOKして閉じます。
Scriptsタブを開いてAddボタンを押します。
newscriptを選んで、新しく名前をつけ(例:aaaxxMCMScript)、{Extendsを
ski_configbase}にしてOKを押します。
スクリプトのウィンドウを一旦閉じて、Propertiesボタンを押します。
ModNameを選択してEdit Value。
ここにMod名を記載します。(例:Test)
これで準備は整いました。
後は新しく作ったスクリプトに記述していきます。
newscriptを選んで、新しく名前をつけ(例:aaaxxMCMScript)、{Extendsを
ski_configbase}にしてOKを押します。
スクリプトのウィンドウを一旦閉じて、Propertiesボタンを押します。
ModNameを選択してEdit Value。
ここにMod名を記載します。(例:Test)
これで準備は整いました。
後は新しく作ったスクリプトに記述していきます。
MCMの構造と流れ
構造と流れさえ分かればそこまで難しくないです。
![](http://img.atwiki.jp/skyrim_mod/attach/46/264/mcmconst.png)
細かいことはさておき、手を動かしてみましょう。
Scriptname aaaxxMCMScript extends ski_configbase ;変数の定義 int ToggleTestID bool bToggleTest = true ;ページの設定 Event OnPageReset(string page) ToggleTestID = AddToggleOption("Test Toggle", bToggleTest) endEvent int function GetVersion() return 1 endFunction ;選択時の設定 Event OnOptionSelect(int option) if (option == ToggleTestID) bToggleTest = !bToggleTest SetToggleOptionValue(ToggleTestID, bToggleTest) If(bToggleTest) ; bToggleTestがtrueなら グローバル変数.SetValue(1) Else ; bToggleTestがそれ以外(false)なら グローバル変数.SetValue(0) EndIf endIf endEvent ;デフォルトの設定(Fキー押した時に呼び出されるイベント) Event OnOptionDefault(int option) If(option == ToggleTestID) if (!bToggleTest) bToggleTest = true SetToggleOptionValue(ToggleTestID, bToggleTest) ; グローバル変数.SetValue(1) endif EndIf EndEvent ;カーソルが乗った時に下に出るテキストの設定 Event OnOptionHighlight(int option) If(option == ToggleTestID) if (!bToggleTest) SetInfoText("Toggle this option on to activate the mod.") else SetInfoText("Toggle this option off to deactivate the mod.") endif EndIf EndEvent
スクリプトを書いたらコンパイルしてからespを保存し、espをアクティブにして実際にゲーム内で確認してみましょう。
Escキーでメニューを開いて、システムタブのMod Configurationです。
例のとおりですとtestという項目があるのでそれを開いて確認してください。
ToggleTestを押しても実際には何にも効果がないのですが、とりあえずは表示できて動かせたと思います。
例のとおりですとtestという項目があるのでそれを開いて確認してください。
ToggleTestを押しても実際には何にも効果がないのですが、とりあえずは表示できて動かせたと思います。
変数の定義(IDとMCM内の変数の2つ)
OnPageResetにID = Add~Option()を書く
Event OnOption~()内にif option == ID
Set~OptionValue(ID,変数)でMCM上の数値をセットし、グローバル変数か何かで変更した値を渡す。
OnPageResetにID = Add~Option()を書く
Event OnOption~()内にif option == ID
Set~OptionValue(ID,変数)でMCM上の数値をセットし、グローバル変数か何かで変更した値を渡す。
というのが基本的な流れです。
実際に動くメニューを作る
以下の機能を実装したいと思います。
- 時間変更をするスライダー
- 天候を晴れにする機能のキー設定変更
- キルムーブのOn/Off
- キルムーブの確率
まず、天候機能を作ります。
Miscellanneous->Globalで右クリックしてNew、aaaWeatherKeyを作ります。
Short, Valueは199。
Miscellanneous->Globalで右クリックしてNew、aaaWeatherKeyを作ります。
Short, Valueは199。
先ほどのメニューのクエスト(aaaxxMCMQuest)をDepulicateしてaaaWeatherQuestにします。
クエストのスクリプトを削除して新しくスクリプト(aaaxxWeatherScript)を作ります。
Scriptname aaaxxWeatherScript extends Quest int WeatherKey GlobalVariable property aaaWeatherKey auto Weather property SkyrimClear auto int function GetVersion() return 1 endFunction
Event OnInit() RegisterKey() EndEvent Function RegisterKey() UnregisterForKey(WeatherKey) WeatherKey = aaaWeatherKey.GetValueInt() RegisterForKey(WeatherKey) EndFunction Event OnKeyDown(Int KeyCode) if (KeyCode == WeatherKey) SkyrimClear.ForceActive() endif EndEvent
Property の設定を忘れないように。Auto-Fill Allで全部埋まります。
次にQuest Aliasタブを開いて、プレイヤーのAliasを開きます。
SKI_PlayerLoadGameAliasを削除して新しくスクリプトを作ります。
SKI_PlayerLoadGameAliasを削除して新しくスクリプトを作ります。
Scriptname aaaxxTestAliasScript extends ReferenceAlias aaaxxWeatherScript Property QuestScript Auto Event OnPlayerLoadGame() QuestScript.RegisterKey() EndEvent
ロード時に登録したキーが消えるバグがあるので、OnPlayerLoadGame()でロード度にキーを登録し直します。aaaxxWeatherScriptのプロパティの登録を忘れずに。
天気の機能はコレで終わりです。
あとはMCMのスクリプトを書くだけです。
コードが長いけどもめげないこと。
あとはMCMのスクリプトを書くだけです。
コードが長いけどもめげないこと。
Scriptname aaaxxMCMScript extends ski_configbase ;プロパティ aaaxxWeatherScript Property QuestScript Auto GlobalVariable Property KillMove auto GlobalVariable Property KillMoveRandom auto GlobalVariable Property GameHour auto GlobalVariable Property aaaWeatherKey auto ;変数の定義 int KillMoveActiveID int KillMoveRandomID int GameHourID int WeatherKeyID bool _KillMoveActive = true float _KillMoveRandom = 50.0 float _GameHour = 8.0 int _WeatherKey = 199 ;home key ; 初期化 Event OnConfigInit() EndEvent ;このMCMのバージョン int function GetVersion() return 1 endFunction ;ページの設定 Event OnPageReset(string page) SetCursorFillMode(TOP_TO_BOTTOM) AddHeaderOption("KillMove") KillMoveActiveID = AddToggleOption("KillMove", _KillMoveActive) KillMoveRandomID = AddSliderOption("KillMove Random", _KillMoveRandom, "Percent:{0}") AddHeaderOption("Time") GameHourID = AddSliderOption("GameHour", _GameHour, "Hour:{0}") AddHeaderOption("KeyConfig") WeatherKeyID = AddKeyMapOption("WeatherKey", _WeatherKey) endEvent ;選択時の設定 Event OnOptionSelect(int option) if (option == KillMoveActiveID) _KillMoveActive = !_KillMoveActive SetToggleOptionValue(KillMoveActiveID, _KillMoveActive) If(_KillMoveActive) KillMove.SetValue(1) Else KillMove.SetValue(0) EndIf endIf endEvent ;スライダー開いた時のイベント・設定 Event OnOptionSliderOpen(int option) if (option == KillMoveRandomID) SetSliderDialogStartValue(_KillMoveRandom) SetSliderDialogDefaultValue(50) SetSliderDialogRange(0, 100) SetSliderDialogInterval(1) elseif (option == GameHourID) SetSliderDialogStartValue(_GameHour) SetSliderDialogDefaultValue(8) SetSliderDialogRange(0, 24) SetSliderDialogInterval(1) endIf EndEvent Event OnOptionSliderAccept(int option, float value) if (option == KillMoveRandomID) _KillMoveRandom = value SetSliderOptionValue(KillMoveRandomID, _KillMoveRandom, "Percent: {0}") KillMoveRandom.SetValue(_KillMoveRandom) elseif (option == GameHourID) _GameHour = value SetSliderOptionValue(GameHourID, _GameHour, "Hour: {0}") GameHour.SetValue(_GameHour) endIf EndEvent Event OnOptionKeyMapChange(int option, int keyCode, string conflictControl, string conflictName) if (option == WeatherKeyID) _WeatherKey = keyCode SetKeyMapOptionValue(WeatherKeyID, _WeatherKey) aaaWeatherKey.SetValue(_WeatherKey) QuestScript.RegisterKey() ;キーの再登録が必要 endIf EndEvent ;デフォルトの設定(Fキー押した時の挙動) Event OnOptionDefault(int option) If(option == KillMoveActiveID) if (!_KillMoveActive) _KillMoveActive = true SetToggleOptionValue(KillMoveActiveID, _KillMoveActive) KillMove.SetValue(1) endif ElseIf(option == KillMoveRandomID) _KillMoveRandom = 50 SetSliderOptionValue(KillMoveRandomID, _KillMoveRandom, "Percent: {0}") KillMoveRandom.SetValue(_KillMoveRandom) ElseIf(option == GameHourID) _GameHour = 8 SetSliderOptionValue(GameHourID, _GameHour, "Hour: {0}") GameHour.SetValue(_GameHour) ElseIf(option == WeatherKeyID) _WeatherKey = 199 SetKeyMapOptionValue(WeatherKeyID, _WeatherKey) aaaWeatherKey.SetValue(_WeatherKey) EndIf EndEvent ;カーソルが乗った時に下に出るテキストの設定 Event OnOptionHighlight(int option) If(option == KillMoveActiveID) if (!_KillMoveActive) SetInfoText("Toggle this option on to activate killmove.") else SetInfoText("Toggle this option off to deactivate killmove.") endif Elseif(option == KillMoveRandomID) SetInfoText("Killmove random percent.") Elseif(option == GameHourID) SetInfoText("Set game hour.") Elseif(option == WeatherKeyID) SetInfoText("Set Weather Key.") EndIf EndEvent
例のごとくプロパティ登録を忘れずに。
注意すべき点は1スクリプトにつき、同一のイベントは一つまでなので、 イベント内でif (option == ID)で振り分けます。
作ったMCMを更新するとき
int function GetVersion() return 2 endFunction
returnのところの数値を整数で一つ上げます。ここの数値が変わったタイミングでOnUpdateVersion()のイベントが動くので、ここに追加項目(初期設定だとOnInit()に書く内容)を記載します。
例はキーとリストの追加。
例はキーとリストの追加。
Event OnUpdateVersion() DodgeKey = Input.GetMappedKey("Sprint") SetKeyMapOptionValue(keyID, DodgeKey) InputMethodList = new string[3] InputMethodList[0] = "DodgeKey/2Tap" InputMethodList[1] = "DodgeKey" InputMethodList[2] = "GamePad/2Tap" EndEvent
添付ファイル