Open3

一定の速度でプロップを動かす

aiiroIndyaiiroIndy

概要

  • 繰り返し四角を描くように、プロップを移動させ続ける。
  • 左クリック、右クリックで速度を調整。
  • スイッチのオンでスタート、オフでストップ(キャンセル)。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()



仕掛けの設定

aiiroIndyaiiroIndy

概要

  • 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()")