「SkyUI MCM」の編集履歴(バックアップ)一覧に戻る

SkyUI MCM - (2014/01/06 (月) 00:38:15) のソース

SkyUI MCMのチュートリアル

SkyUI wiki
https://github.com/schlangster/skyui/wiki

Quick Start(SkyUI公式チュートリアル)
https://github.com/schlangster/skyui/wiki/MCM-Quickstart

API Reference(SkyUI公式レファレンス)
https://github.com/schlangster/skyui/wiki/MCM-API-Reference

・イントロダクション
Mod Configuration Menu (MCM)は名前の通りMod調整メニューを追加します。
これは自分自身でModのメニューをとりあえず作れるようになるためのチュートリアルです。ある程度Papyrusに触ったことがある方向け。

・準備
SkyUI wikiからSkyUI SDKを入れます。
Skyrim 1.8なら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押して閉じます。

再度作成したクエストを開いて、Quest Aliasタブを開きます。
右クリックして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して閉じます。

Scriptsタブを開いてAddボタンを押します。
newscriptを選んで、新しく名前をつけ(例:aaaxxMCMScript)、Extendsを
ski_configbaseにしてOKを押します。
スクリプトのウィンドウを一旦閉じて、Propertiesボタンを押します。
ModNameを選択してEdit Value。
ここにMod名を記載します。(例:Test)
これで準備は整いました。
後は新しく作ったスクリプトに記述していきます。

・MCMの構造と流れ
構造と流れさえ分かればそこまで難しくないです。

細かいことはさておき、手を動かしてみましょう。

Scriptname aaaxxMCMScript extends  ski_configbase

;変数の定義
int ToggleTestID
bool bToggleTest = true

;ページの設定
Event OnPageReset(string page)
    ToggleTestID = AddToggleOption("Test Toggle", bToggleTest)
 endEvent

;選択時の設定
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を押しても実際には何にも効果がないのですが、とりあえずは表示できて動かせたと思います。

変数の定義(IDとMCM内の変数の2つ)
OnPageResetにID = Add~Option()を書く
Event OnOption~()内にif option == ID
Set~OptionValue(ID,変数)でMCM上の数値をセットし、グローバル変数か何かで変更した値を渡す。

というのが基本的な流れです。


・実際に動くメニューを作る

以下の機能を実装したいと思います。
時間変更をするスライダー
天候を晴れにする機能のキー設定変更
キルムーブのOn/Off
キルムーブの確率

まず、天候機能を作ります。
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

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を削除して新しくスクリプトを作ります。


Scriptname aaaxxTestAliasScript extends ReferenceAlias  

aaaxxWeatherScript Property QuestScript Auto

Event OnPlayerLoadGame()
    QuestScript.RegisterKey()
EndEvent

ロード時に登録したキーが消えるバグがあるので、OnPlayerLoadGame()でロード度にキーを登録し直します。aaaxxWeatherScriptのプロパティの登録を忘れずに。

天気の機能はコレで終わりです。
あとは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 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)で振り分けます。


あとはAPI Referenceみればなんとかなると思います(丸投げ)
目安箱バナー