【主な実行例】 Framework01、02; QFramework00(動画は古いバージョンを踏襲していますが、最新のものをお勧めします)、01(なし)、02(なし)、03(なし)

概要

00、10、13 を実行している場合は、10 を実行することを検討してください。
11、12はダウンロードされず、その時この2つは00、10と間違えられて
UniRxを使用してしまいました

フレームワークには 2
00 Unity ゲーム フレームワーク構築 2019 年第 1 四半期 C# のコア知識と簡単な Manager Of Manager フレームワーク構築 120 レッスン 01 Unity
ゲームフレームワーク構築 2019 年第 2 四半期モジュール/システム設計、命名、テスト (リソース管理/ホット アップデート) 133 レッスン

QFramework加上简介有4个
总共是6个
10 QFramework 使用指南 91课数(2个示例,备忘录和魔塔)【免费】【里面的示例是文章主题内容】
(这是sik学院视频下的资料,QF有点老了,也有一些报错。不建议用,建议到https://github.com/liangxiegame/QFramework下载最新的,里面例子,教程文档什么都有。)
11 框架搭建 决定版:架构演化(第一季) 31课数
12 框架搭建 决定版:应用篇(第二季) 51课数
13 框架搭建 决定版:理论强化篇(第三季) 53课数

名前

主に実際のサンダルの使い方に依存します

プライベート

mXxx
m_Xxx
直接小文字の xxx

パブリック
大文字 Xxx

----------------------------------------------------

00 第 1 四半期 C# のコア知識と簡単な Manager Of Manager フレームワーク構築

ここに画像の説明を挿入

MsgDispatcher を使用して MonoBehavior にメッセージを送信する

/****************************************************
    文件:Demo_202305032353.cs
	作者:lenovo
    邮箱: 
    日期:2023/5/3 23:53:10
	功能:
*****************************************************/

using System;
using UnityEngine;

public class Demo01_202305032353 : MonoBehaviour
{
    
    

    void Start()
    {
    
    
        MsgDispatcher.Register("KillEnemy",OnEnemyKilled);
        MsgDispatcher.Send("KillEnemy","赵云");
        //
        MsgDispatcher.UnRegister("KillEnemy", OnEnemyKilled);
        MsgDispatcher.Send("KillEnemy", "赵云");
        //
        this.Delay(5f, () => {
    
    Debug.Log("5秒真男人"); });
    }

    private void OnEnemyKilled(object obj)
    {
    
    
        Debug.LogFormat("{0}KillEnemy", obj );
    }
}

ここに画像の説明を挿入

メッセージ MonoBehaviourMsg (MonoBehaviour に組み込まれた MsgDispatcher)

/****************************************************
    文件:Demo_202305032353.cs
	作者:lenovo
    邮箱: 
    日期:2023/5/3 23:53:10
	功能:
*****************************************************/

using System;
using UnityEngine;

public class Demo02_202305032353 : MonoBehaviourMsg
{
    
    

    void Start()
    {
    
    

        this.Delay(5f, () => {
    
    Debug.Log("5秒真男人"); });
        //
        RegisterMsg("AmbushEnemy", OnEnemyAmbushed);
        SendMsg("AmbushEnemy", "孙膑");
        //
        RegisterMsg("DefendEnemy", data => Debug.LogFormat("{0}DefendEnemy", data));
        SendMsg("DefendEnemy", "郝昭");
    }

    private void OnEnemyKilled(object obj)
    {
    
    
        Debug.LogFormat("{0}KillEnemy", obj );
    }


    private void OnEnemyAmbushed(object obj)
    {
    
    
        Debug.LogFormat("{0}AmbushEnemy", obj);
    }

    protected override void OnBeforeDestroy()
    {
    
    

    }
}

ここに画像の説明を挿入

----------------------------------------------------

01 第 2 四半期モジュール/システム設計、命名、テスト (リソース管理/ホット アップデート)

バグ TestFramework エラー

これら 2 つの
フォルダー Tests を追加し、パッケージ TestFramework を追加しましたが、それでもエラーが報告されました。最初に単純に削除しました。
ここに画像の説明を挿入
ここに画像の説明を挿入

ResMgr.LoadSync

using UnityEngine;

namespace QFramework
{
    
    
	public class UIXXXPanel : MonoBehaviour
	{
    
    

#if UNITY_EDITOR
		[UnityEditor.MenuItem("QFramework/Example/9.UIXXXPanel", false, 9)]
		static void MenuItem()
		{
    
    
			UnityEditor.EditorApplication.isPlaying = true;

			new GameObject("UIXXXPanel").AddComponent<UIXXXPanel>();
		}
#endif


        [SerializeField] AudioClip coinClip;
        [SerializeField] AudioClip homeClip;
        [SerializeField] AudioClip bgClip;
        ResLoader mResLoader = new ResLoader();

		private void Start()
		{
    
    
			 coinClip = LoadAudioClip("coin");
			 homeClip  = LoadAudioClip("home");
			 bgClip = LoadAudioClip("coin");
			//
			OtherFunction();
		}


		private void OtherFunction()
		{
    
    
			 bgClip = LoadAudioClip("coin");
		}

		private void OnDestroy()
		{
    
    
			mResLoader.ReleaseAll();
		}

		AudioClip LoadAudioClip(string path)
		{
    
    
            return mResLoader.LoadSync<AudioClip>("resources://"+path);
        }
	}
 }

ResMgr.LoadAsync + コールバック

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace QFramework
{
    
    
	public class ResMgrExample : MonoBehaviour
	{
    
    

#if UNITY_EDITOR
		[UnityEditor.MenuItem("QFramework/Example/10.ResMgrExample", false, 10)]
		static void MenuItem()
		{
    
    
			UnityEditor.EditorApplication.isPlaying = true;

			new GameObject("ResMgrExample").AddComponent<ResMgrExample>();
		}
#endif

		ResLoader mResLoader = new ResLoader();

		[SerializeField] AudioClip audioClip1;
        [SerializeField] AudioClip audioClip2;
        [SerializeField] GameObject go;


		private IEnumerator Start()
		{
    
    
			yield return new WaitForSeconds(2.0f);

			mResLoader.LoadAsync<AudioClip>(
				assetName: "resources://coin", 
				onLoaded: coinClip =>
				{
    
    
					Debug.Log(coinClip.name);
					Debug.Log(Time.time);
				}
			);//这块是回调,所以不一定比后面快
			Debug.Log(Time.time);
			yield return new WaitForSeconds(2.0f);

			audioClip1=	mResLoader.LoadSync<AudioClip>("resources://home");
			yield return new WaitForSeconds(2.0f);

			go=mResLoader.LoadSync<GameObject>("resources://HomePanel");
			audioClip2=	mResLoader.LoadSync<AudioClip>("resources://Audio/coin");
			yield return new WaitForSeconds(5.0f);

			mResLoader.ReleaseAll();
		}
	}
}

スターディレクトリ.CreateDirectory

    /// <summary>文件夹有就好,没有就创建</summary>
    public static void Folder_New(string path)
    {
    
    
        if (Directory.Exists(path) == false) //输出path
        {
    
    
            Directory.CreateDirectory(path);
        }

    }

スター BuildPipeline.BuildAssetBundles

/****************************************************
    文件:AB.cs
	作者:lenovo
    邮箱: 
    日期:2023/5/6 9:41:45
	功能:
*****************************************************/

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using Random = UnityEngine.Random;
 

public static class AB 
{
    
    
    public static void Build(
        string outputPath,
        BuildAssetBundleOptions option = BuildAssetBundleOptions.ChunkBasedCompression
    )
    {
    
    
        BuildPipeline.BuildAssetBundles
        (
            outputPath,
            option ,
            EditorUserBuildSettings.activeBuildTarget
        );
        AssetDatabase.Refresh();
    }

}





パッケージ化時にバグ「MenuItemAttribute」が見つかりませんでした

タイプまたは名前空間名 'MenuItemAttribute' が見つかりませんでした。
報告されたエラーは AB パッケージであり、エラーはパッケージのスクリプトにジャンプするように報告されました。

バグテスト用の dll リファレンス

この Alt+Enter で VS エラーは解決できますが、Unity エラーはまだ残っています。
ここに画像の説明を挿入

using NUnit.Framework;
using UnityEngine;

namespace QFramework
{
    
    
	public class NewBehaviourScript : MonoBehaviour
	{
    
    
#if UNITY_EDITOR
		[UnityEditor.MenuItem("QFramework/Playground")]
		private static void Test()
		{
    
    
		}


		[Test]
		public void Playmode()
		{
    
    
			Debug.Log(HotUpdateMgr.Instance.GetLocalResVersion());
		}
#endif
	}
}

Unity に参照がありません

ここに画像の説明を挿入

オリジナルにはこの2つがあります

ここに画像の説明を挿入

バグ「EditorUserBuildSettings」が存在しません

タイプまたは名前空間名「EditorUserBuildSettings」が名前空間「UnityEditor」
アセンブリに存在しないため、エディターがチェックされます。
ここでは、Common という新しいアセンブリを作成し、いくつかのスクリプトをコピーしようとしましたが、その時点では Common アセンブリはエディターをチェックしていませんでした。

TestFrameworkを見る

TestFramework をインストールし、すべてのケースをインポートします (現時点では 1.3.4 のみにケースがあります)
ケース 2 でテストを開始できます
ここに画像の説明を挿入

ケース 02 演習 1_ 解決策

ここに画像の説明を挿入
ここに画像の説明を挿入

主脚本


namespace MyExercise_1s
{
    
    
    public static class MyMath
    {
    
    
        public static int Add(int a, int b)
        {
    
    
            return a + b;
        }
    
        public static int Subtract(int a, int b)
        {
    
    
            return a - b; // Fixed
        }
    }
}

メインスクリプトのテスト

using MyExercise_1s;
using NUnit.Framework;

namespace Tests_1s
{
    
    
    public class MyMathTests
    {
    
    
        [Test]
        public void AddsTwoPositiveIntegers()
        {
    
    
            Assert.AreEqual(3, MyMath.Add(1, 2));
        }
        
        [Test]
        public void AddAPositiveAndNegativeInteger()
        {
    
    
            Assert.AreEqual(1, MyMath.Add(3, -2));
        }
        
        [Test]
        public void SubtractAPositiveInteger()
        {
    
    
            Assert.AreEqual(3, MyMath.Subtract(5, 2));
        }
        
        [Test]
        public void SubtractANegativeInteger()
        {
    
    
            Assert.AreEqual(7, MyMath.Subtract(5, -2));
        }
    }
}

Sandals のバグ (その中のフォルダー) をテストします。

アセンブリ設定

ここでは、ケース 02 のアセンブリをコピーして名前を変更し
、エディター ファイル シェルフの下の [エディター] にチェックを入れるだけです。

アセンブリ設定が異なります

他のファイル棚の下にあるものをチェックします。
ここに画像の説明を挿入

アセンブリ設定は同じです

上記の設定ではまだエラーが報告されていません (V0_0_4 が参照する UnityEditor.TestRunner に問題があるのではないかと盲目的に推測しています)
Sandal のパッケージを直接インポートするとエラーが報告されます。これがこのリファレンスの問題です。
ここに画像の説明を挿入

V0_0_4

using UnityEngine;
using UnityEditor;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;

namespace QFramework
{
    
    
    public class V0_0_4
    {
    
    
        class SingletonTestClass : Singleton<SingletonTestClass>
        {
    
    
            private SingletonTestClass() {
    
     }
        }

        [Test]
        public void SingletonTest()
        {
    
    
            var instanceA = SingletonTestClass.Instance;
            var instanceB = SingletonTestClass.Instance;

            Assert.AreEqual(instanceA.GetHashCode(), instanceB.GetHashCode());
        }
    }
}

ここに画像の説明を挿入

V0_0_4編集者

#if UNITY_EDITOR
using NUnit.Framework;

namespace QFramework
{
    
    
    public class V0_0_4
    {
    
    
        class MonoSingletonTestClass : MonoSingleton<MonoSingletonTestClass>
        {
    
    

        }

        [Test]
        public void MonoSingeltonTest()
        {
    
    
            var instanceA = MonoSingletonTestClass.Instance;
            var instanceB = MonoSingletonTestClass.Instance;

            Assert.AreEqual(instanceA.GetHashCode(), instanceB.GetHashCode());
            Assert.AreEqual(instanceA.name, "MonoSingletonTestClass");
        }
    }
}
#endif

ここに画像の説明を挿入

概要 テストフォルダーが実行される

バグは「EmbeddedLinux」をサポートしていません。

    "EmbeddedLinux",报错不支持,

ここに画像の説明を挿入

ここに画像の説明を挿入

ウォッチサンダルの遊び場(フォルダーが入っています)

アセンブリを修正して、そのリファレンスに従ってjsonを置くのも課題ですが、
どこに置くか、内容は何か、リファレンスを自分で確認してください

{
    
    
    "Version":999
}
using NUnit.Framework;
using UnityEngine;

namespace QFramework
{
    
    
	public class NewBehaviourScript : MonoBehaviour
	{
    
    
#if UNITY_EDITOR
		[UnityEditor.MenuItem("QFramework/Playground")]
		private static void Test()
		{
    
    

        }


		[Test]
		public void Playmode()
		{
    
    
			Debug.Log(HotUpdateMgr.Instance.GetLocalResVersion());
		}
#endif
	}
}

ここに画像の説明を挿入

バグ「MenuItem」が見つかりませんでした

00 プログラムと設定にはエディターは含まれません
00 ルートディレクトリに置きます

バグ ObsoleteUnityEditor.BuildTarget

ここに画像の説明を挿入

ウォッチサンダルのアセットバンドルの例

なお、
01 の 2 つの AB パッケージは 6、02 の
2 つのパッケージ方法は 1、4 で結果は同じで、繰り返しのパッケージは自動的に上書きされます。03 パッケージは2 が
チェックできないことが前提です。

ここに画像の説明を挿入
ここに画像の説明を挿入

バグがパッケージをインポートした時刻

私はパッケージが最初にインポートされた時刻を常に認識しており、その後のエクスポートでも開始時刻のままです

    private static string GeneratePackageName()
    {
    
    
      // return "QFramework_" + DateTime.Now.ToString("yyyyMMddHHMM");///注意年小写的yyyy
        return "Common_" + DateTime.Now.ToString("yyyyMMddHHmm");///注意年小写的yyyy
    }

バグ 一部の Editor クラスが認識されない

同じスクリプトの一部を独自の別のアセンブリにコピーしました。以下の図に示すように、エラーが報告されます。これら 3 つのスクリプトを最も外側のエディターにドラッグするのが正常です。
後で、これは #UNITY_EDITOR (MenuItem のラップ) に問題があることが判明しました

その理由は、Unity がアセンブリ内のエディター内のスクリプトを認識できないため、 #UNITY_EDITOR を手動で追加する必要があると盲目的に推測しているためです

Sandal は名前空間を手動で直接書き込み、アセンブリ メソッドを使用しないため、元のバージョンを直接ドラッグする必要はありません。
ここに画像の説明を挿入

----------------------------------------------------

13 フレームワーク構築決定版:理論強化(シーズン3)

----------------------------------------------------

10 はじめに QFramework ユーザーガイド

01 優れたチェーン プログラミング スタイル (コールバック、タイミング)
02 アクション => 解像度 => UI (後者は前者に基づいています)。対応して、Example (例)、Action => Res => UI とライブラリがあります。

私がやったことを修正する

01 コメントを書きます (Unity コードはコメントを単独で書くことができないため、不親切です。図 1 に示すように、コメントとコードの分離が xml によって実現されている場合でも、説明するためにマウスを移動する限り)。 02 拡張機能からの抜粋 (フレームワークは一時的に使用されます。拡張機能はコピーが簡単で、私の拡張機能に統合されます。これは、独自の拡張機能の整理でもあります (エラーを報告せずにこのプロジェクトにドラッグします)
)
ここに画像の説明を挿入

2017.3.xxx を見る

2017.3 あたりのバージョンを直接使用すると、エラーは報告されず、実行に失敗し、DoTween パネルが自動的にポップアップします。
しかし、それでもこのエラーがスローされます
ここに画像の説明を挿入

バグ 2020.3.23f1c1

変更により Common ライブラリが導入されます

こんな感じで、自分のライブラリを使いたくて仕方がありません。

namespace QFramework.Example
{
    
    
	using UnityEngine;
    using UnityEngine.UI;
    using DG.Tweening;

    public class DOTweenExample : MonoBehaviour 
	{
    
    
        Button mBtnMove;
        GameObject mCube;

        void Start () 
        {
    
    
            mCube = GameObject.Find("Cube");
            //mBtnMove = transform.Find("BtnMove").GetComponent<Button>();
            //mBtnMove.onClick.AddListener(() => { mCube.transform.DOMoveX(5, 1f); });
            mBtnMove = transform.FindTop("Canvas").GetButtonDeep
            (
                "BtnMove"
                ,() => {
    
     mCube.transform.DOMoveX(5, 1f); }
            );
        }
    }
}

バグアセンブリ設定

自動生成された CSharp および Editor プロジェクトを直接インポートして使用しても問題ありません。図1。
ただし、組み込みライブラリをインポートし、それを含むアセンブリを設定する必要があります (QFramework の他のアセンブリの設定を見てください。RootName が感謝しているように見えるかどうかは関係ありません)。図2。
主な理由は、制限する必要がある同じ名前のクラスが存在することです。詳細は次の記事をご覧ください
図1

図Ⅱ

バグ ResMgr、UIMgr など、2 つのアセンブリ間の名前の競合

使用するResMgrはQFrameworkのシングルトンクラスなので型ではなく(これが原因かどうかは不明)、xxx=xxxを使う形式は使えない(これは客観的な存在なので追加しても無駄)ので、QFramework.ResMgrに限定するしかありません。

バグプロジェクトモジュール識別エラー

サークル内(見つかりません)
Assets/QFramework/Framework/3.EditorToolKit/Editor/UnityEditorRushTools/CustomHierarchy.cs
が再インポートされますが、これは正常で問題ありません。
ここに画像の説明を挿入

エラーが報告された 5 か所の半分をコメントアウトします。

これら 5 つは Unity2018 で非推奨になりました。しかし、同様の代替品が見つかりませんでした
Assets/QFramework/Framework/3.EditorToolKit/Editor/UnityEditorRushTools/CustomHierarchy.cs
私は TODO をマークしました。図1

図 2 に示すように、Unity2017 はまだ見つかりますが、
Unity2020 は見つかりません (少なくとも Obsolute が与えられます)
マニュアルには期限切れの
NetworkIdentityが表示されます
図1

図 2 Unity2017.3.xxx

無駄なVSキャッシュの削除

VSキャッシュを削除する

無駄にILCppに変更

したがって、デフォルトの Mono に戻します

Bug Unity はエラーを報告しませんでしたが、VS はエラーを報告しました。でも走れる

1 つを切り取るだけで、図 2 に示すように参照関係が存在します。
ここに画像の説明を挿入
図Ⅱ

概要を見る

01 アセンブリ設定、内部の他のアセンブリを参照して設定する
02 名前の競合、制限を追加する、ResMgr、UIMgr と競合する
03 5 廃止されたステートメント、一時的にコメントアウトする

バグ 常に存在するバグ

5 つの古い文章を再インポートしてコメントします。
その他のエラーは見つかりません。どのバージョンであっても報告されるエラーは 1 つだけです
ここに画像の説明を挿入

バグ MonoComplier.Tick

アセンブリの追加や削除を変更すると、処理バーが何度もスタックしてしまいました。
コンパイルエラーです。タスク マネージャーは強制的に終了することしかできない可能性が高く、次回 EnterSafeMode で選択パネルに入るときは、
ここに画像の説明を挿入
ここに画像の説明を挿入

プロジェクトの構造を見る

ここに画像の説明を挿入

01 ディレイ

3 つのタイミング書き込みメソッド、2 つの開始コルーチン、および 1 つのメインスレッド。
最下層は StartCoroutine

namespace QFramework.Example
{
    
    
	using UnityEngine;

	public class DelayNodeExample : MonoBehaviour
	{
    
    

		private DelayAction mDelay3s = DelayAction.Allocate
		(
			3.0f, () => {
    
     Log.I("延时 3s");}
		);

		void Start()
		{
    
    
			this.Delay
			(
				1.0f, () => {
    
    Log.I("延时 1s");}
			);

			var delay2s = DelayAction.Allocate
			(
				2.0f, () => {
    
     Log.I("延时 2s");}
			);
			this.ExecuteNode(delay2s);
		}


		private void Update()
		{
    
    
			if (mDelay3s != null 
				&& !mDelay3s.Finished 
				&& mDelay3s.Execute(Time.deltaTime)
			)
			{
    
    
				Log.I("Delay3s 执行完成");
			}
		}
	}
}


ここに画像の説明を挿入

02

using UnityEngine;

namespace QFramework.Example
{
    
    
	public class EventNodeExample : MonoBehaviour
	{
    
    
		private EventAction mEventNode2 = EventAction.Allocate(
			() => {
    
     Log.I("event 3 called"); },
			() => {
    
     Log.I("event 4 called"); }
		);


		private void Start()
		{
    
    
			var eventNode = EventAction.Allocate(
				() =>{
    
    Log.I("event 1 called"); }, 
				() =>{
    
    Log.I("event 2 called"); }
			);
			this.ExecuteNode(eventNode);
		}



		private void Update()
		{
    
    
			if (mEventNode2 != null 
				&& !mEventNode2.Finished 
				&& mEventNode2.Execute(Time.deltaTime))
			{
    
    
				Log.I("eventNode2 执行完成");
			}
		}
	}
}

ResKitExample.Audio

AB パッケージの報告は依然としてリソースのせいです

using UnityEngine;
using QFramework;
using ResMgr = QFramework.ResMgr;

public class AudioTest : MonoBehaviour 
{
    
    
    private void Start()
    {
    
    
        ResMgr.Init();

        // 
        AudioManager.Instance.SendMsg(new AudioSoundMsg("TestSound"));

        AudioManager.Instance.SendMsg(new AudioMusicMsg("BackGroundMusic"));

        AudioManager.Instance.SendMsg(new AudioStopMusicMsg());

        AudioManager.PlaySound("TestSound");
        
        AudioManager.PlayMusic("BackgroundMusic");
    }
}

ここに画像の説明を挿入

バグの句読点をどこに書くか

チェーンプログラミングにおける + - * / と "." は
まだ左側に置くことが一般的だと感じているためです。

しかし、VS を使用してから、たとえば「,」の前に Enter キーを押しても自動的にインデントされず、Enter キーの後の「,」は自動的にインデントされることがわかりました。
VSのデフォルトとは違うと思ったので違いは残しつつ共通点を探すしかない
ここに画像の説明を挿入

	public static Button GetButtonDeep
    (
        this Transform root, string childName
        ,UnityEngine.Events.UnityAction action
    )
	{
    
    
		Button result   = root.GetButtonDeep(childName);
		result.onClick.AddListener( action );

		return result;
	}
			gameObject
				.Show()
				.Hide()
				.Name("Yeah")
				.Layer(0)
				.Layer("Default")
				.DestroySelf();

時計のメモ

実際、なぜ私が概要メモ (上) を書くよりもこのようなメモ (下) を書きたいのかわかりません (たとえそれが単なるチュートリアルであっても) あまりにも馴染みすぎていますか
?
簡潔?
コンパイルが速い?
ここに画像の説明を挿入

バグアセンブリと名前空間の関係

同じ名前、まったく同じメソッド Identity() を使用します。場所は図の 2 (アセンブリ CSharp、名前空間 QFramework.Example) です。
同じ名前のものが (Assembly Common && no namespace)、図 1 にあります。
同じ名前のものが (アセンブリ QFramework.Core.Runtime && 名前空間 QFramework) にあります (図 3)。

アセンブリアセンブリ Common、QFramework.Core.Runtime は自動参照
システムで 2 番目のアセンブリとして自動的に認識されます

要因がわかりませんが、最近使用したフォルダーのパスはわかりますか?
名前空間とアセンブリ
ここに画像の説明を挿入

LibsExample.ExtensionExample.GameObjectExample

例を 3 つ挙げてください
GameObject:Object
MonoBehaviour:Behaviour:Component:Object
Transform:Component:Object

using UnityEngine;

namespace QFramework.Example
{
    
    
	/// <summary>
	/// CEGO EXAMPLE:GameObject 链式调用支持 
	/// </summary>
	public class GameObjectExample : MonoBehaviour
	{
    
    
		private void Start()
		{
    
    
			gameObject
				.Show()
				.Hide()
				.Name("Yeah")
				.Layer(0)
				.Layer("Default")
				.DestroySelf();

			// 这里到会断掉,因为GameObject销毁之后就不希望再有操作了
			gameObject.DestroySelfGracefully();


			GameObject instantiatedObj = null;

			gameObject
				.DestroySelfAfterDelay(1.5f)
				.DestroySelfAfterDelayGracefully(1.5f)
				.ApplySelfTo(selfObj => instantiatedObj = selfObj.Instantiate());

            Debug.Log(instantiatedObj);

			#region 通过MonoBehaviour去调用GameObject相关的API

			this
				.Show()
				.Hide()
				.Name("Yeah")
				.Layer(0)
				.Layer("Default")
				.DestroyGameObj();

			this
				.DestroyGameObjGracefully();

			this
				.DestroyGameObjAfterDelay(1.5f)
				.DestroyGameObjAfterDelayGracefully(1.5f)
				.ApplySelfTo(selfScript => instantiatedObj = selfScript.gameObject.Instantiate());

			#endregion


			#region 也可以使用Transform,因为Transform继承了Component,而Core里的所有的链式扩展都默认支持了Component

			transform
				.Show()
				.Hide()
				.Name("Yeah")
				.Layer(0)
				.Layer("Default")
				.DestroyGameObj();

			// 这里到会断掉,因为GameObject销毁之后就不希望再有操作了
			transform
				.DestroyGameObjGracefully();

			transform
				.DestroyGameObjAfterDelay(1.5f)
				.DestroyGameObjAfterDelayGracefully(1.5f)
				.ApplySelfTo(selfTrans => instantiatedObj = selfTrans.gameObject.Instantiate());

			#endregion
		}
	}
}

LibsExample.DOTweenExample

namespace QFramework.Example
{
    
    
	using UnityEngine;
    using UnityEngine.UI;
    using DG.Tweening;

    public class DOTweenExample : MonoBehaviour 
	{
    
    
        Button mBtnMove;
        GameObject mCube;

        void Start () 
        {
    
    
            mCube = GameObject.Find("Cube");
            //mBtnMove = transform.Find("BtnMove").GetComponent<Button>();
            //mBtnMove.onClick.AddListener(() => { mCube.transform.DOMoveX(5, 1f); });
            mBtnMove = transform.FindTop("Canvas").GetButtonDeep
            (
                "BtnMove"
                ,() => {
    
     mCube.transform.DOMoveX(5, 1f); }
            );
        }
    }
}

ここに画像の説明を挿入

LibsExample.ExtensionExample

全員が台本を読んだので、次の記事を含めます
ここに画像の説明を挿入

転送できるいくつかのスクリプトを含める必要がある場合 (転送による影響はほとんどありません)

01 UnityAPIExtensions.cs
02 DotNetExtensions.cs
A Framework.Core.Runtime
B Framework.Core.Editor
C 共通 (独自の)

すべての 01 を Common アセンブリに移動し、古いスクリプトを削除し、A が C
01 を参照して 02 を呼び出すようにします。したがって、一緒に移動して一緒に削除します。そうしないと、参照サイクル エラーが発生します (A は B を参照し、B は A を参照します)。
また、B をCとします。
要約すると、元の UnityAPIExtensions.cs、DotNetExtensions.cs を転送して削除します

レポートが表示されないここに画像の説明を挿入

LibsExample.IOCExample

最下層はアセンブリを検索し、タイプを検索する必要があります。

using UnityEngine;

namespace QFramework.Example
{
    
    
	public class InjectExample : MonoBehaviour
	{
    
    
		[Inject] public A AObj;	//注入

		// Use this for initialization
		void Start()
		{
    
    
			var container = new QFrameworkContainer();
			container.RegisterInstance(new A());//放入字典
			container.Inject(this);//注入
			
			container.Resolve<A>().HelloWorld(); //解决
		}

		public class A
		{
    
    
			public void HelloWorld()
			{
    
    
				"This is A obj".LogInfo();
			}
		}
	}
}

ここに画像の説明を挿入

【未完成】LibsExample.NetworkExample

01 始めたばかりです。クラスを直接逆アセンブルします (1 つのクラスと 1 つのスクリプト)
02 QFramework.、QFramework.Example を分割し、名前空間に従って公開 (CSharp) し
ます 03 スクリプトを見ると、PCClient と MobileServer が表示されます (Clent は PC を属性言語として使用し、Server は Mobile を属性言語として使用する必要があるかはわかりません)
ここに画像の説明を挿入

親クラスをプルする

ここに画像の説明を挿入

パッケージクライアント、ユーティリティがサーバーを実行

ここに画像の説明を挿入

パッケージサーバー、Unity がクライアントを実行

バグ パッケージの実行後にリソースが見つからない

プレハブのパスはそのままで、Prefabs フォルダーを追加してその中に置きました。
これは01 AB パッケージには影響しません(図 2)

ここに画像の説明を挿入
図2

バグにより AB パッケージが見つからない

StreamingAssets でプレイしましたが、このエラーは依然として報告されます。
ただし、Unity で実行するとそうではありません。

Failed to Create Res. Not Find AssetData:AssetName:UIMsg BundleName: TypeName: Key:uimsg

。。。。。。

	[QMonoSingletonPath("[Framework]/MobileServer")]
	public class MobileServer : MonoSingleton<MobileServer>
	{
    
    
	......

        private IEnumerator Start()
		{
    
    
            UIMgr.OpenPanel<UIMsg>();

次の図、つまりフォルダー Resources まで実行します。新しいフォルダー Resources を作成し、それをプレハブにドラッグし、パックして、ビルドします。

namespace QFramework
{
    
    
    public static class ResFactory
    {
    
    
        public static IRes Create(ResSearchRule resSearchRule)
        {
    
    
            var lowerAssetName = resSearchRule.AssetName.ToLower();
            
            short assetType = 0;
            if (lowerAssetName.StartsWith("resources/") || lowerAssetName.StartsWith("resources://"))
            {
    
    
                assetType = ResType.Internal;
            }

バグソケットを繰り返すことはできません

逆輸入は解決しました

バグ 突然デバッグにプロセスをアタッチできなくなりました

まず参照関係を理解し​​ます。
以前は reImport という解決策がありました。

UniRx.Async:
UniRx.Async.Editor:UniRx.Async
UniRx:UniRx.Async
UniRx.Example:UniRx、UniRx.Async

LibsExample.BindingsRxExample

using UnityEngine;
using UnityEngine.UI;
using BindingsRx;
using BindingsRx.Bindings;
using BindingsRx.Converters;
using BindingsRx.Exceptions;
using BindingsRx.Extensions;
using BindingsRx.Filters;

namespace QFramework.Example
{
    
    
    public class BindingsRxExample : MonoBehaviour
    {
    
    

        [SerializeField]  InputField mInputField;
        [SerializeField]  Text mText;

        void Start()
        {
    
    
            Transform canvas = transform.FindTop("Canvas");
            mInputField = canvas.Find("InputField").GetComponent<InputField>();
            mText = canvas.Find("Text").GetComponent<Text>();
            
            // from,to。左边的改变会影响右边
            mInputField.BindTextTo
            (
                () => mText.text
                , text => mText.text = text
            );
        }
    }
}

ここに画像の説明を挿入

LibsExample.JsonPathProtobuf

ここに画像の説明を挿入


using System;
using UnityEngine;
using UnityEngine.UI;

namespace QFramework
{
    
    
    public class JsonPathProtobuf : MonoBehaviour
    {
    
    

        ProtoBufTest tempProto = new ProtoBufTest
        {
    
    
            ID = 1,
            Msg = "Hello"
        };

        JsonTest tempJson = new JsonTest {
    
     Age = 18 };
        string assetsRoot = "Assets/QFramework/Example/LibsExample/JsonPathProtobuf/";
        string appRoot;// Application.dataPath不能写这里

        private void Start()
        {
    
    
            appRoot = Application.dataPath + "/QFramework/Example/LibsExample/JsonPathProtobuf/";
            ShowText();
                


            SaveProtoBuff();
            LoadProtoBuff();
            SaveJson();
            LoadJson();
        }


        #region 辅助


        private void ShowText()
        {
    
    
            Text text = transform.FindTop("Canvas").GetComponentInChildren<Text>();
            text.text = "P 保存protoBuf";
            text.text += "\nO 读取protoBuf";
            text.text += "\nA 保存json";
            text.text += "\nS 读取json";
        }

        private void LoadJson()
        {
    
    
            this.Sequence()
                .Until(() => {
    
    
                    return Input.GetKeyDown(KeyCode.S);
                })
                .Event(() => {
    
    
                    string path = appRoot + "/TestJosn/TestJson.json";
                    JsonTest tempLoadJson = SerializeHelper.LoadJson<JsonTest>(path);
                    Debug.Log(tempLoadJson.Age);
                })
                .Begin();
        }

        private void SaveJson()
        {
    
    
            this.Sequence()
                .Until(() => {
    
    
                    return Input.GetKeyDown(KeyCode.A);
                })
                .Event(() => {
    
    
                    string path = appRoot + "TestJosn".CreateDirIfNotExists();
                    path += "/TestJson.json"; tempJson.SaveJson(path);
#if UNITY_EDITOR
                    UnityEditor.AssetDatabase.Refresh();
#endif
                })
                .Begin();
        }

        private void LoadProtoBuff()
        {
    
    
            this.Sequence()
                .Until(() => {
    
    
                    return Input.GetKeyDown(KeyCode.O);
                })
                .Event(() => {
    
    

                    string path = appRoot + "TestJosn/testPro.proto";
                    ProtoBufTest tempLoadBuf = SerializeHelper.LoadProtoBuff<ProtoBufTest>(path);
                    Debug.Log(tempLoadBuf.ID);
                })
                .Begin();
        }

        private void SaveProtoBuff()
        {
    
    
            this.Sequence()
                .Until(() => {
    
    
                    return Input.GetKeyDown(KeyCode.P);
                })
                .Event(() => {
    
    
                    string path = (assetsRoot + "TestJosn").CreateDirIfNotExists();
                    path += "/testPro.proto";
                    tempProto.SaveProtoBuff(path);
#if UNITY_EDITOR
                    UnityEditor.AssetDatabase.Refresh();
#endif

                })
                .Begin();
        }
        #endregion  

    }


    #region 内部类



    [ProtoBuf.ProtoContract]
    public class ProtoBufTest
    {
    
    
        [ProtoBuf.ProtoMember(1)]
        public int ID=0;

        [ProtoBuf.ProtoMember(2)]
        public string Msg="Hello";
    }

    [System.Serializable]
    public class JsonTest
    {
    
    
        private string mName;
        public string Name
        {
    
    
            get {
    
     return mName; }
            set {
    
     mName = value; }
        }
        private int mAge;
        public int Age
        {
    
    
            get {
    
     return mAge; }
            set {
    
     mAge = value; }
        }
    }
    #endregion


}


バグ IL2CPP

モノラルに戻す
ここに画像の説明を挿入

LibsExample/SingletonExample/0.Singleton

シングルトン
MonoSingleton
ISingleton、MonoBehavior
ISingleton

LibsExample/SingletonExample/0.Singleton

シングルトンは削除されましたが、静的変数はまだ存在します

namespace QFramework.Example
{
    
    
	using UnityEngine;

	
	public class Singleton : MonoBehaviour
	{
    
    
		private void Start()
		{
    
    
			Class2Singleton.Instance.Log("Hello World!");
			
			Class2Singleton.Instance.Dispose();//删除
			
			// a differente instance
			Class2Singleton.Instance.Log("Hello World!");
		}
	}
}

ここに画像の説明を挿入

namespace QFramework.Example
{
    
    
    using UnityEngine;

    internal class Class2Singleton : Singleton<Class2Singleton>
    {
    
    
        private static int mIndex = 0;

        private Class2Singleton() {
    
     }

        public override void OnSingletonInit()
        {
    
    
            mIndex++;
        }

        public void Log(string content)
        {
    
    
            Debug.Log("Class2Singleton" + mIndex + ":" + content);
        }
    }
}

LibsExample/SingletonExample/2.SingletonProperty

MonoSingleton のライフサイクルを見てください。
ここに画像の説明を挿入

namespace QFramework.Example
{
    
    
	using System.Collections;
	using UnityEngine;


	public class MonoSingletonExample : MonoBehaviour
	{
    
    
		private IEnumerator Start()
		{
    
    
			var instance = Class2MonoSingleton.Instance;

			yield return new WaitForSeconds(3.0f);
			
			instance.Dispose();
		}
	}
}
namespace QFramework.Example
{
    
    
    using System.Collections;
    using UnityEngine;

    internal class Class2MonoSingleton : MonoSingleton<Class2MonoSingleton>
    {
    
    
        public override void OnSingletonInit()
        {
    
    
            Debug.Log(name + ":" + "OnSingletonInit");
        }

        private void Awake()
        {
    
    
            Debug.Log(name + ":" + "Awake");
        }

        private void Start()
        {
    
    
            Debug.Log(name + ":" + "Start");
        }

        protected override void OnDestroy()
        {
    
    
            base.OnDestroy();

            Debug.Log(name + ":" + "OnDestroy");
        }
    }
}

LibsExample/UniRxExample

UITestUniRx

Xxx というプレハブ、
2 つのスクリプト(両方とも部分的)、スクリプト 1 の名前は XxxComponents (Xxx.Components に変更しました)、スクリプト 2 の名前は Xxx

01 UITestUniRx.Components を見る

using UnityEngine;
using UnityEngine.UI;
using QFramework;

namespace QFramework.Example
{
    
    
	public partial class UITestUniRx
	{
    
    
		[SerializeField] public Toggle Toggle;
		[SerializeField] public Button Button;
		[SerializeField] public InputField InputField;
        [SerializeField] public Text Text;
	}
}

01 UITestUniRxData を見る


using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using QFramework;
using UniRx;

namespace QFramework.Example
{
    
    
	public class UITestUniRxData : UIPanelData
	{
    
    
		// TODO: Query Mgr's Data
	}

	public partial class UITestUniRx : UIPanel
	{
    
    
		protected override void InitUI(IUIData uiData = null)
		{
    
    
		}

		protected override void ProcessMsg (int eventId,QMsg msg)
		{
    
    
			throw new System.NotImplementedException ();
		}

		protected override void RegisterUIEvent()
		{
    
    
            Button
				.onClick
                .AsObservable()//可被观察
                .Subscribe(x=> this.LogInfo("按下按钮"));//点击了就打印
        
            InputField
				.OnValueChangedAsObservable() //值发生变化时
                .Where(x => x != null)		 //当x!=null时
                .SubscribeToText(Text);	   //变换Text的值

            Toggle
				.OnValueChangedAsObservable() //值发生变化时
                .SubscribeToInteractable(Button); //设置是否可交互
        }

		protected override void OnShow()
		{
    
    
			base.OnShow();
		}

		protected override void OnHide()
		{
    
    
			base.OnHide();
		}

		protected override void OnClose()
		{
    
    
		}

		void ShowLog(string content)
		{
    
    
			Debug.Log("[ UITestUniRx:]" + content);
		}
	}
}

01、02テスト(01、02効果テスト)を見る



using System.Collections.Generic;
using UnityEngine;
using QFramework;
using QFramework.Example;
using UniRx;
using UnityEngine.UI;
using System;
using System.Text;
using UnityEngine.Networking;
using System.Collections;

namespace LFramework
{
    
    
    /// <summary>
    /// 2018/3/30
    /// </summary>
    public class TestUniRx : MonoBehaviour
    {
    
    
        #region 字属


        public static readonly UniRx.Diagnostics.Logger log =   new UniRx.Diagnostics.Logger("L Log");
        //IReactiveProperty<bool> isChange      = new ReactiveProperty<bool>(false);


        [Header("ReactiveSubscribe的")]
        private CompositeDisposable disposables = new CompositeDisposable();
        /// <summary>ReactiveSubscribe的初始符</summary>
        bool ReactiveSubscribeFirst = false;
        private IDisposable CurrentSub;
        #endregion

        #region 测试
        void Start()
        {
    
    
            QFramework.ResMgr.Init();
            ReactiveSubscribeFirst = false;
            TestStart01();
            TestStart02();


        }

        void TestStart01()
        {
    
     
            QFramework.UIMgr.OpenPanel<UITestUniRx>();
        }
        void TestStart02()
        {
    
    
            //说明怎么操作
            Debug.Log( String.Format(
                  "( a , DoubleClick);           //双击                    \n "
                + "( s , WWW);                   //WWW                     \n "
                + "( d , Property);              //属性监听(T键改变值)   \n "
                + "( f , Coroutine);             //和unity协程             \n "
                + "( g , ReactiveSubscribe);     //收集器                  \n "
                + "( h , TsfSubscribe);          //transform               \n  "
                + "空格就退出\n "                
                ) );
            Dictionary<string, Action> m_FuncDic = new Dictionary<string, Action>();
            m_FuncDic.Add("a", DoubleClick);           //双击
            m_FuncDic.Add("s", WWW);                   //WWW
            m_FuncDic.Add("d", Property);              //属性监听
            m_FuncDic.Add("f", Coroutine);             //和unity协程
            m_FuncDic.Add("g", ReactiveSubscribe);     //收集器
            m_FuncDic.Add("h", TsfSubscribe);          //transform

            //UniRx.Diagnostics.ObservableLogger//这里应该只是演示一种格式
            //    .Listener
            //    .Subscribe(_ => Debug.Log(_));

            // m_FuncDic中,按了什么键,执行什么方法
            Observable.EveryUpdate()
                .Do((x) => {
    
    
                    if (Input.inputString != string.Empty && Input.inputString != " ")
                    {
    
    
                        Debug.Log(Input.inputString);
                        if (m_FuncDic.ContainsKey(Input.inputString))
                        {
    
    
                            if (CurrentSub != null)
                            {
    
     
                                CurrentSub.Dispose();
                            }
                            m_FuncDic[Input.inputString].InvokeGracefully();
                        }
                    }
                })
                .Subscribe()
                .AddTo(this);

            
            Observable.EveryUpdate()
                .Where(_ => Input.GetKeyDown(KeyCode.Space))
                .Subscribe(_ => {
    
    
                    disposables.Dispose();
                    disposables.Clear();
                })
                .AddTo(this);
        }


        #endregion



        #region 辅助
        /// <summary>双击</summary>
        void DoubleClick()
        {
    
    
            var stream = Observable
                .EveryUpdate()
                .Where(x => Input.GetMouseButtonDown(0));

            CurrentSub = stream
                .Buffer(stream.Throttle(TimeSpan.FromSeconds(0.25f)))
                .Do(x => Debug.Log("在检测"))
                .Where(x => x.Count >= 2)
                .Subscribe(x => Debug.Log("按下次数" + x.Count));
        }

        void WWW()
        {
    
    
            ObservableWWW
                //.GetWWW("http://img.taopic.com/uploads/allimg/120428/128240-12042Q4020849.jpg")//这地址没东西了
                .GetWWW("https://patchwiki.biligame.com/images/blhx/thumb/a/a3/0ldcv3eg1w6c27witzhw69rskhlurum.jpg/350px-%E5%A4%A7%E5%87%A4%E6%8D%A2%E8%A3%855.jpg")
                .Subscribe(down =>{
    
    
                    Texture2D temp2d = down.texture;
                    Debug.Log(temp2d.name);
                    Sprite tempSp = Sprite.Create(temp2d
                        , new Rect(0, 0, temp2d.width, temp2d.height)
                        , Vector2.zero);
                    QFramework.UIMgr.GetPanel<UITestUniRx>().GetComponent<Image>().sprite = tempSp;
                }, x => Debug.Log("请求错误"))
                .AddTo(disposables);
        }


        /// <summary>属性</summary>
        void Property()
        {
    
    
            IReactiveProperty<bool> m_Bool = new ReactiveProperty<bool>(false);
            m_Bool.Subscribe(xs => Debug.Log("值改变"));

            CurrentSub = Observable.EveryUpdate()
                .Where(_ => Input.GetKeyDown(KeyCode.T))
                .Subscribe(_ => m_Bool.Value = !m_Bool.Value);
        }


        /// <summary>协程</summary>
        void Coroutine()
        {
    
    
            Sample10_MainThreadDispatcher temp = new Sample10_MainThreadDispatcher();
            CurrentSub = temp.Run();
            Debug.Log(temp);
        }

        /// <summary>GameObj</summary>
        void ReactiveSubscribe()
        {
    
    

            if (ReactiveSubscribeFirst == false)
            {
    
     
                ReactiveSubscribeFirst= true;

            }
            disposables = new CompositeDisposable();
            ReactiveCollection<int> m_ReaList = new ReactiveCollection<int>();
            //
            m_ReaList.ObserveCountChanged()
                .Subscribe(x => {
    
     Debug.Log("变"+x); })
                .AddTo(disposables);

            m_ReaList.ObserveAdd()
                .Subscribe(x => {
    
     Debug.Log("加"+x); })
                .AddTo(disposables);

            m_ReaList.ObserveRemove()
                .Subscribe(x => Debug.Log("减"+x))
                .AddTo(disposables);
            //
            m_ReaList.Add(1);
            m_ReaList.Remove(1);
            CurrentSub = disposables;
            Debug.Log("-------------------------------");
        }

        /// <summary>transform</summary>
        void TsfSubscribe()
        {
    
    
            CurrentSub = transform
                .ObserveEveryValueChanged(x => x.position)
                .Subscribe(x => Debug.Log(x));
        }
        #endregion



        #region 内部类

        /// <summary>从Assets/QFramework/Example/LibsExample/UniRxExample/OfficialExamples/Sample10_MainThreadDispatcher.cs
        /// 复制修改的类
        ///  <para/>都运行打印很乱,可以注释其它一个一个运行
        /// </summary>
        public class Sample10_MainThreadDispatcher
        {
    
    
            public CompositeDisposable Run()
            {
    
    


                Debug.Log("--------------------------");
                CompositeDisposable disposable = new CompositeDisposable();
                // MainThreadDispatcher is heart of Rx and Unity integration
                // StartCoroutine can start coroutine besides MonoBehaviour.
                MainThreadDispatcher.StartCoroutine(TestAsync());//调用一次,执行一次


                // We have two way of run coroutine, FromCoroutine or StartCoroutine.
                // StartCoroutine is Unity primitive way and it's awaitable by yield return.
                // FromCoroutine is Rx, it's composable and cancellable by subscription's IDisposable.
                // FromCoroutine's overload can have return value, see:Sample05_ConvertFromCoroutine
                Observable.FromCoroutine(TestAsync)//调用一次,执行一次
                    .Subscribe()
                    .AddTo(disposable);


                // Add Action to MainThreadDispatcher. Action is saved queue, run on next update.
                MainThreadDispatcher.Post(_ => Debug.Log("test"), null); //调用一次,执行一次


                // Timebased operations is run on MainThread(as default)
                // All timebased operation(Interval, Timer, Delay, Buffer, etc...)is single thread, thread safe!
                Observable.Interval(TimeSpan.FromSeconds(1))//每隔一秒x++
                    .Subscribe(x => Debug.Log(x))
                    .AddTo(disposable);


                // Observable.Start use ThreadPool Scheduler as default.
                // ObserveOnMainThread return to mainthread
                Observable.Start(() => Unit.Default) // asynchronous work ;打印了Unit的ToString()方法
                    .ObserveOnMainThread()
                    .Subscribe(x => Debug.Log(x))
                    .AddTo(disposable);
                //
                return disposable;
            }

            IEnumerator TestAsync()
            {
    
    
                Debug.Log("a");
                yield return new WaitForSeconds(1);
                Debug.Log("b");
                yield return new WaitForSeconds(1);
                Debug.Log("c");
                yield return new WaitForSeconds(1);
                Debug.Log("d");
            }
        }

        #endregion      

    }
}


ウォッチ01エフェクト

ここに画像の説明を挿入

ウォッチ02エフェクト

ダブルクリックを検出する

ここに画像の説明を挿入

ネットマップ WWW

ここに画像の説明を挿入

ブール値をリッスンする

ここに画像の説明を挿入

リストを聞く

別途掲載します。
実行時は追加後自動変更
削除後自動変更
ここに画像の説明を挿入

        /// <summary>GameObj</summary>
        void ReactiveSubscribe()
        {
    
    

            if (ReactiveSubscribeFirst == false)
            {
    
     
                ReactiveSubscribeFirst= true;

            }
            disposables = new CompositeDisposable();
            ReactiveCollection<int> m_ReaList = new ReactiveCollection<int>();
            //
            m_ReaList.ObserveCountChanged()
                .Subscribe(x => {
    
     Debug.Log("变"+x); })
                .AddTo(disposables);

            m_ReaList.ObserveAdd()
                .Subscribe(x => {
    
     Debug.Log("加"+x); })
                .AddTo(disposables);

            m_ReaList.ObserveRemove()
                .Subscribe(x => Debug.Log("减"+x))
                .AddTo(disposables);
            //
            m_ReaList.Add(1);
            m_ReaList.Remove(1);
            CurrentSub = disposables;
            Debug.Log("-------------------------------");
        }

リスニング変換

ここに画像の説明を挿入

LibsExample/UniRxExample/OfficialExamples

Sample01_観察可能なWWW

メソッドのみを記述し、MonoBehavior で呼び出します。

ObservableWWW.Get

        /// <summary></summary>
        private void StartTest01()
        {
    
    
            // Basic: Download from google.
                //ObservableWWW.Get("http://google.co.jp/") //我这边超时错误
                ObservableWWW
                    .Get("https://baidu.com/")//返回<!DOCTYPE html><!--STATUS OK--><html><head><meta.......
                    .Subscribe(
                        onNext:  res  => Debug.Log(res.Substring(0, 100)), // onSuccess
                        onError: error => Debug.LogException(error)); // onError
        }

ここに画像の説明を挿入

から、選択

ここに画像の説明を挿入

        private void StartTest02()
        {
    
    
            int textId = 2;//外网测不了时
            if(textId == 1)
            {
    
    
                // Linear Pattern with LINQ Query Expressions
                // download after google, start bing download
                var query = from google in ObservableWWW.Get("http://google.com/")
                            from bing in ObservableWWW.Get("http://bing.com/")
                            select new {
    
     google, bing };



                var cancel = query.Subscribe(x => {
    
    
                    Debug.LogFormat("{0}:{1}"
                        , x.google.Substring(0, 100)
                        , x.bing.Substring(0, 100));
                });            
                // Call Dispose is cancel downloading.
                cancel.Dispose();
            }
            if(textId ==2)//有时会报错Empty reply from server,多运行几下
            {
    
     
                var query = from baidu in ObservableWWW.Get("http://baidu.com/")
                              from sougou in ObservableWWW.Get("http://sougou.com/")
                              select new {
    
     baidu, sougou };


                var cancel = query
                    .Subscribe(res => {
    
    

                        Debug.Log(res.baidu);
                        Debug.Log(res.sougou);
                        Debug.LogFormat("{0}:{1}"
                            , res.baidu.Substring(0, 5)
                            , res.sougou.Substring(0, 5));
                });
                // Call Dispose is cancel downloading.
                //cancel.Dispose();
            }
        }

いつすべて

ここに画像の説明を挿入

       private void StartTest03_WhenAll()
        {
    
    
            int curID = 2;
            if (curID == 1)
            {
    
    
                // Observable.WhenAll is for parallel asynchronous operation
                // (It's like Observable.Zip but specialized for single async operations like Task.WhenAll of .NET 4)
                var parallel = Observable.WhenAll(
                    ObservableWWW.Get("http://google.com/"),
                    ObservableWWW.Get("http://bing.com/"),
                    ObservableWWW.Get("http://unity3d.com/"));

                parallel.Subscribe(xs =>
                {
    
    
                    Debug.Log(xs[0].Substring(0, 100)); // google
                    Debug.Log(xs[1].Substring(0, 100)); // bing
                    Debug.Log(xs[2].Substring(0, 100)); // unity
                });
            }

            if (curID == 2)
            {
    
    
                //意思是res的复数
                var reses = Observable.WhenAll(
                    ObservableWWW.Get("https://baidu.com/")
                    , ObservableWWW.Get("https://sougou.com/")
                    , ObservableWWW.Get("https://www.bilibili.com/")
                );

                reses.Subscribe(res =>
                {
    
    
                    Debug.Log(res[0].Substring(0, 100));
                    Debug.Log(res[1].Substring(0, 100));
                    Debug.Log(res[2].Substring(0, 100));
                });
            }

        }

ScheduledNotifier の進行状況

100% 直接実行
ここに画像の説明を挿入

        private void StartTest04_ScheduledNotifier()
        {
    
    
            int curID = 2;
            if (curID == 1)
            {
    
    
                // with Progress
                // notifier for progress
                var progressNotifier = new ScheduledNotifier<float>();
                progressNotifier.Subscribe(x => Debug.Log(x)); // write www.progress

                // pass notifier to WWW.Get/Post
                ObservableWWW
                    .Get(url: "http://google.com/", progress: progressNotifier)
                    .Subscribe();
            }
            if (curID == 2)
            {
    
    
                var scheduledNotifier = new ScheduledNotifier<float>();
                scheduledNotifier.Subscribe(x => Debug.Log(x));


                ObservableWWW
                    .Get(url: "http://baidu.com/", progress: scheduledNotifier)
                    .Subscribe();
            }
        }

WWWエラー例外

ここに画像の説明を挿入

       private void StartTest05_WWWErrorException()
        {
    
    
            int curID = 2;
            if (curID == 1)
            {
    
    
                // with Error
                // If WWW has .error, ObservableWWW throws WWWErrorException to onError pipeline.
                // WWWErrorException has RawErrorMessage, HasResponse, StatusCode, ResponseHeaders
                ObservableWWW
                    .Get("http://www.google.com/404")
                    .CatchIgnore((WWWErrorException ex) =>
                    {
    
    
                        Debug.Log(ex.RawErrorMessage);
                        if (ex.HasResponse)
                        {
    
    
                            Debug.Log(ex.StatusCode);
                        }
                        foreach (var item in ex.ResponseHeaders)
                        {
    
    
                            Debug.Log(item.Key + ":" + item.Value);
                        }
                    })
                    .Subscribe();
            }
            if (curID == 2)
            {
    
    
                ObservableWWW.Get("https://www.bilibili.com/404")
                    .CatchIgnore((WWWErrorException error) =>
                    {
    
    
                        Debug.Log(error.RawErrorMessage);
                        if (error.HasResponse)
                        {
    
    
                            Debug.Log(error.StatusCode);
                        }
                        string str = "";
                        foreach (var item in error.ResponseHeaders)
                        {
    
    
                            str+=item.Key + ":" + item.Value+"\n";
                        }

                        Debug.Log(str);
                    })
                    .Subscribe();
            }
        }

Sample02_ObservableTriggers

ここに画像の説明を挿入

      void Do_ObservableUpdateTrigger()
        {
    
    
            int curID = 2;
            if (curID == 1)
            {
    
    
                // Get the plain object
                var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);

                // Add ObservableXxxTrigger for handle MonoBehaviour's event as Observable
                cube.AddComponent<ObservableUpdateTrigger>()
                    .UpdateAsObservable()
                    .SampleFrame(30)
                    .Subscribe(
                        res => Debug.Log("cube")
                        , () => Debug.Log("destroy"));

                // destroy after 3 second:)
                GameObject.Destroy(cube, 6f);
            }

            if (curID == 2)
            {
    
    
                var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);

                cube.AddComponent<ObservableUpdateTrigger>()
                    .UpdateAsObservable()
                    .SampleFrame(30)
                    .Skip(1)
                    .Subscribe(_ => {
    
    
                        Debug.Log("cube");
                        Debug.Log("destroy");
                    });

                GameObject.Destroy(cube, 4f);
            }
        }

Sample03_GameObjectAsObservable(UpdateAsObservable、OnMouseUpAsObservable)

ここに画像の説明を挿入

        void Start()
        {
    
    
            int curId = 2;
            if (curId == 1)
            {
    
    
                // All events can subscribe by ***AsObservable if enables UniRx.Triggers
                this.OnMouseDownAsObservable()
                    .SelectMany(_ => this.gameObject.UpdateAsObservable())
                    .TakeUntil(this.gameObject.OnMouseUpAsObservable())//结束标志
                    .Select(_ => Input.mousePosition)
                    .RepeatUntilDestroy(this)
                    .Subscribe(pos => Debug.Log(pos), () => Debug.Log("!!!" + "complete"));
            }
            if (curId == 2)
            {
    
    
                // All events can subscribe by ***AsObservable if enables UniRx.Triggers
                this.OnMouseDownAsObservable()//鼠标点击
                    .SelectMany(_ => this.gameObject.UpdateAsObservable())//点击的是一个物体
                    .TakeUntil(this.gameObject.OnMouseUpAsObservable())//结束标志
                    .Select(_ => Input.mousePosition) //在结果中选择 pos
                    .RepeatUntilDestroy(this) //不断重复这个过程直到销毁
                    .Subscribe(
                         onNext: pos => Debug.Log(pos), 
                         onCompleted: () => Debug.Log("!!!" + "complete")
                     );
            }
        }

Sample04_ConvertFromUnityCallback

+LogCallbackを出力するだけです
ここに画像の説明を挿入

using System;
using UnityEngine;

namespace UniRx.Examples
{
    
    
    public class Sample04_ConvertFromUnityCallback : MonoBehaviour
    {
    
    
        void Awake()
        {
    
    
            // method is separatable(分离) and composable(组合)
            LogHelper
                .LogCallbackAsObservable()
                .Where( x => (x.LogType == LogType.Warning)  )
                .Subscribe(x => Debug.Log(x));

            LogHelper
                .LogCallbackAsObservable()
                .Where(x => (x.LogType == LogType.Error) )
                .Subscribe(x => Debug.Log(x));
        }

        private void Update()
        {
    
    
            if (Input.GetMouseButtonDown(0))
            {
    
    
                Debug.LogWarning("LogWarning");
                Debug.LogError("LogError");
            }
        }


        #region 内部类


        // This is about log but more reliable log sample => Sample11_Logger

        private class LogCallback
        {
    
    
            public string Condition;
            public string StackTrace;
            public UnityEngine.LogType LogType;
        }

        static class LogHelper
        {
    
    
            // If static register callback, use Subject for event branching.

#if (UNITY_4_0 || UNITY_4_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7)                    
            static Subject<LogCallback> subject;

            public static IObservable<LogCallback> LogCallbackAsObservable()
            {
    
    
                if (subject == null)
                {
    
    
                    subject = new Subject<LogCallback>();

                    // Publish to Subject in callback


                    UnityEngine.Application.RegisterLogCallback((condition, stackTrace, type) =>
                    {
    
    
                        subject.OnNext(new LogCallback {
    
     Condition = condition, StackTrace = stackTrace, LogType = type });
                    });
                }

                return subject.AsObservable();
            }

#else
            // If standard evetns, you can use Observable.FromEvent.

            public static IObservable<LogCallback> LogCallbackAsObservable()
            {
    
    
                return Observable.FromEvent<Application.LogCallback, LogCallback>(
                    conversion: h 
                    => ( 
                        condition, 
                        stackTrace, 
                        type) 
                    => h( new LogCallback {
    
     
                        Condition = condition, 
                        StackTrace = stackTrace, 
                        LogType = type
                    }),
                    addHandler:    h => Application.logMessageReceived += h, 
                    removeHandler: h => Application.logMessageReceived -= h);
            }
#endif
        }
        #endregion



    }
}

Sample05_ConvertFromCoroutine

届いたのですが形式が間違っていて公式サイトを見てもどこが間違っているのかわかりません。
ここに画像の説明を挿入

開始スクリプト Sample05_ConvertFromCoroutine_Start

/****************************************************
    文件:Sample05_ConvertFromCoroutine_Start.cs
	作者:lenovo
    邮箱: 
    日期:2023/6/10 9:21:46
	功能:对应的测试脚本
*****************************************************/

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;

namespace UniRx.Examples
{
    
    
    public class Sample05_ConvertFromCoroutine_Start : MonoBehaviour
    {
    
    
        #region 属性

        #endregion

        #region 生命



        /// <summary>首次载入且Go激活</summary>
        void Start()
        {
    
    
            Sample05_ConvertFromCoroutine.GetWWW("https://www.baidu.com",gameObject);
            //https://docs.unity.cn/2021.3/Documentation/ScriptReference/Networking.UnityWebRequest.Get.html
            //"https://www.example.com"
            //https://error.html"
        }


        #endregion

    }
}




Sample05_ConvertFromCoroutine

using System;
using System.Collections;
using System.Threading;
using UnityEngine;
#if UNITY_2018_3_OR_NEWER
#pragma warning disable CS0618
#endif

namespace UniRx.Examples
{
    
    
    public class Sample05_ConvertFromCoroutine
    {
    
    
        // public method
        public static IObservable<string>  GetWWW(string url,GameObject gameObject=null)
        {
    
    
            int curID = 2;   
            if (curID == 1)
            {
    
     
          
                // convert coroutine to IObservable
                // cancellation ,取消的名词
                // Token,目的为了减轻服务器压力,方式是对请求数据(用户名与密码)的加工
                return Observable
                    .FromCoroutine<string>((observer, cancellationToken) 
                         => GetWWWCore(url, observer, cancellationToken)
                    );            
            }
            if (curID == 2)
            {
    
    
                return (IObservable<string>)Observable
                    .FromCoroutine<string>((observer, cancellationToken)
                        => GetWWWCore(url, observer, cancellationToken))
                    .Subscribe(
                        _ => Debug.Log("OnNext"),
                        () => Debug.Log("OnCompleted"))
                    .AddTo(gameObject);
            }

            return null;



        }

        // IEnumerator with callback
        static IEnumerator GetWWWCore(string url
            , IObserver<string> observer
            , CancellationToken cancellationToken)
        {
    
    
            var www = new UnityEngine.WWW(url);
            while (!www.isDone && !cancellationToken.IsCancellationRequested)//连接中
            {
    
               
               
                yield return null;
            }

            if (cancellationToken.IsCancellationRequested)//取消连接
            {
    
    
                yield break;
            } 

            if (www.error != null) //连接错误
            {
    
    
                observer.OnError(new Exception(www.error));
            }
            else  //连接成功
            {
    
    
                observer.OnNext(www.text);
                Debug.Log(www.text);
                observer.OnCompleted();
            }
        }
    }
}
#if UNITY_2018_3_OR_NEWER
#pragma warning restore CS0618
#endif

Sample06_ConvertToCoroutine

印刷番号、
リクエスト URL、場合によってはエラー (unity3d.com) はエラーの可能性が高い
ここに画像の説明を挿入

using System;
using System.Collections;
using UnityEngine;

namespace UniRx.Examples
{
    
    
    public class Sample06_ConvertToCoroutine : MonoBehaviour
    {
    
    
        // convert IObservable to Coroutine
        void Start()
        {
    
    
            StartCoroutine(  NormalCoroutine()  );
            StartCoroutine( TestNewCustomYieldInstruction()  );
        }



        #region 辅助


        /// <summary>=Range(1, 10),然后Return(100)</summary>
        IEnumerator NormalCoroutine()     
            

        {
    
    
            yield return new WaitForSeconds(1);


            var val = default(int);
            yield return Observable
                .Range(1, 10)
                .StartAsCoroutine(x => {
    
     val = x; });


            Debug.Log(val); // 10(callback is last value)
            yield return new WaitForSeconds(3);


            yield return Observable
                .Return(100)
                .StartAsCoroutine(x => {
    
     val = x; });


            Debug.Log(val); // 100
        }


        #region TestNewCustomYieldInstruction


        // Note:ToAwaitableEnumerator/StartAsCoroutine/LazyTask are obsolete way on Unity 5.3
        // You can use ToYieldInstruction.

#if !(UNITY_4_0 || UNITY_4_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2)
#if UNITY_2018_3_OR_NEWER
#pragma warning disable CS0618
#endif

        IEnumerator TestNewCustomYieldInstruction()
        {
    
    
            // wait Rx Observable.
            yield return Observable
                .Timer(TimeSpan.FromSeconds(1))
                .ToYieldInstruction();


            // you can change the scheduler(this is ignore Time.scale)
            yield return Observable
                .Timer( TimeSpan.FromSeconds(1), Scheduler.MainThreadIgnoreTimeScale )
                .ToYieldInstruction();


            // get return value from ObservableYieldInstruction
            var oWWW = ObservableWWW
                //.Get("http://unity3d.com/")
                .Get("https://www.baidu.com/")
                .ToYieldInstruction(throwOnError: false);
            yield return oWWW;                                                                                                                    


            if (oWWW.HasError) 
            {
    
     
                Debug.Log("oWWW.Error\n" + oWWW.Error.ToString()); 
            }
            if (oWWW.HasResult)
            {
    
     
                Debug.Log("oWWW.Result\n"+ oWWW.Result); 
            }

            // other sample(wait until transform.position.y >= 100)
            // 这块我打印不出什么来验证
            yield return this
                .ObserveEveryValueChanged(go => go.transform)
                .FirstOrDefault(trans => trans.position.y >= 100 )
                .ToYieldInstruction();

        }
#if UNITY_2018_3_OR_NEWER
#pragma warning restore CS0618
#endif
#endif
        #endregion
        #endregion


    }
}

Sample07_OrchestratIEnumerator

2 回実行し、2 回目にマウスをクリックしてコルーチンを終了します。
ここに画像の説明を挿入

#pragma warning disable 0168
#pragma warning disable 0219

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

namespace UniRx.Examples
{
    
    
    public class Sample07_OrchestratIEnumerator : MonoBehaviour
    {
    
    


        void Start()
        {
    
    
            // after completed AsyncA, run AsyncB as continuous routine.
            // UniRx expands SelectMany(IEnumerator) as SelectMany(IEnumerator.ToObservable())
            var cancel = Observable
               .FromCoroutine(AsyncA)
                .SelectMany(AsyncB)//==.SelectMany(AsyncB.ToObservable())
                .Subscribe();



            // If you want to stop Coroutine(as cancel), call subscription.Dispose()
            // cancel.Dispose();
            Observable.EveryUpdate()
                .Where(_ => Input.GetMouseButtonDown(0))
                .Subscribe(_ => cancel.Dispose(), () =>Debug.Log("已取消!!!")); //取消协程任务


            int i = 0; //做个计时不然看不出效果
            Observable
                .EveryUpdate()
                .Sample(TimeSpan.FromSeconds(1f))
                .Subscribe(_ => Debug.Log(i++ + "DoTimer-----"))
                .AddTo(this);
        }

        // two coroutines
        IEnumerator AsyncA()
        {
    
    
            Debug.Log("a start");
            yield return new WaitForSeconds(3);
            Debug.Log("a end");
        }                                         

        IEnumerator AsyncB()
        {
    
    
            Debug.Log("b start");
            yield return new WaitForEndOfFrame();
            Debug.Log("b end");
        }
    }
}

#pragma warning restore 0219
#pragma warning restore 0168

Sample08_DetectDoubleClick ダブルクリック

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

namespace UniRx.Examples
{
    
    
    public class Sample08_DetectDoubleClick : MonoBehaviour
    {
    
    
        void Start()
        {
    
    
            // Global event handling is very useful.
            // UniRx can handle there events.
            // Observable.EveryUpdate/EveryFixedUpdate/EveryEndOfFrame
            // Observable.EveryApplicationFocus/EveryApplicationPause
            // Observable.OnceApplicationQuit

            // This DoubleCLick Sample is from
            // The introduction to Reactive Programming you've been missing
            // https://gist.github.com/staltz/868e7e9bc2a7b8c1f754

            var clickStream = Observable.EveryUpdate()
                .Where(_ => Input.GetMouseButtonDown(0));  //if(Input.GetMouseButtonDown(0))


            //打印"双击DoubleClick Detected! Count:" num++
            clickStream
                .Buffer(clickStream.Throttle(TimeSpan.FromMilliseconds(250)))//掐死(面包条一段一段掐团),if(timer>=250){ xs.Count++;timer=0;}
                .Where(xs => xs.Count >= 2)//predicate谓语. if (xs.Count >= 2)
                .Subscribe(xs => Debug.Log("双击DoubleClick Detected! Count:" + xs.Count));
        }
    }
}

サンプル09_イベント処理

スタートテスト01

Qを押します
ここに画像の説明を挿入

スタートテスト02

ここに画像の説明を挿入

スタートテスト03

ここに画像の説明を挿入

スタートテスト04

ここに画像の説明を挿入

スタートテスト05

StartTest01~05のスクリプト

#pragma warning disable 0067

using System;
using System.Reflection;
using UnityEngine;

namespace UniRx.Examples
{
    
    
    public class Sample09_EventHandling : MonoBehaviour
    {
    
    




        #region 字属


        /// <summary>Foo,function object Oriented,即面向对象函数,原命名为FooBar</summary>
        public event EventHandler<MyEventArgs> mMyEventHandler;
        public event Action<int> mIntAction;

        CompositeDisposable mCompositeDisposable = new CompositeDisposable();

        // Subject is Rx's native event expression and recommend way for use Rx as event.
        // Subject.OnNext as fire event,
        // expose IObserver is subscibable for external source, it's no need convert.
        Subject<int> mSubject = new Subject<int>(); //主题
        public IObservable<int> mObservable {
    
     get {
    
     return mSubject; } } //可被观察的
        #endregion



        #region 生命
        void Start()
        {
    
    
            //不用Start,采用Update按键的方式
            //StartTest01();
            //StartTest02();
            //StartTest03();
            //StartTest04();
            //StartTest05();
        }

        private void Update()
        {
    
    
            Common.DownKeyCode( KeyCode.Q, StartTest01 );
            Common.DownKeyCode( KeyCode.W, StartTest02 );
            Common.DownKeyCode( KeyCode.E, StartTest03 );
            Common.DownKeyCode( KeyCode.R, StartTest04 );
            Common.DownKeyCode( KeyCode.T, StartTest05 );
        }

        void OnDestroy()
        {
    
    
            // manage subscription lifecycle
            mCompositeDisposable.Dispose();
        }
        #endregion



        #region 辅助


        private void StartTest01()
        {
    
    
            //01 定义
            // convert to IO<EventPattern> as (sender, eventArgs)
            Observable.FromEventPattern<EventHandler<MyEventArgs>, MyEventArgs>(
                    conversion:    handler => handler.Invoke,
                    addHandler:    handler => mMyEventHandler += handler,
                    removeHandler: handler => mMyEventHandler -= handler)//后面都用 h 简代 handler
                .Subscribe(onNext: handler => Debug.Log("StartTest01的OnNext CallBack:"+ handler.EventArgs.ToString()) )
                .AddTo(mCompositeDisposable); // IDisposable can add to collection easily by AddTo

            //02 接下来测试

            mMyEventHandler(this, new MyEventArgs {
    
     MyProperty = 666 });
        }

        private void StartTest02()
        {
    
                                                                                           
            // convert to IO<EventArgs>, many situation this is useful than FromEventPattern
            Observable.FromEvent<EventHandler<MyEventArgs>, MyEventArgs>(
                    conversion:    h => (sender, e) => h(e),
                    addHandler:    h => mMyEventHandler += h,
                    removeHandler: h => mMyEventHandler -= h)
                .Subscribe(onNext: handler => Debug.Log("StartTest02的OnNext CallBack:" + handler.MyProperty) )
                .AddTo(mCompositeDisposable);

            mMyEventHandler(this, new MyEventArgs {
    
     MyProperty = 666 });

        }

        private void StartTest03()
        {
    
    
            // You can convert Action like event.
            Observable.FromEvent<int>(
                    addHandler:    h => mIntAction += h,
                    removeHandler: h => mIntAction -= h)
                .Subscribe(onNext: handler => Debug.Log("StartTest03的OnNext CallBack:" + handler.ToString()))
                .AddTo(mCompositeDisposable);

            mIntAction(3); //一个委托(命令、请求都可以说,实质是方法的地址,这个例子没往里面塞具体的方法)
        }

        private void StartTest04()
        {
    
    
            // AOT Safe EventHandling, use dummy capture, see:https://github.com/neuecc/UniRx/wiki/AOT-Exception-Patterns-and-Hacks
            var capture = 0;
            Observable.FromEventPattern<EventHandler<MyEventArgs>, MyEventArgs>(
                    conversion:     h => 
                    {
    
    
                        capture.GetHashCode(); // dummy for AOT
                        return new EventHandler<MyEventArgs>(h);
                    },
                    addHandler:     h => mMyEventHandler += h,
                    removeHandler:  h => mMyEventHandler -= h)
                .Subscribe(onNext: handler => Debug.Log("StartTest04的OnNext CallBack:" + handler.EventArgs.ToString()))
                .AddTo(mCompositeDisposable);

            mMyEventHandler(this, new MyEventArgs {
    
     MyProperty = 666 });
        }

        private void StartTest05()
        {
    
    
            // Subject as like event.
            mObservable
                .Subscribe(onNext: handler => Debug.Log("StartTest05的OnNext CallBack:") )
                .AddTo(mCompositeDisposable);

            mSubject.OnNext(1); // fire event
        }
        #endregion

        #region 内部类
        public class MyEventArgs : EventArgs
        {
    
    
            public int MyProperty {
    
     get; set; }

            public override string ToString()
            {
    
    
                string str = "";
                str += "MyProperty\t" + MyProperty + "\n";

                return str;
            }
        }
        #endregion

    }
}

#pragma warning restore 0067

Sample10_MainThreadDispatcher

結果はコメントに書いてあります

             RunTest01(); //abcd
             RunTest02();//abcd
             RunTest03();//test
             RunTest04(); //0 1 2 3 4.....
             RunTest05();//()
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;

namespace UniRx.Examples
{
    
    
    public class Sample10_MainThreadDispatcherStart : MonoBehaviour
    {
    
    
        #region 属性

        #endregion

        #region 生命

        /// <summary>首次载入</summary>
        void Awake()
        {
    
    
            Sample10_MainThreadDispatcher mainThreadDispatcher = new Sample10_MainThreadDispatcher();
            mainThreadDispatcher.Run();
        }
     
        #endregion 



    }
}
using System;
using System.Collections;
using UnityEngine;

namespace UniRx.Examples
{
    
    
    public class Sample10_MainThreadDispatcher
    {
    
    
        public void Run()
        {
    
    

             RunTest01(); //abcd
             RunTest02();//abcd
             RunTest03();//test
             RunTest04(); //0 1 2 3 4.....
             RunTest05();//()
        }

        private void RunTest05()
        {
    
    
            // Observable.Start use ThreadPool Scheduler as default.
            // ObserveOnMainThread return to mainthread
            Observable
                .Start(() => Unit.Default) // asynchronous work
                .ObserveOnMainThread()
                .Subscribe(x => Debug.Log(x));
        }

        private void RunTest04()
        {
    
    
            // Timebased operations is run on MainThread(as default)
            // All timebased operation(Interval, Timer, Delay, Buffer, etc...)is single thread, thread safe!
            Observable
                .Interval(TimeSpan.FromSeconds(1))
                .Subscribe(x => Debug.Log(x));
        }


        private void RunTest03()
        {
    
    
            // Add Action to MainThreadDispatcher. Action is saved queue, run on next update.
            MainThreadDispatcher
                .Post(_ => Debug.Log("test"), null);
        }


        /// <summary>运行一次</summary>
        private void RunTest02()
        {
    
    
            // We have two way of run coroutine, FromCoroutine or StartCoroutine.
            // StartCoroutine is Unity primitive way and it's awaitable by yield return.
            // FromCoroutine is Rx, it's composable and cancellable by subscription's IDisposable.
            // FromCoroutine's overload can have return value, see:Sample05_ConvertFromCoroutine
            Observable
                .FromCoroutine(TestAsync)
                .Subscribe();
        }

        /// <summary>运行一次</summary>
        private void RunTest01()
        {
    
    
            // MainThreadDispatcher is heart of Rx and Unity integration (结合)

            // StartCoroutine can start coroutine besides MonoBehaviour.
            MainThreadDispatcher
                .StartCoroutine(TestAsync());
        }

        IEnumerator TestAsync()
        {
    
    
            Debug.Log("a");
            yield return new WaitForSeconds(1);


            Debug.Log("b");
            yield return new WaitForSeconds(1);


            Debug.Log("c");
            yield return new WaitForSeconds(1);


            Debug.Log("d");
        }
    }
}

サンプル11_ロガー

起動スクリプトが必要です
ここに画像の説明を挿入

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;

namespace UniRx.Examples
{
    
    
    public class Sample11_LoggerStart : MonoBehaviour
    {
    
    

        #region 生命



        /// <summary>首次载入且Go激活</summary>
        void Start()
        {
    
    
            Sample11_Logger logger = new Sample11_Logger();
            logger.ApplicationInitialize();
            logger.Run();   
        }

        #endregion 


    }
}




using System;
using System.Collections;
using UniRx.Diagnostics;
using UnityEngine;

namespace UniRx.Examples
{
    
    
    public class Sample11_Logger
    {
    
    
        // UniRx.Diagnostics.Logger
        // logger is threadsafe, define per class with name.
		static readonly UniRx.Diagnostics.Logger mLogger = new UniRx.Diagnostics.Logger("Sample11");

        // call once at applicationinit
        public void ApplicationInitialize()
        {
    
    
            // Log as Stream, UniRx.Diagnostics.ObservableLogger.Listener is IObservable<LogEntry>
            // You can subscribe and output to any place.
            // 初始化
            ObservableLogger.Listener.LogToUnityDebug();
            


            // for example, filter only Exception and upload to web.
            // (make custom sink(IObserver<EventEntry>) is better to use)
            // 没啥演示,没服务器来收集日志
            ObservableLogger.Listener
                .Where(x => x.LogType == LogType.Exception)
                .Subscribe(x =>
                {
    
    
                     //ObservableWWW.Post("", null).Subscribe();
                });
        }

        public void Run()
        {
    
    
            // Debug is write only DebugBuild.
            mLogger.Debug("Debug Message");

            // or other logging methods
            mLogger.Log("Message");
            mLogger.Exception(new Exception("test exception"));
        }
    }
}

サンプル12_反応性プロパティ

ここに画像の説明を挿入

// for uGUI(from 4.6)
#if !(UNITY_4_0 || UNITY_4_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_4 || UNITY_4_5)

using System;
using UnityEngine;
using UnityEngine.UI;

namespace UniRx.Examples
{
    
    
    public class Sample12_ReactiveProperty : MonoBehaviour
    {
    
    


        #region 字属
        [Header("场景节点")]
        public Button       MyButton;
        public Toggle       MyToggle;
        public InputField   MyInputField;
        public Text         MyText;
        public Slider       MySlider;

        // You can monitor/modifie in inspector by SpecializedReactiveProperty
        [Header("脚本变量")]
        public IntReactiveProperty IntRxProp = new IntReactiveProperty();
        Enemy enemy = new Enemy(1000);
        #endregion




        private void Awake()
        {
    
    
            Transform canvasTrans = transform.FindTop("Canvas");
            MyButton        = canvasTrans.GetComponentDeep<Button>("MyButton") ;
            MyToggle        = canvasTrans.GetComponentDeep<Toggle>("MyToggle");
            MyInputField    = canvasTrans.GetComponentDeep<InputField>("MyInputField");
            MyText          = canvasTrans.GetComponentDeep<Text>("MyText");
            MySlider        = canvasTrans.GetComponentDeep<Slider>("MySlider");
        }


        void Start()
        {
    
    

            InitButton();
            InitToggle();
            InitInputField();
            InitSlider();
            InitEnemy();
            InitInspector();
        }


        #region 辅助
        private void InitInspector()
        {
    
    
            // initial text:)  
            //滑动细节面板上的属性就会同步Text显示
            IntRxProp.SubscribeToText(MyText);
        }

        private void InitEnemy()
        {
    
    
          
            // from RxProp, CurrentHp changing(Button Click) is observable
            enemy.CurrentHp.SubscribeToText(MyText);
            enemy.IsDead.Where(isDead => isDead == true)
                .Subscribe(_ =>
                {
    
    
                    MyToggle.interactable = MyButton.interactable = false;
                });


        }

        private void InitInputField()
        {
    
    
            // input shows delay after 1 second
            //延时一秒,将输入框文字赋值文本组件
#if !(UNITY_4_6 || UNITY_4_7 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2)
            MyInputField.OnValueChangedAsObservable()
#else
                MyInputField.OnValueChangeAsObservable()
#endif
                .Where(x => x != null)
                .Delay(TimeSpan.FromSeconds(1))
                .SubscribeToText(MyText); // SubscribeToText is UniRx.UI Extension Method   
        }

        private void InitSlider()
        {
    
    
            // converting for human visibility
            //
            MySlider.OnValueChangedAsObservable()
                .SubscribeToText(MyText, x => Math.Round(x, 2).ToString());
        }

        private void InitToggle()
        {
    
    
            // Toggle, Input etc as Observable(OnValueChangedAsObservable is helper for provide isOn value on subscribe)
            // SubscribeToInteractable is UniRx.UI Extension Method, same as .interactable = x)
            //Toggle控制Button的Interactable
            MyToggle.OnValueChangedAsObservable().SubscribeToInteractable(MyButton);
        }

        private void InitButton()
        {
    
    
            // UnityEvent as Observable
            // (shortcut, MyButton.OnClickAsObservable())
            // 点按钮扣99
            MyButton.onClick.AsObservable().Subscribe(_ => enemy.CurrentHp.Value -= 99);
        }
        #endregion

    }


    #region 内部类
    // Reactive Notification Model
    public class Enemy
    {
    
    
        public IReactiveProperty<long> CurrentHp {
    
     get; private set; }

        public IReadOnlyReactiveProperty<bool> IsDead {
    
     get; private set; }

        public Enemy(int initialHp)
        {
    
    
            // Declarative Property
            CurrentHp = new ReactiveProperty<long>(initialHp);
            IsDead = CurrentHp.Select(x => x <= 0).ToReactiveProperty();
        }
    }
    #endregion

}

#endif

サンプル13_ToDoApp

バグ

ノードが失われています。ToDoList
ノードのサイズが下のボタンを覆っているため (この時点ではマスクがありません)、アイテムを追加した後、下のボタンは無効になります。

本体

ここに画像の説明を挿入

// for uGUI(from 4.6)
#if !(UNITY_4_0 || UNITY_4_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_4 || UNITY_4_5)

using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.EventSystems;

namespace UniRx.Examples
{
    
    
    public class Sample13_ToDoApp : MonoBehaviour
    {
    
    

        [Header("场景节点")]
        public Text Title;
        public Button AddBtn;
        public Button ClearBtn;
        public InputField ToDoInput;
        public GameObject SampleItemPrefab;
        public GameObject TodoLst;

        [Header("脚本变量")]
        ReactiveCollection<GameObject> toDos = new ReactiveCollection<GameObject>();


        private void Awake()
        {
    
    
            Transform canvasTrans = transform.FindTop("Canvas");
            Title = canvasTrans.GetComponentDeep<Text>("Title");
            AddBtn = canvasTrans.GetComponentDeep<Button>("AddBtn");
            ClearBtn = canvasTrans.GetComponentDeep<Button>("ClearBtn");
            ToDoInput = canvasTrans.GetComponentDeep<InputField>("ToDoInput");
            TodoLst = canvasTrans.FindChildDeep("TodoLst").gameObject;
            toDos = new ReactiveCollection<GameObject>();
        }
        void Start()
        {
    
    
            //两个按钮
            {
    
     
                // merge Button click and push enter key on input field.
                //增加按钮或输入框回车,同功能
                var submit = Observable.Merge(
                    AddBtn.OnClickAsObservable().Select( _ => ToDoInput.text),
                    ToDoInput.OnEndEditAsObservable().Where( _ => Input.GetKeyDown(KeyCode.Return)));

                // 增加
                submit
                    .Where(x => x != "")
                    .Subscribe(x =>{
    
    
                        ToDoInput.text = ""; // clear input field
                        var item = Instantiate(SampleItemPrefab) as GameObject;
                        (item.GetComponentInChildren(typeof(Text)) as Text).text = x;
                        toDos.Add(item);});

                // 清空已经办好的(勾选了的)
                ClearBtn
                    .OnClickAsObservable()
                    .Subscribe(_ => {
    
    
                        var removeTargets = toDos.Where(x => x.GetComponent<Toggle>().isOn).ToArray();
                        foreach (var item in removeTargets)
                        {
    
    
                            toDos.Remove(item);
                        }});            
            }


            //对Item的增删改
            {
    
     
                //变化是改变抬头上的文本(数量变化)
                toDos
                    .ObserveCountChanged()
                    .Subscribe(x => Title.text = "TODO App, ItemCount:" + x);

                //增加的将该变量设置父节点
                toDos
                    .ObserveAdd()
                    .Subscribe(x =>{
    
    x.Value.transform.SetParent(TodoLst.transform, false);});

                //清空时销毁
                toDos
                    .ObserveRemove()
                    .Subscribe(x =>{
    
    GameObject.Destroy(x.Value);});            
            }
        }
    }
}

#endif

UIKitExample/EventExample

登録イベント (送信、監視)
オブザーバー (受信、呼び出し、メソッドを呼び出すことができます。ここでの例はパラメーター「Hello World!」と呼ばれます)
ここに画像の説明を挿入

コルーチン

内部のクラスが失われ、エラーが報告されます

うp主のファン登録に相当する受け取り

using UnityEngine;

namespace QFramework
{
    
    


	public class EventGet : MonoBehaviour 
	{
    
    
		void Start () 
		{
    
    
			QEventSystem.RegisterEvent(TestEvent.TestOne,GetEvent);
		}

		void GetEvent(int key, params object[] obj)
		{
    
    
			switch (key)
			{
    
    
				case (int)TestEvent.TestOne:
					this.LogInfo(obj[0].ToString());
					break;
			}
		}
	}
}

送信、アップマスターに相当

using UnityEngine;
using UniRx;

namespace QFramework
{
    
    
    public class EventTest : MonoBehaviour
    {
    
           
        void Start()
        {
    
    
            Observable
                .EveryUpdate()
                .Subscribe( _ => 
                    QEventSystem.SendEvent(TestEvent.TestOne,"Hello World!"));
        }
    }
}

列挙する

using UnityEngine;

namespace QFramework
{
    
    
    public enum TestEvent
    {
    
    
        TestOne
    }
}

UIKitExample/ManagerOfManagersExample

指定された ID を実行するためのロジックはありません。ForwardMsg(tmpMsg) のコメントを解除する必要があります。タスク リストに入れておきます。
ここに画像の説明を挿入

結果を得ることができる
ここに画像の説明を挿入

namespace QFramework
{
    
    
	using UnityEngine;

	[QMonoSingletonPath("[Event]/QMsgCenter")]
	public partial class QMsgCenter : MonoBehaviour, ISingleton
	{
    
    
		......
		public void SendMsg(QMsg tmpMsg)
		{
    
    
			......
   			 //	TODO case (int)PlayerEvent.Run: 
			 ForwardMsg(tmpMsg);
		}

プレーヤー、ファンに相当

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace QFramework.Example
{
    
    
	public class Player : QMonoBehaviour
	{
    
    
		
		private IManager mManager;

		// Use this for initialization
		void Start()
		{
    
    
			RegisterEvent(PlayerEvent.Run);
		}

		// Update is called once per frame

		protected override void ProcessMsg(int eventId, QMsg msg)
		{
    
    
			switch (eventId)
			{
    
    
				case (int)PlayerEvent.Run: //查TODO ,去取消注释才有结果		
					Log.I("收到跑的消息了");
					break;
			}
		}

		public override IManager Manager
		{
    
    
			get {
    
     return GameManager.Instance ; }
		}



		#region 内部类
		public class GameManager : QMgrBehaviour, ISingleton
        {
    
    
            public override int ManagerId
            {
    
    
                get {
    
     return QMgrID.Game; }
            }


            public static GameManager Instance
            {
    
    
                get {
    
     return MonoSingletonProperty<GameManager>.Instance; }
            }

            public void OnSingletonInit()
            {
    
    

            }
        }

		#endregion

    }


}

マネージャーのマネージャーの例

using System.Collections;
using System.Collections.Generic;
using QFramework;
using UnityEngine;

namespace QFramework.Example
{
    
    
	
	public class ManagerOfManagersExample : QMonoBehaviour
	{
    
    
		public override IManager Manager
		{
    
    
			get {
    
     return UIManager.Instance; }
		}


		private void Update()
		{
    
    
			if (Input.GetMouseButtonDown(0))
			{
    
    

				Debug.Log("单击");	
				SendEvent(PlayerEvent.Run);
			}
		}
	}
}

ForwardMsg のソース

using System.Collections;
using System.Collections.Generic;
using QFramework.Example;
using UnityEngine;


namespace QFramework
{
    
    
	/// <summary>管所有Mgr</summary>
	public partial class QMsgCenter 
	{
    
    

		public static void ForwardMsg(QMsg msg)
		{
    
    
			switch (msg.ManagerID)
			{
    
    
				case QMgrID.Game:
					Player.GameManager.Instance.SendMsg(msg);//根据msg.ManagerID,给mgr发消息
                    break;
			}
		}

	}
}

列挙する

namespace QFramework.Example
{
    
    

    public enum PlayerEvent
    {
    
    
        Start = QMgrID.Game,
        Run,
        End
    }
}

UIKitExample/UIExample

全体的な動作を確認するために見てください

ここに画像の説明を挿入

Bug VS がブレークポイントを削除した後も、エラー リストはまだ保存されています。

modify は、AB パッケージからフォルダーを作成し、スクリプトのすべてのコンテンツを独自のライブラリに転送する拡張メソッドです。

Logのdllを使用するのでコピーするだけ

ResKitサンプル/オーディオ

AB 名は元のファイル名を直接コピーし、システムは自動的に小文字に変更します。
名前の形式を見て、必須の名前付け形式があるのか​​と思いましたが、実際には単に人々の利益のためです。詳細については、Assets/QFrameworkData/QAssets.cs を参照してください。
ここに画像の説明を挿入
ここに画像の説明を挿入

using UnityEngine;
using QFramework;


public class AudioTest : MonoBehaviour 
{
    
    
    string mMusicName = "resources://JYJ - BACK SEAT";
    //string mMusicName = "BackGroundMusic";
    string mSoundName = "TestSound";


    private void Start()
    {
    
    
        QFramework.ResMgr.Init();

        // 
       // AudioManager.Instance.SendMsg(new AudioSoundMsg(mSoundName));

        AudioManager.Instance.SendMsg(new AudioMusicMsg(mMusicName));

        AudioManager.Instance.SendMsg(new AudioStopMusicMsg());

       // AudioManager.PlaySound(mSoundName);
        
        AudioManager.PlayMusic(mMusicName);
    }
}

これを行う理由は、RealFrame が同様のことを行っており、比較して統合したいためです。

ResKitExample/プール

ここに画像の説明を挿入
ここに画像の説明を挿入

using UnityEngine;

namespace QFramework
{
    
    
    public class CallPool : MonoBehaviour
    {
    
    

        
        private void Start()
        {
    
    
            #region SimpleObjectPool


            "====SimpleObjectPool".LogInfo();
            var pool = new SimpleObjectPool<Fish>(() => new Fish(),initCount:50);
            pool.CurCount.LogInfo();
           //
            var fish = pool.Allocate();
            pool.CurCount.LogInfo();
            //
            pool.Recycle(fish);
            pool.CurCount.LogInfo();
            #endregion



            #region SafeObjectPool


            "====SafeObjectPool".LogInfo();
            SafeObjectPool<Bullet>.Instance.Init(50,25);
            var bullet = Bullet.Allocate();
            SafeObjectPool<Bullet>.Instance.CurCount.LogInfo();
            //
            bullet.Recycle2Cache();
            SafeObjectPool<Bullet>.Instance.CurCount.LogInfo();
            #endregion
        }



        #region 内部类


        class Fish
        {
    
    

        }


        class Bullet :IPoolable,IPoolType
        {
    
    

            public  bool IsRecycled {
    
     get; set; }


            public static Bullet Allocate()
            {
    
    
                return SafeObjectPool<Bullet>.Instance.Allocate();
            }
            public void OnRecycled()
            {
    
    
                "回收了".LogInfo();
            }



            
            public void Recycle2Cache()
            {
    
    
                SafeObjectPool<Bullet>.Instance.Recycle(this);
            }
        }
        #endregion  


    }
}

ResKitExample/RefCounter

ここに画像の説明を挿入

using UnityEngine;

namespace QFramework.Course
{
    
    
    public class RefCounterExample : MonoBehaviour
    {
    
    
        void Start()
        {
    
    
            var room = new Room();

            room.EnterPeople();
            room.EnterPeople();
            room.EnterPeople();
            //
            room.LeavePeople();
            room.LeavePeople();
            room.LeavePeople();
        }
    }



    #region 内部类
    public class Light
    {
    
    
        public void SwitchOn()
        {
    
    
            Log.E("开灯");
        }

        public void SwitchOff()
        {
    
    
            Log.E("关灯");
        }
    }

    public class Room : SimpleRC
    {
    
    
        private Light mLight = new Light();

        public void EnterPeople()
        {
    
    
            Log.E("进入人了");

            if (RefCount == 0)
            {
    
    
                mLight.SwitchOn();
            }

            Retain();
        }

        public void LeavePeople()
        {
    
    
            Release();

            Log.E("人出来了");
        }

    
        protected override void OnZeroRef()
        {
    
    
            mLight.SwitchOff();
        }
    }
    #endregion
}

ResKitExample/ResKit/LoadAssetBundleResExample

using UnityEngine;
using UnityEngine.UI;

namespace QFramework.Example
{
    
    
	public class AssetBundleResExample : MonoBehaviour
	{
    
    
		private ResLoader mResLoader = ResLoader.Allocate();

		public RawImage RawImage;

		private void Awake()
		{
    
    
			ResMgr.Init();
		}

		// Use this for initialization
		void Start()
		{
    
    
			Transform canvasTrans = transform.FindTop("Canvas");
			RawImage rawImage = canvasTrans.Find("RawImage").GetComponent<RawImage>();
			RawImage.texture = mResLoader.LoadSync<Texture2D>("TestImage");
			
			// 通过下边方式也一样
			RawImage.texture = mResLoader.LoadSync<Texture2D>("testimage_png","TestImage");
		}

		private void OnDestroy()
		{
    
    
			mResLoader.Recycle2Cache(); //回收到缓存
            mResLoader = null;
		}
	}
}

ResKitExample/ResKit/LoadAssetBundleResExample

バグ、ここのパッケージングが機能しません

ここに画像の説明を挿入
それで、最初に私がやったことは、画像をResourcesに置き、それを取得するパスにResources/を追加することでした(最後のものはResources.Load(string path)です)。
ここに画像の説明を挿入

ただし、最初のフォルダーにはリソースがないため、引き続き探します。

時計 ResKit のパッケージ化

01 ResMgr.Init() のメソッドでファイル名を見つけ (図 1、パッケージ化された画像を直接切り取った)、その後、この方法でパッケージ化されていることがわかりました (図 2) 02 以前の問題は、mResLoader.LoadSync で ResDatas.GetAssetData が見つかり、その中の 2 つの静的リストが空でした。つまり、asset_bindle_config はパッケージ化時に生成されないため、asset_bindle_config から何もロードされませんでした。
真ん中
ここに画像の説明を挿入
ここに画像の説明を挿入

using UnityEngine;
using UnityEngine.UI;

namespace QFramework.Example
{
    
    
	public class AssetBundleResExample : MonoBehaviour
	{
    
    
		private ResLoader mResLoader = ResLoader.Allocate();
		public RawImage RawImage;

		private void Awake()
		{
    
    
			ResMgr.Init();
		}

		// Use this for initialization
		void Start()
		{
    
    
			Transform canvasTrans = transform.FindTop("Canvas");
            RawImage = canvasTrans.Find("RawImage").GetComponent<RawImage>();
            //底层能够走的方法 ResDatas.GetAssetData
            //RawImage.texture = mResLoader.LoadSync<Texture2D>("TestImage");

            // 通过下边方式也一样
            RawImage.texture = mResLoader.LoadSync<Texture2D>("testimage_png","TestImage");
		}



        private void OnDestroy()
		{
    
    
			mResLoader.Recycle2Cache(); //回收到缓存
            mResLoader = null;
		}
	}
}

ここに画像の説明を挿入

ResKitExample/ResKit/LoadResourcesResExample

上記と同じロジックで、「resources://」または「Resources/」を追加して他の論理ブランチに移動します。

using UnityEngine;
using UnityEngine.UI;

namespace QFramework.Example
{
    
    
	public class LoadResourcesResExample : MonoBehaviour
	{
    
    
		public RawImage RawImage;
		
		private ResLoader mResLoader = ResLoader.Allocate();
		
		// Use this for initialization
		private void Start()
		{
    
    
			RawImage.texture = mResLoader.LoadSync<Texture2D>("resources://TestTexture");
		}

		private void OnDestroy()
		{
    
    
			Log.I("On Destroy ");
			mResLoader.Recycle2Cache();
			mResLoader = null;
		}
	}
}

ここに画像の説明を挿入

ResKitExample/ResKit

bug 空

実際の内容は、上記 2 つの例をまとめたものです。
しかし、3 番目のアセットは null ("assetobj_prefab", "AssetObj") を報告します。

            GameObject prefab = mResLoader.LoadSync<GameObject>("assetobj_prefab", "AssetObj");
            prefab.Instantiate()
				.Name("这是使用通过 AssetName  和 AssetBundle 加载的对象");

ここに画像の説明を挿入

時計の比較

バックトラッキングでは何が問題なのかわからないため、別のプレハブ、はい、UI オブジェクトをロードしてみてください
ここに画像の説明を挿入

            //回溯看不出哪里错了,所以试试加载其它预制体
            GameObject prefab = mResLoader.LoadSync<GameObject>("uitestunirx_prefab", "UITestUniRx");
            prefab.Instantiate()
				.Name("这是使用通过 AssetName  和 AssetBundle 加载的对象");

見て比較するとラベルが少ないことがわかります

でもテストが終わったらそれが理由ではない
ここに画像の説明を挿入

前のコードをコメントアウトしてみてください

LoadSync の方法には、リソース名を直接指定する方法、パッケージ名 + ファイル名を指定する方法の 2 つがあります。同じリソースに対して、使用できる LoadSync は 1 つだけです。どちらを先に使用しても、もう一方は空になります。
次の記述は、コードの 2 番目のブロック mResLoader.LoadSync("AssetObj") を報告します。


			GameObject prefab = mResLoader.LoadSync<GameObject>("assetobj_prefab", "AssetObj");
            //回溯看不出哪里错了,所以试试加载其它预制体	,最终发现是QFramework标签
           // GameObject prefab = mResLoader.LoadSync<GameObject>("uitestunirx_prefab", "UITestUniRx");
            prefab.Instantiate()
				.Name("这是使用通过 AssetName  和 AssetBundle 加载的对象");

            mResLoader.LoadSync<GameObject>("AssetObj")
				.Instantiate()
				.Name("这是使用通过 AssetName 加载的对象");

合計を変更する

ここに画像の説明を挿入


using System.IO;
using UnityEngine;

namespace QFramework.Example
{
    
    
	public class ResKitExample : MonoBehaviour
	{
    
    
		private ResLoader mResLoader = ResLoader.Allocate();


        private void Awake()
        {
    
    
			ResMgr.Init();		
        }
        private void Start()
		{
    
    
			

			mResLoader.LoadSync<GameObject>("resources://GameObject")
				.Instantiate()
				.Name("这是使用 ResKit 加载的对象");

            if (true)//二选一,选A,B就报空的那种
            {
    
    
                mResLoader.LoadSync<GameObject>("assetobj_prefab", "AssetObj")
                    //回溯看不出哪里错了,所以试试加载其它预制体	,最终发现是QFramework标签
                    // mResLoader.LoadSync<GameObject>("uitestunirx_prefab", "UITestUniRx");
                    .Instantiate()
                    .Name("这是使用通过 AssetName  和 AssetBundle 加载的对象");
            }
            else
            {
    
    
                mResLoader.LoadSync<GameObject>("AssetObj")
                    .Instantiate()
                    .Name("这是使用通过 AssetName 加载的对象");
            }



        }

		

		private void OnDestroy()
		{
    
    
			mResLoader.Recycle2Cache();
			mResLoader = null;
		}
	}
}

ResKitExample/SpriteAtlas

ここに画像の説明を挿入

using System.Collections;
using UnityEngine;
using UnityEngine.U2D;
using UnityEngine.UI;

namespace QFramework
{
    
    
	/// <inheritdoc />
	/// <summary>
	/// 参考:http://www.cnblogs.com/TheChenLin/p/9763710.html
	/// </summary>
	public class TestSpriteAtlas : MonoBehaviour
	{
    
    
		[SerializeField] private Image mImage;

		// Use this for initialization
		private IEnumerator Start()
		{
    
    
			Transform canvasTrans = transform.FindTop("Canvas");
            mImage=canvasTrans.GetComponentInChildren<Image>();
            var loader = ResLoader.Allocate();
			ResMgr.Init();

#if UNITY_2017_1_OR_NEWER
			var spriteAtlas = loader.LoadSync<SpriteAtlas>("spriteatlas");
			var square = spriteAtlas.GetSprite("Square");
			Log.I(spriteAtlas.spriteCount);

			mImage.sprite = square;
#endif

			yield return new WaitForSeconds(5.0f);

			loader.Recycle2Cache();
			loader = null;
		}
	}
}

UIKitExample/UIExample

A=>B は、A が B を開けることができることを意味します。多くのスクリプトがあります。プロジェクトを参照してください。
1=>2
2=>3
2=>4
3=>5
ここに画像の説明を挿入

star 中括弧の書き方

ここにコードスニペットを挿入

UniRx シリーズのチュートリアルを監視するためのスクリプト

Wang Xiaoti/UniRx 集中
UniRx シリーズのチュートリアル
は長いため、
再利用に適した静的クラスを投稿するかどうかを検討してください

UniRxExtensions

/****************************************************
    文件:UniRxExtensions.cs
	作者:lenovo
    邮箱: 
    日期:2023/6/6 17:55:35
	功能:
    来源:https://www.bilibili.com/video/BV1EB4y1z7nY/?spm_id_from=333.337.search-card.all.click&vd_source=54db9dcba32c4988ccd3eddc7070f140
*****************************************************/

using System;
using System.Collections;
using System.Collections.Generic;
using UniRx;
using UnityEngine;
using Random = UnityEngine.Random;
//需要这两个
using UniRx;
using UniRx.Async;
using UniRx.Triggers;


/*
 *  AddTo,同生共死
 *  Subject,一个参数,多个用元组
 *  Where==if,过滤
 *  First,第一个才有效
 *  括号里面的方法可以写 _=> ()=> 形参(比如unit,list)=>
 *  buffer,事件缓存,事件存一块可以一起输出
 *  01 go.UpdateAsObservable() ;02 Observable.EveryUpdate().AddTo(this) 。01的好处是自动AddTo(go)上
 *  x协程返回IEnumerator,无法适应TryCatch
 *  ReactiveProperty,常用于UI的MVC
 */

public static partial class UniRxExtensions
{
    
    

    #region 生命


    /// <summary>首次载入且Go激活</summary>
    public static void ExampleMonoBehaviour(this MonoBehaviour mono)
    {
    
    
        if (false)
        {
    
     
            DoAfterTime(mono);
            DoUpdate(mono);
            DoTimer(mono);        
        }

    }

    public static void ExampleGameObject(this GameObject go, MonoBehaviour mono)
    {
    
    
        if (false)
        {
    
     
            go.DoWhenHide();
            go.DoWhenDestroy();
            go.DoWhenMouseDown();
            go.DoDelayMouseDown(2f);
            go.DoDelayFrameMouseDown(2);
            go.DoDelayMouseDownByUpdate(2f);
            go.DoWhenCollide();
            go.DoUpdate();
            go.DoTimer(1f);
            IDisposable disposable = go.DoUpdateDispose();//ifxxx,操作disposable
        }

       

    }

    public static void BindInt(this ReactiveProperty<int> num,MonoBehaviour mono) 
    {
    
    
        num   
            .Skip(1)//跳过第一次的赋值初始化阶段
            .Subscribe(_ =>Debug.Log("ValueChange"))
            .AddTo(mono);
    }


    #endregion


    #region 辅助
    public static void DoWhenHide(this GameObject go)
    {
    
    
        go
          .OnDisableAsObservable()
          .Subscribe(_ => Debug.Log("DoWhenHide"))
          .AddTo(go);
    }

    public static void DoWhenDestroy(this GameObject go)
    {
    
    
        go
          .OnDestroyAsObservable()
          .Subscribe(_ => Debug.Log("DoWhenHide"))
          .AddTo(go);
    }

    public static void DoWhenMouseDown(this GameObject go)
    {
    
    
        go
          .OnMouseDownAsObservable()
          .Subscribe(_ => Debug.Log("DoWhenMouseDown"))
          .AddTo(go);
    }

    public static void DoDelayMouseDown(this GameObject go, float delay)
    {
    
    
        go
          .OnMouseDownAsObservable()
          .Delay(TimeSpan.FromSeconds(delay))
          .Subscribe(_ => Debug.Log("DoDelayMouseDown"))
          .AddTo(go);
    }
    public static void DoDelayFrameMouseDown(this GameObject go, int cnt)
    {
    
    
        go
          .OnMouseDownAsObservable()
          .DelayFrame( cnt )
          .Subscribe(_ => Debug.Log("DoDelayMouseDown"))
          .AddTo(go);
    }

    /// <summary>一般用于if(xxx){disposable.Dispose();}</summary>
    public static IDisposable DoUpdateDispose(this GameObject go)
    {
    
    
        IDisposable disposable = go
           .UpdateAsObservable()
           .Subscribe(_ =>Debug.Log("DoUpdateDispose"))
           .AddTo(go);

        return disposable;
    }

    /// <summary>一般用于if(xxx){disposable.Dispose();}</summary>
    public static IDisposable DoUpdateDispose(this GameObject go,CompositeDisposable compositeDisposable)
    {
    
    
        IDisposable disposable = go
           .UpdateAsObservable()
           .Subscribe(_ => Debug.Log("DoUpdateDispose"))
           .AddTo(compositeDisposable);

        return disposable;
    }

    public static void DoDelayMouseDownByUpdate(this GameObject go, float delay)
    {
    
    
        go
          .UpdateAsObservable()
          .Where( _=>
          {
    
    
              if (Input.GetMouseButtonDown(0))
              {
    
    
                  Debug.Log("DoDelayMouseDownByUpdate点击鼠标左键");
                  return true;
              }
              return false;
          })
          .Delay(TimeSpan.FromSeconds(delay))
          .Subscribe(_ => Debug.Log("DoDelayMouseDownByUpdate"))
          .AddTo(go);
    }

    public static void DoWhenCollide(this GameObject go)
    {
    
    
        go
          .OnCollisionEnterAsObservable()
          .Subscribe(_ => Debug.Log("DoWhenCollide"))
          .AddTo(go);
    }


    /// <summary>每隔2秒</summary>
    public static void DoTimer(this MonoBehaviour mono)
    {
    
    
        Observable
            .EveryUpdate()
            .Sample(TimeSpan.FromSeconds(2f))
            .Subscribe(_ => Debug.Log("DoTimer"))
            .AddTo(mono);
    }



    public static void DoUpdate(this MonoBehaviour mono)
    {
    
    
        Observable
            .EveryUpdate()
            .Subscribe(_ => Debug.Log("DoUpdate"))
            .AddTo(mono);
    }

    public static void DoUpdate(this GameObject go)
    {
    
    
        go
            .UpdateAsObservable()
            .Subscribe(_ => Debug.Log("DoUpdate"))
            .AddTo(go);
    }

    public static void DoTimer(this GameObject go,float time)
    {
    
    
        go
            .UpdateAsObservable()
            .Sample(TimeSpan.FromSeconds(time))
            .Subscribe(_ => Debug.Log("DoTimer"))
            .AddTo(go);
    }

    public static void DoAfterTime(this MonoBehaviour mono)
    {
    
    
        Observable
            .Timer(TimeSpan.FromSeconds(2f))
            .Subscribe(_ => Debug.Log("DoAfterTime"))
            .AddTo(mono);
    }
    #endregion

    #region 系统

    #endregion

    #region 辅助

    #endregion

}




UniRxExtensions.FirstLastTake

/****************************************************
    文件:UniRxExtensions.FirstLastTake.cs
	作者:lenovo
    邮箱: 
    日期:2023/6/7 17:48:10
	功能:
*****************************************************/

using System;
using System.Collections;
using System.Collections.Generic;
using UniRx;
using UniRx.Triggers;
using UnityEngine;
using UnityEngine.Events;
using Random = UnityEngine.Random;


public static partial class UniRxExtensions
{
    
    
    public static void ExampleStart_Keyword(GameObject go)
    {
    
    
        //go.DoFirst();
        //go.DoLast();
        //go.DoTake(3);
        //go.DoBuffer(60 * 25);
        //go.DoMerge();
        //go.DoReturn();
        go.Do();
    }

    public static void DoFirst(this GameObject go)
    {
    
    
        go
            .UpdateAsObservable()
            .Where(_ => Input.GetMouseButtonDown(0))
            .First(unit => true)
            .Subscribe(_ => Debug.Log("DoFirst"))
            .AddTo(go);
    }

    public static void DoLast(this GameObject go)
    {
    
    
        go
            .UpdateAsObservable()
            .Where(unit => Input.GetMouseButtonDown(0))
            .Last(unit => true)
            .Subscribe(_ => Debug.Log("DoLast"))
            .AddTo(go);
    }

    public static void DoTake(this GameObject go, int cnt)
    {
    
    
        go
            .UpdateAsObservable()
            .Where(unit => Input.GetMouseButtonDown(0))
            .Take(cnt)
            .Subscribe(_ => Debug.Log("DoTake"))
            .AddTo(go);
    }


    /// <summary>每cnt帧的时间输出一次</summary>
    public static void DoBuffer(this GameObject go, int cnt)
    {
    
    
        go
            .UpdateAsObservable()
            .Buffer(cnt)
            .Subscribe(_ => Debug.Log("DoBuffer"))
            .AddTo(go);

    }

    public static void DoMerge(this GameObject go)
    {
    
    
        IObservable<Unit> disposable0 = go.UpdateAsObservable()
            .Where(_ => Input.GetMouseButtonDown(0));

        IObservable<Unit> disposable1 = go.UpdateAsObservable()
            .Where(_ => Input.GetMouseButtonDown(1));

        disposable0.Merge(disposable1)
            .Subscribe(_ => Debug.Log("Mereg单击"))
            .AddTo(go);

        //相当于
        //IObservable<Unit> disposable3 = go.UpdateAsObservable()
        //  .Where(_ => Input.GetMouseButtonDown(0)  || Input.GetMouseButtonDown(1));

    }
    public static void DoReturn(this GameObject obj)
    {
    
    

        Debug.Log("DoReturn的前面");
        Observable
            .Return("DoReturn")
            .Subscribe(Debug.Log)
            .AddTo(obj);


    }

    /// <summary>提前筛选</summary> 
    public static void Do(this GameObject go)
    {
    
    
        go.UpdateAsObservable()
            .Do(_ => Debug.Log("Do"))
            .Subscribe(_ => Debug.Log("Do的Subscribe"))//不订阅就不会带引Do
            .AddTo(go);

    }


    /// <summary>与Where、Delay等结合使用</summary>
    public static void DoWithDo(this GameObject go)
    {
    
    
        go.UpdateAsObservable()
            .Where(_ => Input.GetMouseButtonDown(0))
            .Do(_ => Debug.Log("DoWhereDo按下了鼠标"))
            .Delay(TimeSpan.FromSeconds(2f))
            .Do(_ => Debug.Log("DoWhereDo延时2秒"))
            .Subscribe(_ => Debug.Log("DoWhereDo的Subscribe"))//不订阅就不会带引Do
            .AddTo(go);

    }


    public static void DoStartWith(this GameObject go)
    {
    
    
        Observable
            .Return("baidu.com")
            .StartWith("https://")
            .Subscribe(_ => Debug.Log("DoStartWith的Subscribe"))
            .AddTo(go);
    }

}




UniRxExtensionsMonoBehavior.Start

/****************************************************
    文件:UniRxExtensionsMonoBehaviour.Start.cs
	作者:lenovo
    邮箱: 
    日期:2023/6/8 22:40:42
	功能:生命函数放这里
*****************************************************/

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;
 

    public partial class UniRxExtensionsMonoBehaviour : MonoBehaviour
    {
    
    


        #region 生命


        /// <summary>首次载入且Go激活</summary>
        void Start()
        {
    
    
            
            //UniRxExtensions.ExampleMonoBehaviour(this);
            //UniRxExtensions.ExampleGameObject(gameObject,this);
            //UniRxExtensions.ExampleStart_Keyword(gameObject);
            //Example_Scene();
            //Example_ToObservable();
            ExampleStart_Message();

        }


        #endregion 



    }




UniRxExtensionsMonoBehaviour.Message_ReactiveProperty

/****************************************************
    文件:UniRxExtensionsMonoBehaviour.Message_ReactiveProperty.cs
	作者:lenovo
    邮箱: 
    日期:2023/6/7 17:48:10
	功能:消息机制
*****************************************************/

using System;
using System.Collections;
using System.Collections.Generic;
using UniRx;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using Random = UnityEngine.Random;


public  partial class UniRxExtensionsMonoBehaviour : MonoBehaviour
{
    
    

    int msgId = 0;
    ReactiveProperty<int> mReactiveProperty_Int = new ReactiveProperty<int>();
    ReactiveProperty<string> mReactiveProperty_String = new ReactiveProperty<string>();
    static int CurTextID = 3;
    
    
    public void ExampleStart_Message()
    {
    
    
        if (CurTextID == 1)
        {
    
     
            MainThreadingMsg_Receive();//注册
            MainThreadingMsg_Publish();//调用
            MainThreadingMsg_Publish();
            MainThreadingMsg_Publish();        
        }

        //
        if (CurTextID == 2)
        {
    
    
            ReactivePropertyChangeValue_Int();
            mReactiveProperty_Int.Value++;//调用
            mReactiveProperty_Int.Value++;
            mReactiveProperty_Int.Value++;
        }
        //
        if (CurTextID == 3)
        {
    
    
            //ReactivePropertyChangeValue_Int();//如果前面没注册
            ReactivePropertyChangeValue_String();
            mReactiveProperty_String.Value = Guid.NewGuid().ToString();
            mReactiveProperty_Int.Value++;
            mReactiveProperty_String.Value = Guid.NewGuid().ToString();
        }
    }




    #region 辅助

    void ReactivePropertyChangeValue_Int()
    {
    
    

        mReactiveProperty_Int
            .Skip(1)//跳过初始化
            .Subscribe(_=>Debug.Log("ReactivePropertyChangeValue_Int的Subscribe"))
            .AddTo(this);
    }


    void ReactivePropertyChangeValue_String()
    {
    
    

        mReactiveProperty_String
            .Skip(1)//跳过初始化
            .Subscribe(_ => Debug.Log("ReactivePropertyChangeValue_String的Subscribe"))
            .AddTo(this);
    }

    void ReactiveProperty_Merge()
    {
    
    
        mReactiveProperty_Int
           .Select(_ => Unit.Default)
           .Merge(mReactiveProperty_String.Select(_ => Unit.Default))
           .Subscribe(_=>Debug.Log("ReactiveProperty_Merge的Subscribe"))
           .AddTo(this);
    }

        /// <summary>多线程的消息,主线程下一帧Update收</summary>
        void MultiThreadingMsg_Receive()
    {
    
    
        MessageBroker.Default.Receive<MsgTmp>()
            .SubscribeOnMainThread()
            .Subscribe(msgTmp =>
                Debug.Log("MainThreadingMsg_Receive的Subscribe" + msgTmp.ToString()))
            .AddTo(this);

    }


    /// <summary>单线程的消息,即发即收</summary>
    void MainThreadingMsg_Publish()
    {
    
    
        MessageBroker.Default.Publish(new MsgTmp()
        {
    
    
            Idx = msgId,
            Val = "绝区零"+ msgId.ToString(),
           
        }) ;
        msgId++;
    }


     void MainThreadingMsg_Receive()
    {
    
    
        MessageBroker.Default.Receive<MsgTmp>()
           .Subscribe(msgTmp => 
            Debug.Log("MainThreadingMsg_Receive的Subscribe"+msgTmp.ToString()))
           .AddTo(this);
   
    }
    #endregion


    #region 内部类

    #endregion
    class MsgTmp
    {
    
     
        public int Idx {
    
     get; set; }
        public string Val {
    
     get; set; }


        public override string ToString()
        {
    
    
            string str = "MsgTmp";
            str += "\tIdx=" + Idx;
            str += "\tVal=" + Val;

            return str;
        }
    }
}





UniRxExtensionsMonoBehavior.Scene

/****************************************************
    文件:UniRxExtensionsMonoBehaviour.Scene.cs
	作者:lenovo
    邮箱: 
    日期:2023/6/6 18:6:33
	功能:
*****************************************************/

using System;
using System.Collections;
using System.Collections.Generic;
using UniRx;
using UnityEngine;
using Random = UnityEngine.Random;
 

public partial  class UniRxExtensionsMonoBehaviour : MonoBehaviour
{
    
    
    //意思是一部分放Start,一部分放Update,单用Dic好像搞错了,而且也不每关
    Dictionary<Action,Action> startUpdateDic=new Dictionary<Action,Action>(); 
    ReactiveProperty<int> numRp=new ReactiveProperty<int>(0);
    //
    IDisposable disposable;
    CompositeDisposable compositeDisposable;


    /// <summary>有场景交互部分</summary>
    private void Example_Scene()
    {
    
    


        gameObject.FindTop("Go").ExampleGameObject(this );
        numRp.BindInt(this);
        //
        GameObject Cube1 = gameObject.FindTop("Cube1");
        Cube1.DoWhenCollide();
        Cube1.DoWhenMouseDown();
        //
        disposable = gameObject.DoUpdateDispose();
        //
        disposable = gameObject.DoUpdateDispose(compositeDisposable);
        //
        disposable = gameObject.DoUpdateDispose(compositeDisposable);
        compositeDisposable.AddTo(gameObject);



    }

    private void Example_SceneUpdate()
    {
    
    
        if (Input.GetMouseButtonDown(0))
        {
    
    
            numRp.Value++;
            //
            disposable.Dispose();
            compositeDisposable.Dispose();
        }
    }


}





UniRxExtensions.ToObservable

/****************************************************
    文件:UniRxExtensions.ToObservable.cs
	作者:lenovo
    邮箱: 
    日期:2023/6/7 17:48:10
	功能:各种协程转Observable
*****************************************************/

using System;
using System.Collections;
using System.Collections.Generic;
using UniRx;
using UniRx.Triggers;
using UnityEngine;
using UnityEngine.Events;
using Random = UnityEngine.Random;


public partial  class UniRxExtensionsMonoBehaviour:MonoBehaviour
{
    
    
    void Example_ToObservable()
    {
    
    
        //IEnumeratorBody2Observable(enumerator());
        IEnumeratorBody2Observable_TryCatch(enumerator_TryCatch());

        //
        //IEnumerator2ObservableBody();
        //IEnumerator2ObservableBody_TryCatch();

    }



    #region 辅助

    /// <summary>转,但方法块在IEnumeratorBody</summary>
    void IEnumeratorBody2Observable( IEnumerator from)
    {
    
    
        from.ToObservable()
            .DoOnCompleted(()=>  Debug.Log("ConvertToObservable")) //这里_(报错)与()(不报错)是不同的
            .Subscribe( _ =>  Debug.Log("ConvertToObservable的Subscribe"))
            .AddTo(this);
    }

    /// <summary>转,但方法块在IEnumeratorBody</summary>
    void IEnumeratorBody2Observable_TryCatch(IEnumerator from)
    {
    
    
        from.ToObservable()
            .Catch<Unit, Exception>(expcetion =>
            {
    
    
                Debug.LogError("IEnumeratorBody2Observable_TryCatch的Catch<Unit, Exception>");
                return Observable.ReturnUnit();
            })
            .DoOnCompleted(() => Debug.Log("IEnumeratorBody2Observable_TryCatch的DoOnCompleted(该异常不会阻碍DoOnCompleted的打印)")) //这里_(报错)与()(不报错)是不同的
            .Subscribe(_ => Debug.Log("IEnumeratorBody2Observable_TryCatch的Subscribe"))
            .AddTo(this);
    }

    IEnumerator enumerator(Action onComplted = null)
    {
    
    

        Debug.Log("enumerator的前");
        yield return null;
        Debug.Log("enumerator的后");
        onComplted?.Invoke();
    }

    IEnumerator enumerator_TryCatch(Action onComplted = null)
    {
    
    
        int index = 0;
        Debug.Log("enumerator的前");
        yield return null;
        Debug.Log("enumerator的后");
        int[] arr = new int[0];
         index = arr[0];
    }


    IObservable<Unit> Obs()
    {
    
    
        IObservable<Unit> res = Observable.ReturnUnit();
        res.Do(_ => Debug.Log("IObservable<Unit>的前"))
            .DelayFrame(5)
            .Do(_ => Debug.Log("IObservable<Unit>的后"));

        return res;
    }


    /// <summary>IObservable<Unit>解决IEnumerator的异常捕捉</summary>
    IObservable<Unit> ObsTryCatch()
    {
    
    
        int index = 0;
        IObservable<Unit> res = Observable.ReturnUnit();
        res=res
            .Do(_ => Debug.Log("IObservable<Unit>的前"))
            .DelayFrame(5)
            .Do(_ => Debug.Log("IObservable<Unit>的后"))
            .Do( _=>
            {
    
    
                int[] arr = new int[0];
                index = arr[0];
            })
            .Catch<Unit,Exception>( expcetion=>               
            {
    
    

                Debug.LogError(" IObservable<Unit>的异常");
                return Observable.ReturnUnit();
            });

        return res;
    }


    /// <summary>转,但方法块在Observable</summary>
    void IEnumerator2ObservableBody()
    {
    
    
        Obs()
            .DoOnCompleted(() => Debug.Log("IObservable<Unit>的DoOnCompleted"))
            .Subscribe()
            .AddTo(this);

        StartCoroutine(Obs()
            .DoOnCompleted(() => 
                Debug.Log("IObservable<Unit>的StartCoroutine的DoOnCompleted"))
            .ToYieldInstruction());
    }

    /// <summary>转,但方法块在Observable</summary>
    void IEnumerator2ObservableBody_TryCatch()
    {
    
    
        ObsTryCatch()
            .DoOnCompleted(() => Debug.Log("IObservable<Unit>的TryCatch的DoOnCompleted"))
            .Subscribe()
            .AddTo(this);

        StartCoroutine(ObsTryCatch()
            .DoOnCompleted(() =>
                Debug.Log("IObservable<Unit>的TryCatch的StartCoroutine的DoOnCompleted"))
            .ToYieldInstruction());
    }
    #endregion



}




ブロガーの inspironxdeUniRx シリーズをご覧ください (UniRX EventHandler は注意深く逆アセンブルされており、入門に適しています)

12.UniRx配列(FromEvent、FromEventPattern、Where、WhenAll、Never)

ボゴ 2010 を視聴する (代表者のスピーチ、分かりやすい)

C# のデリゲーションと各国語シリーズのイベントの説明 (1)

【未完成】TodoListメモデモ

位置

それを中の TodoList フォルダーにドラッグし、圧縮パッケージを変更すると、完全なプロジェクト (QF を含む) になります。
ここに画像の説明を挿入

TodoItem

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;
 
namespace QFramework.TodoList
{
    
    
    public class TodoItem 
    {
    
    
          public bool Completed;
          public string Content;


        public TodoItem(bool v1, string v2)
        {
    
    
            this.Completed = v1;
            this.Content = v2;
        }
    }
}

Todoリスト

using QFramework;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;
 
namespace QFramework.TodoList
{
    
    
    public class TodoList
    {
    
    
        public List<TodoItem> mTodoItems;
    }
}

プレハブ

デモは簡単すぎるので、コードを直接貼り付けるだけです

        void CreatePrefab()
        {
    
    

            Transform UIRoot = transform.FindTop("UIRoot");//拖了一个QF的UIRoot预制体
            Transform Design = UIRoot.FindChildDeep("Design");
            Design.Show();
            //
            GameObject UITodoList = new GameObject("UITodoList");
            UITodoList.SetParent(Design);
            UITodoList.GetOrAddComponent<RectTransform>().Stretch();
            //
            GameObject text = new GameObject("Text");
            text.SetParent(UITodoList);
            text.GetOrAddComponent<RectTransform>().Stretch();
            text.AddComponent<Text>().alignment = TextAnchor.UpperCenter;
            text.AddComponent<UIMark>();

            // 根据上面拖出UITodoList这个预制体,右键两个@ResKit-AssetBundle Mark 、@UIKit-Create UICode,生成相关脚本
            //命名空间要改到,QFramework/Preferences
        }
    /// <summary>平铺开</summary>
    public static  RectTransform Stretch(this RectTransform rect)
    {
    
    
        rect.anchorMin = Vector2.zero;
        rect.anchorMax = Vector2.one;
        rect.sizeDelta = Vector2.zero;

        return rect;
    }

QFramework/設定エラーのバグ

バグ UIOKPanelData が存在しません

ここに画像の説明を挿入

//
これはクラス名なので変更してください

ここに画像の説明を挿入

01 エラーメッセージ

エラーを報告したため、名前空間 QFramework.Example を名前空間 QFramework.TodoList に手動で変更しました。図1
ここに画像の説明を挿入

02 スクリプトの場所

場所は、Assets/QFramework/Framework/0.Core/Editor/1.PackageManager/Window/PackageKitWindow.cs です。

	public class PackageKitWindow : QEditorWindow
	{
    
    
		[MenuItem(FrameworkMenuItems.Preferences, false, FrameworkMenuItemsPriorities.Preferences)]
		private static void Open()
		{
    
    

03 ショートカットキーリピート

Ctrl+E (%e) のショートカットキーを見つけてそれを繰り返し、QF を学ぶ前に個人ライブラリ Common にいくつか持っていって、個人のものを先にコメントアウトしました。

04 jsonファイルがありません

ここに画像の説明を挿入

05 TodoList 圧縮パッケージ内のスクリプトを見つけてコピーします

レポートが空です
これまでのところ、最新バージョンにジャンプします

バグ

これはsikアカデミーのビデオの下にある情報です。QFは少し古いため、いくつかの間違いがあります。使用はお勧めしませんが、サンプルとチュートリアル ドキュメントが含まれている最新バージョンを https://github.com/liangxiegame/QFramework からダウンロードすることをお勧めします。

----------------------------------------------------

----------------------------------------------------

おすすめ

転載: blog.csdn.net/weixin_39538253/article/details/130183319