msw-defaultplayer について
msw-defaultplayerは、MapleStory WorldsのDefaultPlayerモデルをModelBuilderで確認・変更するスキルです。ゲーム制作者向けに、プレイヤーのコンポーネントや移動、物理、HP、カメラを設定できます。
主な機能
- 01DefaultPlayerモデルの確認と変更
- 02プレイヤーコンポーネントの管理
- 03移動と物理設定
- 04HPとカメラ設定の調整
- 05実行時のプレイヤー階層の把握
活用シーン
- 01移動やジャンプ設定の変更
- 02カメラ追従やHPの調整
- 03プレイヤーコンポーネントの追加・削除
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ msw-git/ msw-ai-coding-plugins-official --skill msw-defaultplayerインストール後、Claude Code で/msw-defaultplayerを入力して読み込まれたか確認します。
詳細
MSW DefaultPlayer
msw-general ModelBuilder を使用して DefaultPlayer モデルファイルを確認・修正し、コンポーネントを管理して、移動/物理/HP/カメラを設定します。
コスチューム/アバター装備については、
msw-avatarスキルを参照してください。コスチュームは DefaultPlayer だけでなく、あらゆるエンティティに適用されるため、別のスキルで扱います。
DefaultPlayer の概要
DefaultPlayer とは?
MapleStory Worlds Maker ワークスペースにデフォルトで用意されているプレイヤーキャラクターモデルです。
- ユーザーがワールドに入ると、このモデルに基づいてプレイヤーエンティティが作成されます。
- 使用するモデル ID は、
DefaultUserEnterLeaveLogicのPlayerUriプロパティで指定します。
ファイルの場所と構造
DefaultPlayer は、2 つの .model ファイルで構成されています。
| ファイル | パス | 役割 |
|---|---|---|
| Player.model | ./Global/Player.model | ベースモデルです。Components リストと Properties リンクを定義します |
| DefaultPlayer.model | ./Global/DefaultPlayer.model | Player を継承します(BaseModelId: "player")。Values を上書きします |
重要:どちらのファイルも
./Global/にあります。カスタムスクリプトファイルは./RootDesk/MyDesk/の下に作成します。
DefaultPlayer は ModelBuilder を通じてパッチを適用します
DefaultPlayer は、生の JSON を直接編集するのではなく、隣接する msw-general/scripts/model/msw_model_builder.cjs を通じて管理します。
- プロパティ値を変更する場合:
ModelBuilder.read("./Global/DefaultPlayer.model").value(...) - コンポーネントを追加/削除する場合:
component()/removeComponent() - ベースのコンポーネントリストを確認する場合:
ModelBuilder.snapshot("./Global/Player.model")
ファイル構造の詳細
Player.model(ベース)
Path: ./Global/Player.model
EntryKey: model://player
Components:プレイヤーにデフォルトで設定されるコンポーネントの全リスト(MOD.Core.* ネイティブコンポーネント)Properties:モデルプロパティとコンポーネントプロパティのリンク定義(インスペクターから編集可能なプロパティ)Values:空です(デフォルト値はエンジンによって提供されます)
DefaultPlayer.model(オーバーライド)
Path: ./Global/DefaultPlayer.model
EntryKey: model://defaultplayer
BaseModelId: "player"
Components:DefaultPlayer に追加されるコンポーネントのみ(例:script.PlayerHit、script.PlayerAttack)Values:上書きされた設定値の配列
DefaultPlayer のデフォルトコンポーネント一覧
Player.model から継承されるネイティブコンポーネント:
| コンポーネント | 役割 |
|---|---|
| TransformComponent | 位置、回転、スケール |
| MovementComponent | 移動速度とジャンプ力の制御 |
| RigidbodyComponent | 物理(重力、足場)、MapleStory スタイルの移動 |
| KinematicbodyComponent | RectTileMap 上での上下左右の移動 |
| SideviewbodyComponent | SideViewRectTileMap 上での横スクロール移動 |
| StateComponent | ステートマシン(歩行、ジャンプ、死亡など) |
| AvatarRendererComponent | アバターのレンダリング、色、感情 |
| AvatarStateAnimationComponent | ステートからアバターアニメーションへのマッピング |
| CostumeManagerComponent | 装備/コスチューム管理 → 詳細は msw-avatar スキルを参照してください |
| CameraComponent | カメラの追従設定 |
| PlayerControllerComponent | 入力からアクションへのマッピング、条件処理 |
| PlayerComponent | HP、死亡/復活、PVP、マップ移動 |
| ChatBalloonComponent | チャット吹き出し |
| NameTagComponent | ネームタグ |
| DamageSkinSettingComponent | ダメージスキン |
| DamageSkinSpawnerComponent | ダメージスキンのスポーン |
| HitEffectSpawnerComponent | ヒットエフェクトのスポーン |
| TriggerComponent | 衝突検出 |
| InventoryComponent | インベントリ |
DefaultPlayer.model で追加されるスクリプトコンポーネント:
| コンポーネント | 役割 |
|---|---|
| script.PlayerHit | プレイヤーの被弾処理ロジック |
| script.PlayerAttack | プレイヤーの攻撃ロジック |
クイックリファレンス — 主要コンポーネント
| コンポーネント | 役割 | 主なプロパティ/メソッド |
|---|---|---|
| PlayerComponent | HP、死亡/復活、PVP、マップ移動 | Hp, MaxHp, PVPMode, RespawnDuration, RespawnPosition, UserId, IsDead(), ProcessDead(), ProcessRevive(), MoveToMapPosition() |
| PlayerControllerComponent | 入力からアクションへのマッピング、条件付き制御 | SetActionKey(key, actionName), ActionAttack(), ActionJump(), LookDirectionX |
| MovementComponent | 高レベルの移動速度/ジャンプインターフェース | InputSpeed(デフォルト 1.0), JumpForce(デフォルト 1), Jump(), Stop() |
| RigidbodyComponent | Maple のサイドビュー物理(重力/足場) | Gravity, WalkAcceleration, WalkSpeed, AddForce(), IsOnGround() |
| KinematicbodyComponent | RectTile 上でのトップビュー移動(上下左右) | (RectTile マップモードのみ) |
| SideviewbodyComponent | SideViewRectTile 上でのサイドビュー | (SideViewRectTile マップモードのみ) |
| AvatarRendererComponent | アバターの描画/色/感情 | SetColor(), SetAlpha(), PlayEmotion(), PlayRate |
| StateComponent | ステートマシン(Walk/Jump/Dead) | CurrentStateName, ChangeState(), DeadEvent/ReviveEvent |
| NameTagComponent | ネームタグ | Name, FontSize, FontColor, NameTagRUID |
| ChatBalloonComponent | チャットバルーン | Message, ChatModeEnabled, ShowDuration |
| CameraComponent | カメラの追従 | DeadZone, SoftZone, Damping, ScreenOffset |
| TriggerComponent | 衝突検出 | BoxSize, Offset, CollisionGroup |
DefaultPlayer の Values 構造
DefaultPlayer.model の Values 配列にある各エントリーの形式:
{
"TargetType": "<component name> or null",
"Name": "<property name>",
"ValueType": {
"$type": "MODNativeType",
"type": "<type info>"
},
"Value": <value>
}
TargetType のルール
null:Player.model の Properties で定義されたモデルプロパティ(Properties を介して実際のコンポーネントプロパティにリンクされています)"MOD.Core.<ComponentName>":特定のネイティブコンポーネントのプロパティを直接上書きします"script.<ScriptName>":カスタムスクリプトコンポーネントのプロパティです
モデルプロパティ(TargetType: null)
Player.model の Properties で定義されたリンクを介して、実際のコンポーネントプロパティにマッピングされます。
| モデルプロパティ名 | ソースのコンポーネントプロパティ | 説明 | デフォルト |
|---|---|---|---|
| speed | MovementComponent.InputSpeed | 移動速度 | 1.0 |
| jumpForce | MovementComponent.JumpForce | ジャンプの高さ | 1.0 |
| walkAcceleration | RigidbodyComponent.WalkAcceleration | 加速/減速 | 1.0 |
| gravity | RigidbodyComponent.Gravity | 重力 | 1.0 |
| cameraDeadZone | CameraComponent.DeadZone | カメラのデッドゾーン | {x: 0.052, y: 0.08} |
| cameraSoftZone | CameraComponent.SoftZone | カメラのソフトゾーン | {x: 0.268, y: 0.7} |
| cameraDamping | CameraComponent.Damping | カメラのスムーズな追従 | {x: 2.5, y: 3.9} |
| cameraScreen | CameraComponent.ScreenOffset | デッドゾーンの中心点 | {x: 0.5, y: 0.655} |
| cameraDutch | CameraComponent.DutchAngle | カメラの回転 | 0.0 |
| cameraOffset | CameraComponent.CameraOffset | カメラ位置のオフセット | {x: 0.0, y: 0.0} |
| message | ChatBalloonComponent.Message | チャットバルーンのメッセージ | "" |
| chatModeEnabled | ChatBalloonComponent.ChatModeEnabled | チャットを処理するかどうか(例:バルーンを表示する) | true |
| nameTag | NameTagComponent.Name | ネームタグ | "" |
| damageSkinId | DamageSkinSettingComponent.DamageSkinId | ダメージスキンの種類 | DataRef |
| damageDelayPerAttack | DamageSkinSettingComponent.DelayPerAttack | ダメージの遅延 | 0.05 |
| triggerBodyBoxSize | TriggerComponent.BoxSize | 衝突検出領域のサイズ | {x: 0.66, y: 0.7} |
| triggerBodyBoxOffset | TriggerComponent.BoxOffset | 衝突検出領域のオフセット | {x: 0.0, y: 0.35} |
| triggerBodyColliderOffset | TriggerComponent.ColliderOffset | コライダーのオフセット | {x: 0.0, y: 0.35} |
| maxHp | PlayerComponent.MaxHp | 最大 HP | 1000 |
直接コンポーネントの上書き(TargetType: specific component)
モデルプロパティリンクを介さず、コンポーネントのプロパティを直接上書きする値です。
| TargetType | Name | Description | Default |
|---|---|---|---|
| MOD.Core.CameraComponent | ZoomRatioMax | カメラの最大ズーム比率 | 500.0 |
| MOD.Core.MovementComponent | JumpForce | ジャンプ力(直接上書き) | 1.0 |
| MOD.Core.MovementComponent | InputSpeed | 移動速度(直接上書き) | 1.0 |
| script.PlayerHit | CollisionGroup | 当たり判定の衝突グループ | CollisionGroup ID |
| script.PlayerHit | BoxSize | 当たり判定領域のサイズ | {x: 0.45, y: 0.7} |
| script.PlayerHit | ColliderOffset | 当たり判定のオフセット | {x: 0.0, y: 0.35} |
マップモードごとの移動コンポーネント
TileMapMode↔Body の対応表については、
msw-general/references/platform.md§4 を参照してください。マップモードに応じて、RigidbodyComponent/KinematicbodyComponent/SideviewbodyComponent のいずれかが有効になります。
プレイヤーの識別(スクリプトから参照する場合)
entity.PlayerComponent ~= nil→ エンティティがプレイヤーかどうか_UserService.LocalPlayer→ 自分のプレイヤーエンティティ(クライアント専用)_UserService:GetUserEntityByUserId(userId)→ 特定のユーザーのプレイヤーエンティティ
プレイヤーエンティティの実行時構造(ルートと子)
スポーンしたプレイヤーは、単一のフラットなエンティティではありません。実行時にエンジンがプレイヤールートの下に小さな階層を構築し、アバターのアクションセレクターはルートではなく孫エンティティに配置されます。これは、コンポーネントの検索方法やアバターのポーズのトリガー方法に影響します。
コンポーネントとエンティティの対応
| Component | Where it lives | Lookup |
|---|---|---|
PlayerComponent | ルート | player:GetComponent("PlayerComponent")(または player.PlayerComponent) |
StateComponent | ルート | player:GetComponent("StateComponent") |
MovementComponent | ルート | player:GetComponent("MovementComponent") |
AvatarRendererComponent | ルート | player.AvatarRendererComponent |
AvatarStateAnimationComponent | ルート | player:GetComponent("AvatarStateAnimationComponent") |
PlayerControllerComponent | ルート | player.PlayerControllerComponent |
AvatarBodyActionSelectorComponent | ルートの Body 孫エンティティ(アバタールートの下) | player:GetComponent(...) からは取得できません — 下記を参照 |
AvatarFaceActionSelectorComponent | ルートの Face 孫エンティティ | player:GetComponent(...) からは取得できません — 下記を参照 |
player:GetComponent("AvatarBodyActionSelectorComponent") は nil を返します。また、LSP は警告を出しません(シグネチャは nil を許容しない Component です)。この失敗は実行時にのみ確認できます。
セレクターへのアクセス方法
-- ClientOnly context (recommended — the direct API)
local body = self.Entity.AvatarRendererComponent:GetBodyEntity()
local face = self.Entity.AvatarRendererComponent:GetFaceEntity()
local bodySelector = body and body:GetComponent("AvatarBodyActionSelectorComponent")
local faceSelector = face and face:GetComponent("AvatarFaceActionSelectorComponent")
-- Server or "either side" context (GetBodyEntity / GetFaceEntity are ClientOnly)
local bodySelector = self.Entity:GetFirstChildComponentByTypeName(
"AvatarBodyActionSelectorComponent", true)
AvatarRendererComponent:GetBodyEntity()とGetFaceEntity()は@ExecSpace("ClientOnly")として宣言されているため、サーバー側のメソッドから呼び出すとnilを返します。サイドをまたいで使える代替手段として、GetFirstChildComponentByTypeName(name, recursive=true)を使用してください。
アバターのポーズをトリガーする — セレクターに直接書き込まず、StateComponent を使用する
稼働中のプレイヤーでは、毎ティック状態マシンが実行されています。PlayerControllerComponent が入力と移動を評価し、StateComponent が状態(IDLE/MOVE など)を遷移させ、AvatarStateAnimationComponent.ReceiveStateChangeEvent がそれを BodyActionStateChangeEvent に変換し、セレクターの ActionState が書き換えられます。
つまり、AvatarBodyActionSelectorComponent.ActionState に直接書き込むと、通知されずに上書きされます。値が反映されるのは1フレームだけで、その後の状態マシンのティックで現在の StateComponent の状態がセレクターに再び反映され、書き込んだ値は消えます。代入直後のログには ActionState=Attack と表示されますが、プレイモードではポーズが1フレームだけちらついて消えます。
正しいエントリーポイント
local state = self.Entity:GetComponent("StateComponent")
state:ChangeState("ATTACK") -- ActionSheet keys are UPPERCASE
状態キーはプレイヤーの ActionSheet に由来します。DefaultPlayer には、デフォルトのアニメーションにそれぞれ対応する 11 個の大文字キーが用意されています。
StateComponent:ChangeState(...) のキー | デフォルトのアニメーション |
|---|---|
"IDLE" | stand |
"MOVE" | walk |
"ATTACK" | attack |
"HIT" | hit |
"CROUCH" | crouch |
"FALL" | fall |
"JUMP" | fall |
"CLIMB" | rope |
"LADDER" | ladder |
"DEAD" | dead |
"SIT" | sit |
アクションが終了すると、ステートマシンは自動的に IDLE に戻るため、手動で復帰タイマーを設定する必要はありません。
大文字・小文字の落とし穴:
ChangeStateに渡す文字列キーは大文字("ATTACK")です。selector.ActionStateに直接設定する列挙値(NPC の場合。下記参照)はMapleAvatarBodyActionState.Attackで、パスカルケースです。別の API ですが、基になる状態は同じです。文字列側の大文字・小文字が誤っていると("attack"/"Attack")、警告なしに ActionSheet のマッピングが見つかりません。
selector を直接書き換えられるのはどんなときですか?
実行中の PlayerControllerComponent + StateComponent + AvatarStateAnimationComponent のスタックを持たないエンティティに限られます。たとえば、アバターレンダラーを表示に使うものの、ステートマシンを駆動する入力コントローラーを持たない NPC やモンスターです。このようなエンティティでは、selector.ActionState = MapleAvatarBodyActionState.<Pose> の設定が維持されます。DefaultPlayer のようなエンティティでは、代わりに StateComponent:ChangeState(...) を使用してください。
主なサービスの概要(スクリプト参照用)
| サービス | 役割 | 主な API |
|---|---|---|
| _UserService | ユーザー管理、入退場 | LocalPlayer、UserEntities、GetUserEntityByUserId()、UserEnterEvent/UserLeaveEvent |
| _TeleportService | テレポート/マップ移動 | TeleportToEntity()、TeleportToMapPosition()、WarpUserToWorldAsync() |
| _CameraService | カメラ制御 | SwitchCameraTo()、ZoomTo()、ZoomReset() |
| DefaultUserEnterLeaveLogic | ユーザーの入退場ロジック | PlayerUri(プレイヤーモデル ID)、StartPoint(開始マップ) |
DefaultPlayer の変更方法
プロパティ値(Values)の変更
ModelBuilder.read() で ./Global/DefaultPlayer.model を読み込み、value() で値を更新します。
例:移動速度を 2.0 に設定
const { ModelBuilder } = require("../msw-general/scripts/model/msw_model_builder.cjs");
const b = ModelBuilder.read("./Global/DefaultPlayer.model");
b.value(null, "speed", 2.0, "float")
.value("MovementComponent", "InputSpeed", 2.0, "float")
.write("./Global/DefaultPlayer.model");
注:モデルプロパティ(
TargetType: null、Name: "speed")と、コンポーネントへの直接のオーバーライド(TargetType: "MOD.Core.MovementComponent"、Name: "InputSpeed")の両方が存在する場合があります。value()を使って、両方を一貫した値に設定してください。
例:ジャンプ力を 1.5、HP を 2000 に設定
const b = ModelBuilder.read("./Global/DefaultPlayer.model");
b.value(null, "jumpForce", 1.5, "float")
.value("MovementComponent", "JumpForce", 1.5, "float")
.value(null, "maxHp", 2000, "int")
.write("./Global/DefaultPlayer.model");
新しい Values エントリの追加
ModelBuilder.value(targetType, name, value, typeKey) を使用します。ビルダーが ValueType の記述子を生成するため、型の文字列を手動で記述しないでください。
一般的な typeKey の値:bool、int、float、double、string、vector2、vector3、data_ref、collision_group
コンポーネントの追加
./Global/DefaultPlayer.model で component() を使用します。
Player.model から継承されていないコンポーネントのみ追加してください。継承されたネイティブコンポーネント(PlayerComponent、MovementComponent、CameraComponent、StateComponent など)は再宣言せず、value(...) で値をオーバーライドしてください。BaseModelId: "player" からすでに継承されているコンポーネントをローカルで追加すると、ModelBuilder は警告(M040)を出します。
カスタムスクリプトコンポーネントの追加:
const b = ModelBuilder.read("./Global/DefaultPlayer.model");
b.component("script.MyCustomComponent")
.write("./Global/DefaultPlayer.model");
カスタムスクリプト(.mlua)は
./RootDesk/MyDesk/の下に作成してください。先にスクリプトを記述して Maker をrefreshしてから、ビルダーで"script.<ScriptName>"を追加します。
継承されていないネイティブコンポーネントの追加:
const b = ModelBuilder.read("./Global/DefaultPlayer.model");
b.component("SpriteRendererComponent")
.write("./Global/DefaultPlayer.model");
コンポーネントの削除
DefaultPlayer.model で removeComponent() を使用します。関連する Values エントリはビルダーによって削除されます。
注意:Player.model(ベース)から継承されたコンポーネントは、DefaultPlayer.model の Components には含まれません。ベースのコンポーネントを削除するには、
ModelBuilderを使ってPlayer.modelにパッチを適用する必要がありますが、一般的には推奨されません。
落とし穴(よくある落とし穴)
DefaultPlayer.model のコンポーネントの追加および値の変更でよくある落とし穴です。
コンポーネントリストの落とし穴
| # | 落とし穴 | 症状 | 対処方法 |
|---|---|---|---|
| C1 | 追加した script.XXX が消える、または適用されない | 同じディレクトリ内の対応する .codeblock メタデータに登録されていないスクリプトコンポーネントは、読み込み時に警告なく破棄されます。その状態で保存すると、完全に失われます | .mlua を作成したら、Maker Refresh を使って .codeblock を自動生成します。または、スポーン直後に entity:AddComponent("Name") で実行時にアタッチします |
| C2 | Player.model にすでにあるネイティブコンポーネント(例:MOD.Core.MovementComponent)を重複して追加する | 重複コンポーネントの警告が出るだけで、処理はブロックされません。そのため、ワークスペースに警告が蓄積し、動作が非決定的になります | 追加する前に、ベースコンポーネントリスト(§65-89)を確認します。すでにある場合は、Values で設定を変更します |
| C3 | script.PlayerHit / script.PlayerAttack を削除する | これらは DefaultPlayer に付属する唯一の追加スクリプトです。削除すると、被弾無効化/攻撃ロジックが失われます | 無効化が目的なら、スクリプト内のロジックを切り替えるか、Values で Enable=false にします |
| C4 | AvatarRendererComponent を無効にして SpriteRendererComponent(または別のレンダラー)に置き換える | Avatar と Sprite のレンダラーが同時に有効だと、Z ファイティングが発生したり、コスチュームが適用されなくなったりします | Avatar を無効にしてから Sprite を追加します(§395 のパターンを参照) |
| C5 | カスタムのダメージ処理で HP プロパティだけを減らす(またはダメージスキンイベントだけをブロードキャストする)ため、エンジンの被弾/死亡パイプラインが実行されない | アバターのステートマシンが反応するのはプロパティの書き込みではなく StateChangeEvent です。ダメージ数値/パーティクルは正常に表示されても、被弾/死亡/復活の間、アバターはアイドル状態のままです。エラーログのない、気づきにくい表示上の問題です | まずは、HitComponent:OnHit(attacker, damage, isCrit, attackInfo, hitCount) 経由でダメージを処理します。すると script.PlayerHit が被弾/死亡/リスポーンへの遷移を自動的に処理します。手動でダメージを処理する必要がある場合(継続ダメージ/オーラ/スクリプトによる処理)は、被弾ポーズには StateComponent:ChangeState("HIT") を使い、死亡と復活のサイクルには PlayerComponent:ProcessDead() / ProcessRevive() を併用します。HP だけを編集しないでください。アバターは反応しません。 |
| C6 | AvatarRendererComponent が有効なエンティティ(例:DefaultPlayer)で SpriteRendererComponent.Color / FlipX を設定する | コンポーネントは存在し、GetComponent も非 nil を返しますが、スプライト出力はアバターレンダラー独自のパイプラインの背後に隠れるため、色/反転の書き込みは何も起こりません。同じ方法がスプライトレンダラーのみのエンティティでは機能するため、最初の試行でのコピー&ペーストは警告なしに失敗します | 色合いには AvatarRendererComponent:SetColor(r, g, b, a)(0~1 の浮動小数点数)、フェードには :SetAlpha(a) を使います。どちらも ClientOnly です。向きを変えるには、sprite.FlipX ではなく MovementComponent.MoveDirection(またはゲームロジックの向き指定 API)でキャラクターを操作します |
値の変更時の注意点 — jumpForce / speed のみ追加の注意が必要です
Values のエントリーの大半は TargetType=null(エイリアス)形式で、ModelBuilder.value(null, ...) を通じて設定できます。例外は以下の 2 つのフィールドのみです。エイリアスとネイティブのエントリー(TargetType="MOD.Core.MovementComponent")が同時に存在します。
| フィールド | エイリアスのエントリー | ネイティブのエントリー |
|---|---|---|
| ジャンプ力 | jumpForce (TargetType=null) | JumpForce (TargetType="MOD.Core.MovementComponent") |
| 移動速度 | speed (TargetType=null) | InputSpeed (TargetType="MOD.Core.MovementComponent") |
エンティティのスポーン時に Values は配列順に適用され、どちらも同じネイティブフィールドに書き込みます。ネイティブのエントリーは配列の後方にあるため、ネイティブの値が優先されます。
- 誤り:エイリアス側(
jumpForce/speed)のみを編集する → 後方にあるネイティブのエントリーによって上書きされ、反映されません - 正しい方法:両方を同じ値に編集するか、ネイティブ側(
JumpForce/InputSpeed)のみを編集します
その他のエイリアスのみのエントリー(walkAcceleration、gravity、cameraDeadZone 以外のカメラ関連項目、nameTag、damageSkinId、damageDelayPerAttack、triggerBody*、maxHp など)は、エイリアスからそのまま変更できます。
DefaultPlayer を非表示にする
DefaultPlayer のコンポーネントはベースモデルから継承されるため、削除できません。Enable=false で無効化するのが唯一の方法です。
コンポーネントの維持/無効化の分類
| コンポーネント | 完全に非表示 | アバターのみ非表示 | 備考 |
|---|---|---|---|
| TransformComponent | 維持 | 維持 | 必須 |
| PlayerComponent | 維持 | 維持 | 必須 — 無効化すると進入時に失敗します |
| StateComponent | 維持 | 維持 | 無効化すると他のコンポーネントでエラーが発生します |
| MovementComponent | 維持 | 維持 | 移動が必要な場合は維持します |
| CameraComponent | 維持 | 維持 | カメラが必要な場合は維持します |
| AvatarRendererComponent | 無効化 | 無効化 | 重要 — これだけを無効化すれば非表示になります |
| AvatarStateAnimationComponent | 無効化 | 無効化 | |
| CostumeManagerComponent | 無効化 | 無効化 | |
| PlayerControllerComponent | 無効化 | 維持 | 移動を制限するかどうかによります |
| ChatBalloonComponent | 無効化 | 無効化 | |
| NameTagComponent | 無効化 | 無効化 | |
| DamageSkinSettingComponent | 無効化 | 無効化 | |
| DamageSkinSpawnerComponent | 無効化 | 無効化 | |
| HitComponent | 無効化 | 無効化 | |
| HitEffectSpawnerComponent | 無効化 | 無効化 | |
| TriggerComponent | 無効化 | 無効化 | |
| InventoryComponent | 無効化 | 無効化 | |
| RigidbodyComponent | 無効化 | マップモードに応じて維持 | MapleTile マップの場合 |
| SideviewbodyComponent | 無効化 | マップモードに応じて維持 | SideViewRectTile マップの場合 |
| KinematicbodyComponent | EnableShadow=false | EnableShadow=false | 影のみを削除します |
Builder での編集 — Values に Enable=false を追加する
ModelBuilder.value() でコンポーネントの値を設定します。Enable のエントリーがまだないコンポーネントには、Builder が追加します。
const { ModelBuilder } = require("../msw-general/scripts/model/msw_model_builder.cjs");
const b = ModelBuilder.read("./Global/DefaultPlayer.model");
b.enable("AvatarRendererComponent", false)
.value("KinematicbodyComponent", "EnableShadow", false, "bool")
.write("./Global/DefaultPlayer.model");
保存後、Maker Refresh が必要です。
DefaultPlayer のコンポーネント拡張パターン
- アバターのないプレイヤー:AvatarRendererComponent を無効化 → SpriteRendererComponent を追加 → SpriteRUID を設定します。
- コリジョンの設定:TriggerComponent の Values で ColliderType と CollisionGroup を調整します。
- SpawnLocation:マップ(.map)ファイルに Special → SpawnLocation を配置します(復活位置)。
ワークフロー
プレイヤーの基本プロパティ(移動速度、ジャンプ力、HP など)を変更する
1. Load ./Global/DefaultPlayer.model with ModelBuilder.read()
2. Update values with value(targetType, name, value, typeKey)
3. If both the model property (TargetType: null) and the direct component override exist, set both consistently
4. write("./Global/DefaultPlayer.model")
プレイヤーにカスタムスクリプトを追加する
1. Write a new .mlua script under ./RootDesk/MyDesk/ (see the msw-scripting skill)
2. Maker refresh so the script type is registered
3. Load ./Global/DefaultPlayer.model with ModelBuilder.read()
4. Add "script.<ScriptName>" with component()
5. If needed, add default property values for the script with value()
6. write("./Global/DefaultPlayer.model")
7. Request Maker Refresh
カメラ設定を変更する
1. Load ./Global/DefaultPlayer.model with ModelBuilder.read()
2. Set cameraDeadZone, cameraSoftZone, cameraDamping, cameraScreen, cameraDutch, cameraOffset with value()
3. write("./Global/DefaultPlayer.model")
制限事項と注意点
対象範囲
- ModelBuilder を通じて、DefaultPlayer/Player のモデルファイルを調査・パッチ適用します
component()/removeComponent()を通じてコンポーネントを追加・削除しますvalue()を通じて、移動/物理演算/HP/カメラの設定を行います
対象外
- コスチューム/アバター装備 →
msw-avatarスキル - UI エディター →
./ui/以下の .ui ファイル(専用スキル) - マップ編集 →
./map/以下の .map ファイル(NPC/モンスターのスポーンを含む専用スキル) - 一般的なスクリプト/リソース → それぞれの専用スキル
制約事項
- Global/ の扱いに注意:DefaultPlayer.model と Player.model は
./Global/にあります。このフォルダーはエンジンのデフォルトテンプレート用に予約されているため、ここに新しいファイルを作成することは推奨されません。 - カスタムスクリプトの配置場所:新しいスクリプトファイルは
./RootDesk/MyDesk/以下に作成してください。 - マップモードに関する注意:有効な移動コンポーネントは、マップモード(MapleTile/RectTile/SideViewRectTile)によって異なります。
- ValueType の正確性:Values エントリーを追加するときは、明示的な
typeKeyを指定してModelBuilder.value()を使用してください。ValueTypeを手書きしないでください。 - Maker Refresh:スクリプトを追加・変更した後は、Maker Refresh が必要です(.codeblock は自動生成されます)。