Open3
一定の速度でプロップを動かす
概要
- 繰り返し四角を描くように、プロップを移動させ続ける。
- 左クリック、右クリックで速度を調整。
- スイッチのオンでスタート、オフでストップ(キャンセル)。agent情報は不要。
※スイッチのStore State Per Playerはオフで設定しておく
プログラム
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
speed_control_endless := class(creative_device):
# スイッチオンでスタート、オフでキャンセル
@editable
In_Switch:switch_device = switch_device{}
@editable
LMBInput:input_trigger_device = input_trigger_device{}
@editable
RMBInput:input_trigger_device = input_trigger_device{}
@editable
Prop:creative_prop = creative_prop{}
# スイッチがオフになった時にシグナル。spawnした処理をキャンセルするために使用
DisableEvent:event() = event(){}
# 1回の移動距離(タイル数)
var TileCount:int = 0
TileSize:float = 512.0
# 速さ(1タイル毎秒)
var TilesPerSecond:float = 1.0
# 移動時間
var TimeToMove:float = 0.0
var PropInitialTf:transform = transform{}
OnBegin<override>()<suspends>:void=
# agent情報がない場合、TurnedOnEvent, TurnedOffEventでは検知できないため、
# StateChangesEventをSubscribe
In_Switch.StateChangesEvent.Subscribe(OnStateChange)
set PropInitialTf = Prop.GetTransform()
# 左クリックで速度アップ。右クリックで速度ダウン
SpeedControl()<suspends>:void=
race:
loop:
race:
block:
LMBInput.PressedEvent.Await()
set TilesPerSecond += 0.5
block:
RMBInput.PressedEvent.Await()
set TilesPerSecond -= 0.5
if(TilesPerSecond <= 0.0):
set TilesPerSecond = 0.1
# ログ出力用
CentiMetersPerSecond := TileSize * TilesPerSecond
Print("SpeedControl() 速さ(tiles/s)={TilesPerSecond}, 速さ(cm/s)={CentiMetersPerSecond}, 時間={TimeToMove}")
DisableEvent.Await()
Print("SpeedControl() End")
Start()<suspends>:void=
set TileCount = 1
var DirectionPattern:int = 1
race:
loop:
# (例) 道のり:512.0 * 1 = 512.0
DistanceToMove := TileSize*TileCount
# 1~4の順番で移動を繰り返す
# 1:Y軸正の方向, 2:X軸正の方向, 3:Y軸負の方向, 4:X軸負の方向
var Offset:vector3 = vector3{}
if(DirectionPattern = 1):
set Offset = vector3{Y:=DistanceToMove}
else if(DirectionPattern = 2):
set Offset = vector3{X:=DistanceToMove}
else if(DirectionPattern = 3):
set Offset = vector3{Y:=-DistanceToMove}
else if(DirectionPattern = 4):
set Offset = vector3{X:=-DistanceToMove}
# Propを1マス分ずつ移動 (5マス分繰り返す)
for(I := 0..4):
# (例) 速さ:
# 1タイル毎秒 1 tiles per second
# = 512センチメートル毎秒 512 centimeters per second
CentiMetersPerSecond := TileSize * TilesPerSecond
# (例) 時間: 道のり / 速さ = 1秒
set TimeToMove = DistanceToMove/CentiMetersPerSecond
PropTf := Prop.GetTransform()
# Propの現在地にOffsetを加えた目的地に移動
Prop.MoveTo(PropTf.Translation + Offset, IdentityRotation(), TimeToMove)
# if(I=0):
# Print("Start() 道のり={DistanceToMove}, 速さ(t/s)={TilesPerSecond}, 速さ(cm/s)={CentiMetersPerSecond}, 時間={TimeToMove}, DirectionPattern={DirectionPattern}")
# 移動方向を変更
if(NextDirectionPattern := Mod[DirectionPattern, 4] + 1):
set DirectionPattern = NextDirectionPattern
Print("Start() Next DirectionPattern={DirectionPattern}")
Sleep(0.0)
DisableEvent.Await()
Print("Start() End")
OnStateChange():void=
Print("OnStateChange() IsStatePerAgent[]={if(In_Switch.IsStatePerAgent[]) then "Success" else "Fail"}")
# In_Switchがプレイヤーごとの統計ではない設定の場合
if(not In_Switch.IsStatePerAgent[]):
if(In_Switch.GetCurrentState[]):
HandleTurnOn()
else:
HandleTurnOff()
HandleTurnOn():void=
Print("HandleTurnOn()")
LMBInput.Enable()
RMBInput.Enable()
if(Prop.TeleportTo[PropInitialTf]){}
spawn:
Start()
spawn:
SpeedControl()
HandleTurnOff():void=
Print("HandleTurnOff()")
LMBInput.Disable()
RMBInput.Disable()
DisableEvent.Signal()
仕掛けの設定
概要
- Lerp関数で、プロップを断続的に上昇・下降させる。パラメーターに応じて移動速度を調整。
- Lerp関数で、ボタンインタラクトの都度、プロップを段階的に上昇させる。
プログラム
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
lerp_sample := class(creative_device):
@editable
In_ResetTrigger:trigger_device = trigger_device{}
@editable
PropKits:[]prop_kit = array{}
OnBegin<override>()<suspends>:void=
In_ResetTrigger.TriggeredEvent.Subscribe(OnResetTriggered)
OnResetTriggered(AgentOpt:?agent):void=
for(PropKit : PropKits):
PropKit.Reset()
prop_kit := class<concrete>:
@editable
In_Trigger:?trigger_device = false
@editable
Button:?button_device = false
@editable
Prop:creative_prop = creative_prop{}
var PropInitialTf:transform = transform{}
var IsJumping:logic = false
var IsPushing:logic = false
var ButtonCount:int = 0
block:
if(ValidTrigger := In_Trigger?):
ValidTrigger.TriggeredEvent.Subscribe(OnTriggered)
if(ValidButton := Button?):
ValidButton.InteractedWithEvent.Subscribe(OnInteraction)
set PropInitialTf = Prop.GetTransform()
OnTriggered(AgentOpt:?agent):void=
if(not IsJumping?):
set IsJumping = true
spawn{ Jumping() }
OnInteraction(Agent:agent):void=
if(not IsPushing?):
set IsPushing = true
spawn{ Pushing() }
Pushing()<suspends>:void=
EndPos := PropInitialTf.Translation + vector3{Z:=512.0*2}
if(ButtonCount <= 9):
set ButtonCount += 1
NewPos := Lerp(PropInitialTf.Translation, EndPos, ButtonCount*0.1)
Prop.MoveTo(NewPos, PropInitialTf.Rotation, 0.5)
Print("Pushing() ButtonCount={ButtonCount}, NewPos={NewPos}")
set IsPushing = false
Jumping()<suspends>:void=
Print("Jumping() ")
StartPos := PropInitialTf.Translation
EndPos := PropInitialTf.Translation + vector3{Z:=512.0*2}
# 上昇
for(I := 1..10):
NewPos := Lerp(StartPos, EndPos, I*0.1)
if(I<3):
Prop.MoveTo(NewPos, PropInitialTf.Rotation, 0.05)
else if(I<6):
Prop.MoveTo(NewPos, PropInitialTf.Rotation, 0.1)
else if(I<9):
Prop.MoveTo(NewPos, PropInitialTf.Rotation, 0.25)
else:
Prop.MoveTo(NewPos, PropInitialTf.Rotation, 0.5)
# 落下
for(Minus := 1..10, I:=10-Minus, I >= 0):
NewPos := Lerp(StartPos, EndPos, I*0.1)
if(I<3):
Prop.MoveTo(NewPos, PropInitialTf.Rotation, 0.05)
else if(I<6):
Prop.MoveTo(NewPos, PropInitialTf.Rotation, 0.1)
else if(I<9):
Prop.MoveTo(NewPos, PropInitialTf.Rotation, 0.25)
else:
Prop.MoveTo(NewPos, PropInitialTf.Rotation, 0.5)
set IsJumping = false
Reset():void=
if(Prop.TeleportTo[PropInitialTf]){}
set IsJumping = false
set IsPushing = false
set ButtonCount = 0
Print("Reset()")
Animating Prop Movement