敵モンスターNPCを作ろう!その1
前回までで基本的な戦闘システムを作ったので、これからはいろいろな種類のモンスターを作りながらプログラミングを学習していくよ。
敵モンスターNPCのモデリング
プログラミングの学習だけならダミーのNPCで十分なんだけど、プログラミング学習で1番大事なことは学習のモチベーションをキープすること。やっぱり自分でモンスターがデザインできた方が楽しいしモチベーションもアップするよ。(=゚ω゚)ノ
RobloxStudioでもモデリングはできるけど、モデリング専用の「Blender」っていうツールがあるからプログラミング学習ついでにモデリング学習もしてみよう♪
「Blender」の学習に興味なければ、「PLUGINS」>「BuildRig」からダミーが作れるから読み飛ばしてね。
モデリング
Blenderを起動して、「File」>「New」>「General」
「Collection」の「Camera」「Light」を削除。
オブジェクトを選択して、「Add Modifier」からレベル3の「Subdivision」を追加。
オブジェクトの右クリックから「Shade Smooth」。
オブジェクトを選択してZ軸方向にサイズ縮小([S]キー → [Z]キー)。左クリックで確定。
[Tab]キーで編集モードに切り替え。さらに[3]キーで面選択モードに切り替えて上面を選択。
[E]キーで面の押し出し。左クリックで確定。
[S]キーで面のサイズ縮小。左クリックで確定。
押し出しとサイズ縮小を繰り返して好みの形状に。
UV展開
テンキー[1]で視点を正面。キーボードの[2]キーで辺選択モードに切り替えて、オブジェクトの正面部分を囲うように[Shift]キーを押しながら辺を複数選択。
[Ctrl]+[E]キーから辺にMarkSeam(縫い目)。
[A]キーでオブジェクトを全選択。[U]キーから[Unwrap]。
テクスチャーペイント
「Texture Paint」メニューに移り、「Texture Slots」の「+」から「Base Color」をAlphaのチェックを外してOK。
UV展開側に作ったBaseColorを適用。
UV展開側を好みの色でブラッシング。
顔はペイントはお好みで。symmetryをX軸方向に設定して目だけペイント。
今回はこんな感じにしたよ。
テクスチャイメージをファイル保存してからPack。
Blenderからobjファイルのエクスポート
Fileメニューで「Save」してからobj形式でエクスポート。
Blenderはここまで。
RobloxStudioにobjファイルのインポート
次はRobloxStudio に移って、Workspaceに「MeshPart」を追加。
Propertiesの「MeshId」のフォルダアイコンをクリックして、さっきBlenderからエクスポートしたobjファイルを選択。
メッシュとテクスチャが読み込まれたら成功だよ!
NPCの設定
NPCのModelには最低限「HumanoidRootPart」っていう中心となる部品が必要なのと、頭上にNPCの名前ラベルを表示させたいから「Head」っていう部品も欲しいんだ。
今回は追加したMeshPartを「頭」にしちゃうよ。
MeshPartのPropertiesからNameを「Head」に変更。
次に「HumanoidRootPart」。Workspaceに「Part」を追加。
「Part」のPropertiesから「Name」を「HumanoidRootPart」に変更。
「Head」より小さめにスケーリング。
「Head」に「HumanoidRootPart」を埋め込みたいんだけど、Propertiesの「CanColide」のチェックを外すとぶつからずに重ねることができるよ。
Moveを使って「HumanoidRootPart」がうまく「Head」に隠れたら、この2つをグループ化。
グループ化したら1つの「Model」ができたね。この「Model」のPropertiesの「Name」をキャラクターの名前に変えよう。ここでは「ぷよいむ」にするよ。
次にRobloxでは最低1つ以上のJoint(関節)がないとアニメーションをつけられないようだから「HumanoidRootPart」と「Head」をJointでつなぐよ。「HumanoidRootPart」の「+」から「Motor6D」を追加。
追加した「Motor6D」のPropertiesの「Part0」の右枠の空欄をクリックするとカーソルが選択アイコンに変わるからExplorerから「HumanoidRootPart」を選択しよう。「Part1」も同じように右枠の空欄をクリックしてから今度は「Head」を選択しよう。これで2つのパーツがJointでつながるんだ。
次にNPCにはもう1つ大事なものがあって「Humanoid」っていう属性をつけてあげる必要があるよ。「Humanoid」には歩く速度、ジャンプ力、体力とか、キャラクターに必要ないろんな設定があるんだ。
モデルの「+」から「Humanoid」を追加。
これで敵モンスターのモデルは完成!
あとはプログラミングで動かしてみよう♪
プレイヤーを追いかけるプログラミング
敵モンスターのモデルの「+」から「Script」を追加。
local npc = script.Parent local hrpOfNPC = npc:WaitForChild("HumanoidRootPart") while wait(1) do local plrs = game.Players:GetPlayers() local closestHRP for i, plr in pairs(plrs) do if plr.Character and plr.Character:FindFirstChild("HumanoidRootPart") then local hrp = plr.Character.HumanoidRootPart local betweenDistance = (hrpOfNPC.Position - hrp.Position).Magnitude if closestHRP == nil then closestHRP = hrp elseif betweenDistance < (hrpOfNPC.Position - closestHRP.Position).Magnitude then closestHRP = hrp end end end if closestHRP then npc.Humanoid:MoveTo(closestHRP.Position) end end
ひとつずつ見ていこう。
local npc = script.Parent
この「script.Parent」は、このスクリプトの親なので、敵モンスターのモデルを「npc」っていう変数でアクセスできるようにしてるよ。
local hrpOfNPC = npc:WaitForChild("HumanoidRootPart")
ここは、NPCの「HumanoidRootPart」を「hrpOfNPC」っていう変数でアクセスできるようにしているよ。
while wait(1) do
ここは最後の「end」までの処理を1秒ごとに繰り返す書き方だよ。
次にWhile文の繰り返し処理を見ていこう。
local plrs = game.Players:GetPlayers()
ここは、ゲームにログインしているプレイヤーたちを取得して「plrs」っていう変数でアクセスできるようにしているよ。
local closestHRP
ここは、あとで何回もアクセスしたいから変数だけ用意しているんだね。
for i, plr in pairs(plrs) do
ここは、For文も繰り返し処理の書き方だね。ゲームにログインしているプレイヤーたちをひとりずつ取り出して「plr」っていう変数に入れて、人数分繰り返しているよ。
次にFor文の繰り返し処理を見ていこう。
if plr.Character and plr.Character:FindFirstChild("HumanoidRootPart") then
ここは、取り出したプレイヤーが「キャラクター」かつ「HumanoidRootPart」を持っているか確認しているよ。確認しないで「HumanoidRootPart」にアクセスすると、なかった場合エラーになっちゃうんだ。
local hrp = plr.Character.HumanoidRootPart
ここは、「HumanoidRootPart」があることがわかったら、「hrp」っていう変数でアクセスできるようにしているよ。
local betweenDistance = (hrpOfNPC.Position - hrp.Position).Magnitude
ここは、敵モンスターの「HumanoidRootPart」の座標とゲームにログインしているプレイヤーのうちのひとりの「HumanoidRootPart」の座標の差の大きさを「betweenDistance」っていう変数でアクセスできるようにしているよ。
if closestHRP == nil then
ここは、あらかじめ用意していた「closestHRP」変数が空のとき、初回のループのときだけ空のはずだから初回は必ず「closestHRP = hrp」を実行するよ。あらかじめ用意しておいた「closestHRP」変数にゲームにログインしているプレイヤーのうちのひとりの「HumanoidRootPart」を格納しているよ。
elseif betweenDistance < (hrpOfNPC.Position - closestHRP.Position).Magnitude then
ここは、2回目以降のループ処理になるね。今回の敵NPCとプレイヤーの座標の差が前回の差より小さいときだけ「closestHRP」変数を上書き更新しているね。これで敵NPCは一番近くにいるプレイヤーの座標が取得できるようになるんだ。
ゲームにログインしているプレイヤー数分のFor文が終わったら、
npc.Humanoid:MoveTo(closestHRP.Position)
これで、このNPCを一番近く人いるプレイヤーの座標へ移動させているよ。
それじゃあ。実際にテストしてみよう。
プレイヤーを追いかけてくれば成功だよ!
NPCのHumanoidのPropertiesに「WalkSpeed」っていう設定があるから、その数値をいじって追跡スピードを調整してみてね^^
次回はこの敵NPCがプレイヤーを攻撃するプログラミングをしてみるよ!
それじゃ~またね~。(@^^)/~~~
コメント