🎚️

【Roblox】ModelのScaleをTweenで補間する

に公開

1. はじめに

みなさんは、TweenServiceを利用されていますでしょうか?
様々なプロパティの値を補間して徐々に変動させることができ、ゲームに必要な色んな表現が可能なため、Robloxでの制作に欠かせない機能の一つです。
しかし、適用できるのがあくまでプロパティであるため、時々融通が利かず困ることがあります。
その一つが、ModelのScaleです。
「Model全体の大きさを補間する」なんて、ゲームでは使いたい場面が沢山あるのに、なんとModelのScaleにはTweenを使うことができません! なんてこった。
というわけで今回は、ModelのScaleをTweenで補間する方法をご紹介します。
(この記事は、TweenServiceを既にある程度使用している事を前提としているため、TweenServiceについての詳しい解説は行いません。ご了承ください)

バージョン:0.669.1.6690663

2. 問題の原因


Roblox Studioのプロパティウィンドウから見ると、ModelのScaleも普通にプロパティのように表示されており、一見普通にTweenが使えそうに見えます。
なのになぜTweenが使えないかというと、Scaleは実際にはプロパティとしては存在していないからです。
公式のリファレンスによると、ModelのScaleは、Scriptからアクセスしようとするとエラーとなり、変更及び取得はModel:ScaleToModel:GetScaleを使用するように書かれています。
Model:ScaleToは、プロパティウィンドウからScaleを変更した時のように、Modelの子孫全ての大きさを調整してくれるメソッドで、Model:GetScaleは現在適用しているScaleを取得するメソッドです。
Model.Scaleでアクセスしようとしても、「Scale is not a valid member of Model(ScaleはModelの有効なメンバではありません)」というエラーが表示され、Model.ChangedイベントでもScaleの変化は検出できません。

3. 対応策を考える

しかし、Model下の全てのBasePartのSize等にTweenを適用するのは大変です。
なんとかModel:ScaleToを使えないものか…
と、ここで逆に考えてみると、Tweenが適用可能な型のプロパティであれば、当然Tweenが使えるということです。
つまり、間に何かnumber型のプロパティを挟み、そのプロパティが変動した時にScaleToを実行すれば、間接的にScaleにTweenを適用できるのでは?
というわけで、NumberValueを利用します!

NumberValue

NumberValueとは、特定の型の値を保持するだけの機能をもつValue系オブジェクトの一種で、number型の値を保持するためのInstanceです。
NumberValue.Valueというnumber型のプロパティを持ち、NumberValue.Changedイベントで値の変動を検出できます。
必要最低限の機能が揃っていますね!
ちなみに、Value系オブジェクトのChangedイベントは、通常のオブジェクトのChangedイベントとは違い引数に変更後のValueの値が直接入っており、手動で取得する必要がありません。

4. NumberValueを介してTweenで補間する

それでは実際にやってみましょう。
今回は、RigのScaleにTweenを適用してみます。
リグビルダーでWorkspace上にRigを生成したら、その子にNumberValueを、さらにその子にScriptを追加してください。
名前はそれぞれ「ScaleValue」「ScaleToTweenScript」としておきます。

そして、ScaleToTweenScriptに以下のコードを追加してください。

ScaleToTweenScript
local scaleValue_ = script.Parent
local model_: Model?

-- 対象Modelを設定する関数.
local function setModel(parent: any)
	if not parent or not parent:IsA("Model") then
		model_ = nil
		return
	end

	-- 現在のScaleで初期化.
	scaleValue_.Value = parent:GetScale()

	-- Modelを設定.
	model_ = parent
end

-- ScaleValueの親が変わったら対象Modelを設定しなおす.
scaleValue_:GetPropertyChangedSignal("Parent"):Connect(function()
	setModel(scaleValue_.Parent)
end)

-- 対象Modelを設定.
setModel(scaleValue_.Parent)

-- Changedイベントに接続.
scaleValue_.Changed:Connect(function(value: number)
	if model_ then
		model_:ScaleTo(value)
	end
end)

やる事は単純なのでこれだけですが、ScaleValue.Valueの値が変われば自動的にScaleToが実行されるようになったはずです。
それでは、TweenでScaleValue.Valueの値を補間してみましょう。
本来は他のScriptから行うのを想定していますが、今回は挙動が確認できれば良いので、このままScaleToTweenScriptに追記します。
実際に利用する際は追記分は消しておいてくださいね。
では、先ほどのコードの下に以下のコードを追加してください。

ScaleToTweenScript
-- Tweenを作成.
local TweenService = game:GetService("TweenService")
local tween0 = TweenService:Create(scaleValue_, TweenInfo.new(1), {Value = 0.001})
local tween1 = TweenService:Create(scaleValue_, TweenInfo.new(1), {Value = 2})

-- Completedイベントを使って、二つのTweenを交互に実行するようにする.
tween0.Completed:Connect(function(playbackState: Enum.PlaybackState)
	tween1:Play()
end)
tween1.Completed:Connect(function(playbackState: Enum.PlaybackState)
	tween0:Play()
end)

-- 再生.
tween0:Play()

一秒ごとに小さくなったり大きくなったりするようにしてみました。

それではさっそく実行して確認してみましょう。

これでModelのScaleをTweenで補間できるようになりました!

ちなみに、今回作成したScriptを利用している時に、補間せずにScaleToを行いたい場合は、Model:ScaleToを直に実行するとScaleValue.Valueの値と実際のScaleが食い違ってしまうので、ScaleValue.Valueの値を変更することでScaleToTweenScriptを介してScaleToを実行しましょう。

5. まとめ

  • ModelのScaleはプロパティではないため、Tweenが適用できない
  • NumberValueは、number型の値を保持するためだけのオブジェクト
  • 値を保持しているNumberValue.Valueはnumber型のプロパティなので、Tweenが適用できる
  • NumberValue.ChangedイベントでScaleToを実行することで、間接的にModelのScaleにTweenを適用できる

今回は、ModelのScaleをTweenで補間する方法をご紹介しました。
次回もTweenが適用し辛いものを補間する方法をご紹介するので、そちらもぜひご覧ください!
最後までお読みいただき、ありがとうございました!

6. 参考

https://create.roblox.com/docs/reference/engine/classes/TweenService
https://create.roblox.com/docs/reference/engine/classes/NumberValue

ランド・ホー Roblox開発チーム

Discussion