Unityに関連する記事です

 UniRx を活用したマウス長押し機能の実装例です。



サンプルコード



using System;
using UniRx;
using UniRx.Triggers;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

public class Variable : MonoBehaviour
{
    [SerializeField, Tooltip("計算機に変数追加ボタン")] private Button btnVariable;

    [SerializeField, Tooltip("変数名表示テキスト")] private Text textVariableName;
    [SerializeField, Tooltip("変数の値表示テキスト")] private Text textVriableValue;

    public ReactiveProperty<string> variableName { get; set; } = new();
    public ReactiveProperty<int> VariableValue { get; set; } = new();


    void Start() {
    // デバッグ用
        GenerateSetup("Sample", 0);
    }

    public void GenerateSetup(string viewText, int index, UnityAction<int> buttonActionAddCalcView = null)
    {
        btnVariable.OnClickAsObservable()
            .ThrottleFirst(System.TimeSpan.FromSeconds(0.5f))
            .Subscribe(_ =>
            {
                buttonActionAddCalcView?.Invoke(index);
            })
            .AddTo(this);

    // UniRx を利用したマウスの長押し処理
    // OnPointerDownをtrueに変換
        btnVariable.OnPointerDownAsObservable().Select(_ => true)
       
         // OnPointerUpをfalseに変換
           // OnPointerDownとOnPointerUpを1つのストリームに合成
           // この後には押した時にtrueが、離した時にfalseが流れるようになる
         .Merge(btnVariable.OnPointerUpAsObservable().Select(_ => false))

           // 1秒間新しい値が来なかったら最後に来た値を流す
           .Throttle(TimeSpan.FromSeconds(0.5f))

           // trueだけを流す
           .Where(b => b)

           // このboolは利用しない値なので、通知発行のみを行っていることを明確にするため、Unitに変換する
         .AsUnitObservable()

         // 上記の処理により、最終的にマウスの長押しを購読する
         .Subscribe(_ =>
         {
             // TODO 長押し時の処理を実装

         })
         .AddTo(this);

        variableName
            .Subscribe(message =>
            {
                SetVariableName(message);
            })
            .AddTo(this);

        variableName.Value = viewText;

        VariableValue.Subscribe(x =>
            {
                SetVariableValue(x.ToString());
            })
            .AddTo(this);

        VariableValue.Value = 0;
    }

    public void SetVariableName(string value)
    {
        textVariableName.text = value;
    }

    public void SetVariableValue(string value)
    {
        textVriableValue.text = value;
    }
}


解説


 btnVariableのOnPointerDownとOnPointerUpを1つのストリームに合成して、
その後にTrueのときだけをフィルタリングし、最終的にUnitに変換してから購読しています。

    // UniRx を利用したマウスの長押し処理
    // OnPointerDownをtrueに変換
        btnVariable.OnPointerDownAsObservable().Select(_ => true)
       
         // OnPointerUpをfalseに変換
           // OnPointerDownとOnPointerUpを1つのストリームに合成
           // この後には押した時にtrueが、離した時にfalseが流れるようになる
         .Merge(btnVariable.OnPointerUpAsObservable().Select(_ => false))

           // 1秒間新しい値が来なかったら最後に来た値を流す
           .Throttle(TimeSpan.FromSeconds(0.5f))

           // trueだけを流す
           .Where(b => b)

           // このboolは利用しない値なので、通知発行のみを行っていることを明確にするため、Unitに変換する
         .AsUnitObservable()

         // 上記の処理により、最終的にマウスの長押しを購読する
         .Subscribe(_ =>
         {
             // TODO 長押し時の処理を実装

         })
         .AddTo(this);

 具体的な処理の流れは以下の通りです。

 OnPointerDownAsObservable()とOnPointerUpAsObservable()をMergeして1つのストリームに結合します。

 合成したストリームの各要素に対して、Select(_ => true)とSelect(_ => false)を使って、それぞれTrueとFalseに変換します。

 変換したストリームをThrottleで0.5秒ごとに制御します。これにより、長押し中でも0.5秒ごとに1回だけイベントが流れます。

 最後に、Trueのときだけをフィルタリングして、AsUnitObservable()でUnitに変換します。

 最終的に、長押し時には1秒ごとにUnitが流れるようになり、そのイベントをSubscribeして実装した処理を呼び出します。
この処理により、btnVariableが長押し(またはタップ)された状態を検知し、その際にイベント処理を呼び出すことができます。


<AsUnitObservable() オペレータ>


 AsUnitObservable() オペレータは、Observableの各要素に対して単なる true ではなく、 Unit を流すように変換するものです。
これは、Observableが特定の値の流れではなく、単なるイベントの発生を表す場合に使われます。

 例えば、 BtnVariable が長押し(またはタップ)されたことを知りたい場合、その情報だけを持つ true を流すのではなく、
Unit を流すことで、特に値に意味がなく、単にイベントが発生したことを表現することができます。

 実際には、この場合、 AsUnitObservable() を挟まなくても動作することがあります。
しかし、イベントの発生を表す場面では、 Unit が使用されることが一般的であり、コードの意図を明示的にするために使われることがあります。
これにより、コードを見る人が単なる true の代わりに Unit を使っていることを理解しやすくなります。

 また、特に値に意味がない場合や、その値を無視する場合にも Unit が使われることがあります。
したがって、このような文脈で .AsUnitObservable() を利用することで、コードの意図が明確になり、他の開発者や自分自身が後で理解しやすくなります。

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu



技術/知識(実装例)

2Dおはじきゲーム(発展編)

2D強制横スクロールアクション(発展編)

3Dダイビングアクション(発展編)

2Dタップシューティング(拡張編)

レースゲーム(抜粋)

2D放置ゲーム(発展編)

3Dレールガンシューティング(応用編)

3D脱出ゲーム(抜粋)

2Dリアルタイムストラテジー

2Dトップビューアドベンチャー(宴アセット使用)

3Dタップアクション(NavMeshAgent 使用)

2Dトップビューアクション(カエルの為に〜、ボコスカウォーズ風)

VideoPlayer イベント連動の実装例

VideoPlayer リスト内からムービー再生の実装例(発展)

AR 画像付きオブジェクト生成の実装例

AR リスト内から生成の実装例(発展)

private



このサイト内の作品はユニティちゃんライセンス条項の元に提供されています。

管理人/副管理人のみ編集できます