From 501a6c3c0d5a1cfd6e09884d57e7a661a4b4115e Mon Sep 17 00:00:00 2001 From: neuecc Date: Fri, 3 Sep 2021 18:14:01 +0900 Subject: [PATCH] ui --- README.md | 101 ++ docs/assets.pptx | Bin 0 -> 36304 bytes sandbox/WpfApp/MainWindow.xaml.cs | 5 + .../Assets/Scenes/Button.prefab | 197 +++ .../Assets/Scenes/Button.prefab.meta | 7 + .../Assets/Scenes/SampleScene.unity | 1298 ++++++++++++++++- .../Assets/Scenes/SampleScript.cs | 78 + .../Assets/Scenes/SampleScript.cs.meta | 11 + 8 files changed, 1695 insertions(+), 2 deletions(-) create mode 100644 docs/assets.pptx create mode 100644 src/ObservableCollections.Unity/Assets/Scenes/Button.prefab create mode 100644 src/ObservableCollections.Unity/Assets/Scenes/Button.prefab.meta create mode 100644 src/ObservableCollections.Unity/Assets/Scenes/SampleScript.cs create mode 100644 src/ObservableCollections.Unity/Assets/Scenes/SampleScript.cs.meta diff --git a/README.md b/README.md index 86300ed..22185a8 100644 --- a/README.md +++ b/README.md @@ -1 +1,102 @@ # ObservableCollections +[![GitHub Actions](https://github.com/Cysharp/ObservableCollections/workflows/Build-Debug/badge.svg)](https://github.com/Cysharp/ObservableCollections/actions) [![Releases](https://img.shields.io/github/release/Cysharp/ObservableCollections.svg)](https://github.com/Cysharp/ObservableCollections/releases) + +ObservableCollections is a high performance observable collections(`ObservableList`, `ObservableDictionary`, `ObservableHashSet`, `ObservableQueue`, `ObservableStack`, `ObservableRingBuffer`, `ObservableFixedSizeRingBuffer`) with synchronized views. + +.NET has [`ObservableCollection`](https://docs.microsoft.com/en-us/dotnet/api/system.collections.objectmodel.observablecollection-1), however it has many lacks of features. + +It based `INotifyCollectionChanged`, `NotifyCollectionChangedEventHandler` and `NotifyCollectionChangedEventArgs`. There are no generics so everything boxed, allocate memory every time. Also `NotifyCollectionChangedEventArgs` holds all values to `IList` even if it is single value, this also causes allocations. `ObservableCollection` has no Range feature so a lot of wastage occurs when adding multiple values, because it is a single value notification. Also, it is not thread-safe is hard to do linkage with the notifier. + +ObservableCollections introduces generics version of `NotifyCollectionChangedEventHandler` and `NotifyCollectionChangedEventArgs`, it using latest C# features(`in`, `readonly ref struct`, `ReadOnlySpan`). + +```csharp +public delegate void NotifyCollectionChangedEventHandler(in NotifyCollectionChangedEventArgs e); + +public readonly ref struct NotifyCollectionChangedEventArgs +{ + public readonly NotifyCollectionChangedAction Action; + public readonly bool IsSingleItem; + public readonly T NewItem; + public readonly T OldItem; + public readonly ReadOnlySpan NewItems; + public readonly ReadOnlySpan OldItems; + public readonly int NewStartingIndex; + public readonly int OldStartingIndex; +} +``` + +Also, use the interface `IObservableCollection` instead of `INotifyCollectionChanged`. This is guaranteed to be thread-safe and can produce a View that is fully synchronized with the collection. + +```csharp +public interface IObservableCollection : IReadOnlyCollection +{ + event NotifyCollectionChangedEventHandler CollectionChanged; + object SyncRoot { get; } + ISynchronizedView CreateView(Func transform, bool reverse = false); +} + +// also exists SortedView +public static ISynchronizedView CreateSortedView(this IObservableCollection source, Func identitySelector, Func transform, IComparer comparer); +public static ISynchronizedView CreateSortedView(this IObservableCollection source, Func identitySelector, Func transform, IComparer viewComparer); +``` + +SynchronizedView helps to separate between Model and View (ViewModel). We will use ObservableCollections as the Model and generate SynchronizedView as the View (ViewModel). This architecture can be applied not only to WPF, but also to Blazor, Unity, etc. + +![image](https://user-images.githubusercontent.com/46207/131979264-2463403b-0fba-474b-8f49-277c2abe1b05.png) + +ObservableCollections has not just a simple list, there are many more data structures. `ObservableList`, `ObservableDictionary`, `ObservableHashSet`, `ObservableQueue`, `ObservableStack`, `ObservableRingBuffer`, `ObservableFixedSizeRingBuffer`. `RingBuffer`, especially `FixedSizeRingBuffer`, can be achieved with efficient performance when there is rotation (e.g., displaying up to 1000 logs, where old ones are deleted when new ones are added). Of course, the AddRange allows for efficient batch processing of large numbers of additions. + +Getting Started +--- +For .NET, use NuGet. For Unity, please read [Unity](#unity) section. + +PM> Install-Package [ObservableCollections](https://www.nuget.org/packages/ObservableCollections) + +create new `ObservableList`, `ObservableDictionary`, `ObservableHashSet`, `ObservableQueue`, `ObservableStack`, `ObservableRingBuffer`, `ObservableFixedSizeRingBuffer`. + + + + + + +```csharp +// WPF simple sample. + +ObservableList list; +public ISynchronizedView ItemsView { get; set; } + +public MainWindow() +{ + InitializeComponent(); + this.DataContext = this; + + list = new ObservableList(); + list.AddRange(new[] { 1, 10, 188 }); + ItemsView = list.CreateSortedView(x => x, x => x, comparer: Comparer.Default).WithINotifyCollectionChanged(); + + BindingOperations.EnableCollectionSynchronization(ItemsView, new object()); // for ui synchronization safety of viewmodel +} + +protected override void OnClosed(EventArgs e) +{ + ItemsView.Dispose(); +} +``` + +TODO: write more usage... + +View/SoretedView +--- + + +Collections +--- + + +Unity +--- + + +License +--- +This library is licensed under the MIT License. \ No newline at end of file diff --git a/docs/assets.pptx b/docs/assets.pptx new file mode 100644 index 0000000000000000000000000000000000000000..bc1016cf77434579e268f8868822f7439e869efd GIT binary patch literal 36304 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 R;05SQ3MBq8_x|zI{{e>q)Z_pF literal 0 HcmV?d00001 diff --git a/sandbox/WpfApp/MainWindow.xaml.cs b/sandbox/WpfApp/MainWindow.xaml.cs index 835e88d..00a66df 100644 --- a/sandbox/WpfApp/MainWindow.xaml.cs +++ b/sandbox/WpfApp/MainWindow.xaml.cs @@ -50,5 +50,10 @@ namespace WpfApp list.Add(adder++); }); } + + protected override void OnClosed(EventArgs e) + { + ItemsView.Dispose(); + } } } diff --git a/src/ObservableCollections.Unity/Assets/Scenes/Button.prefab b/src/ObservableCollections.Unity/Assets/Scenes/Button.prefab new file mode 100644 index 0000000..4a24eb9 --- /dev/null +++ b/src/ObservableCollections.Unity/Assets/Scenes/Button.prefab @@ -0,0 +1,197 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &1956618470265689906 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 618331874408718809} + - component: {fileID: 7969674051040476341} + - component: {fileID: 3304697755884386642} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &618331874408718809 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1956618470265689906} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 5255390928395226544} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &7969674051040476341 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1956618470265689906} + m_CullTransparentMesh: 0 +--- !u!114 &3304697755884386642 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1956618470265689906} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Button +--- !u!1 &8295906003645589311 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5255390928395226544} + - component: {fileID: 8560960181737511060} + - component: {fileID: 6330597562278295799} + - component: {fileID: 2332625603231720647} + m_Layer: 5 + m_Name: Button + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5255390928395226544 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8295906003645589311} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 618331874408718809} + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 160, y: 30} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &8560960181737511060 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8295906003645589311} + m_CullTransparentMesh: 0 +--- !u!114 &6330597562278295799 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8295906003645589311} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!114 &2332625603231720647 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8295906003645589311} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 6330597562278295799} + m_OnClick: + m_PersistentCalls: + m_Calls: [] diff --git a/src/ObservableCollections.Unity/Assets/Scenes/Button.prefab.meta b/src/ObservableCollections.Unity/Assets/Scenes/Button.prefab.meta new file mode 100644 index 0000000..85bad5e --- /dev/null +++ b/src/ObservableCollections.Unity/Assets/Scenes/Button.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7a021aee34791a94f83af413a3ade50c +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ObservableCollections.Unity/Assets/Scenes/SampleScene.unity b/src/ObservableCollections.Unity/Assets/Scenes/SampleScene.unity index fa3fc63..555e1c7 100644 --- a/src/ObservableCollections.Unity/Assets/Scenes/SampleScene.unity +++ b/src/ObservableCollections.Unity/Assets/Scenes/SampleScene.unity @@ -43,7 +43,7 @@ RenderSettings: --- !u!157 &3 LightmapSettings: m_ObjectHideFlags: 0 - serializedVersion: 12 + serializedVersion: 11 m_GIWorkflowMode: 1 m_GISettings: serializedVersion: 2 @@ -98,7 +98,7 @@ LightmapSettings: m_TrainingDataDestination: TrainingData m_LightProbeSampleCountMultiplier: 4 m_LightingDataAsset: {fileID: 0} - m_LightingSettings: {fileID: 0} + m_UseShadowmask: 1 --- !u!196 &4 NavMeshSettings: serializedVersion: 2 @@ -121,6 +121,511 @@ NavMeshSettings: debug: m_Flags: 0 m_NavMeshData: {fileID: 0} +--- !u!1 &57796286 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 57796287} + - component: {fileID: 57796289} + - component: {fileID: 57796288} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &57796287 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 57796286} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 155990449} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &57796288 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 57796286} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Button +--- !u!222 &57796289 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 57796286} + m_CullTransparentMesh: 0 +--- !u!1 &148590149 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 148590153} + - component: {fileID: 148590152} + - component: {fileID: 148590151} + - component: {fileID: 148590150} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &148590150 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 148590149} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &148590151 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 148590149} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 +--- !u!223 &148590152 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 148590149} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &148590153 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 148590149} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 418957056} + - {fileID: 155990449} + - {fileID: 1039383797} + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!1 &155990448 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 155990449} + - component: {fileID: 155990452} + - component: {fileID: 155990451} + - component: {fileID: 155990450} + m_Layer: 5 + m_Name: Button + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &155990449 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 155990448} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 57796287} + m_Father: {fileID: 148590153} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -549, y: 176} + m_SizeDelta: {x: 160, y: 30} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &155990450 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 155990448} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 155990451} + m_OnClick: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &155990451 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 155990448} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &155990452 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 155990448} + m_CullTransparentMesh: 0 +--- !u!1 &189758324 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 189758327} + - component: {fileID: 189758326} + - component: {fileID: 189758325} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &189758325 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 189758324} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &189758326 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 189758324} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!4 &189758327 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 189758324} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &279969104 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 279969105} + m_Layer: 5 + m_Name: Sliding Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &279969105 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 279969104} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 928569516} + m_Father: {fileID: 1117991140} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -20, y: -20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &418957055 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 418957056} + - component: {fileID: 418957059} + - component: {fileID: 418957058} + - component: {fileID: 418957057} + m_Layer: 5 + m_Name: Scroll View + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &418957056 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 418957055} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 2012947388} + - {fileID: 1639712797} + - {fileID: 1117991140} + m_Father: {fileID: 148590153} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -48.1, y: -1.4} + m_SizeDelta: {x: 703.8, y: 566.8} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &418957057 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 418957055} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1aa08ab6e0800fa44ae55d278d1423e3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Content: {fileID: 943860421} + m_Horizontal: 1 + m_Vertical: 1 + m_MovementType: 1 + m_Elasticity: 0.1 + m_Inertia: 1 + m_DecelerationRate: 0.135 + m_ScrollSensitivity: 1 + m_Viewport: {fileID: 2012947388} + m_HorizontalScrollbar: {fileID: 1639712798} + m_VerticalScrollbar: {fileID: 1117991141} + m_HorizontalScrollbarVisibility: 2 + m_VerticalScrollbarVisibility: 2 + m_HorizontalScrollbarSpacing: -3 + m_VerticalScrollbarSpacing: -3 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &418957058 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 418957055} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &418957059 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 418957055} + m_CullTransparentMesh: 0 --- !u!1 &519420028 GameObject: m_ObjectHideFlags: 0 @@ -132,6 +637,7 @@ GameObject: - component: {fileID: 519420032} - component: {fileID: 519420031} - component: {fileID: 519420029} + - component: {fileID: 519420030} m_Layer: 0 m_Name: Main Camera m_TagString: MainCamera @@ -147,6 +653,22 @@ AudioListener: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 519420028} m_Enabled: 1 +--- !u!114 &519420030 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 519420028} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e89d460dcf6b5db44a0e995732078819, type: 3} + m_Name: + m_EditorClassIdentifier: + prefab: {fileID: 2332625603231720647, guid: 7a021aee34791a94f83af413a3ade50c, type: 3} + root: {fileID: 943860420} + add: {fileID: 155990450} + remove: {fileID: 1039383798} --- !u!20 &519420031 Camera: m_ObjectHideFlags: 0 @@ -204,3 +726,775 @@ Transform: m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &928569515 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 928569516} + - component: {fileID: 928569518} + - component: {fileID: 928569517} + m_Layer: 5 + m_Name: Handle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &928569516 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 928569515} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 279969105} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &928569517 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 928569515} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &928569518 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 928569515} + m_CullTransparentMesh: 0 +--- !u!1 &943860420 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 943860421} + - component: {fileID: 943860422} + m_Layer: 5 + m_Name: Content + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &943860421 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 943860420} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 2012947388} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -0.00006425836} + m_SizeDelta: {x: 0, y: 300} + m_Pivot: {x: 0, y: 1} +--- !u!114 &943860422 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 943860420} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 0 + m_Spacing: 0 + m_ChildForceExpandWidth: 1 + m_ChildForceExpandHeight: 1 + m_ChildControlWidth: 0 + m_ChildControlHeight: 0 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 +--- !u!1 &1039383796 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1039383797} + - component: {fileID: 1039383800} + - component: {fileID: 1039383799} + - component: {fileID: 1039383798} + m_Layer: 5 + m_Name: Button (1) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1039383797 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1039383796} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1220176160} + m_Father: {fileID: 148590153} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -549, y: 64} + m_SizeDelta: {x: 160, y: 30} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1039383798 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1039383796} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1039383799} + m_OnClick: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &1039383799 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1039383796} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1039383800 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1039383796} + m_CullTransparentMesh: 0 +--- !u!1 &1117991139 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1117991140} + - component: {fileID: 1117991143} + - component: {fileID: 1117991142} + - component: {fileID: 1117991141} + m_Layer: 5 + m_Name: Scrollbar Vertical + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1117991140 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1117991139} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 279969105} + m_Father: {fileID: 418957056} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 0} + m_AnchorMax: {x: 1, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: 0} + m_Pivot: {x: 1, y: 1} +--- !u!114 &1117991141 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1117991139} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a4db7a114972834c8e4117be1d82ba3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 928569517} + m_HandleRect: {fileID: 928569516} + m_Direction: 2 + m_Value: 1 + m_Size: 1 + m_NumberOfSteps: 0 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &1117991142 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1117991139} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1117991143 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1117991139} + m_CullTransparentMesh: 0 +--- !u!1 &1220176159 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1220176160} + - component: {fileID: 1220176162} + - component: {fileID: 1220176161} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1220176160 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1220176159} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1039383797} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1220176161 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1220176159} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Button +--- !u!222 &1220176162 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1220176159} + m_CullTransparentMesh: 0 +--- !u!1 &1315955577 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1315955578} + - component: {fileID: 1315955580} + - component: {fileID: 1315955579} + m_Layer: 5 + m_Name: Handle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1315955578 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1315955577} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1606965100} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1315955579 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1315955577} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1315955580 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1315955577} + m_CullTransparentMesh: 0 +--- !u!1 &1606965099 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1606965100} + m_Layer: 5 + m_Name: Sliding Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1606965100 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1606965099} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1315955578} + m_Father: {fileID: 1639712797} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -20, y: -20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &1639712796 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1639712797} + - component: {fileID: 1639712800} + - component: {fileID: 1639712799} + - component: {fileID: 1639712798} + m_Layer: 5 + m_Name: Scrollbar Horizontal + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1639712797 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1639712796} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1606965100} + m_Father: {fileID: 418957056} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 20} + m_Pivot: {x: 0, y: 0} +--- !u!114 &1639712798 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1639712796} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a4db7a114972834c8e4117be1d82ba3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1315955579} + m_HandleRect: {fileID: 1315955578} + m_Direction: 0 + m_Value: 0 + m_Size: 0.99999994 + m_NumberOfSteps: 0 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &1639712799 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1639712796} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1639712800 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1639712796} + m_CullTransparentMesh: 0 +--- !u!1 &2012947387 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2012947388} + - component: {fileID: 2012947391} + - component: {fileID: 2012947390} + - component: {fileID: 2012947389} + m_Layer: 5 + m_Name: Viewport + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2012947388 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2012947387} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 943860421} + m_Father: {fileID: 418957056} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 1} +--- !u!114 &2012947389 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2012947387} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ShowMaskGraphic: 0 +--- !u!114 &2012947390 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2012947387} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10917, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &2012947391 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2012947387} + m_CullTransparentMesh: 0 diff --git a/src/ObservableCollections.Unity/Assets/Scenes/SampleScript.cs b/src/ObservableCollections.Unity/Assets/Scenes/SampleScript.cs new file mode 100644 index 0000000..a738ca5 --- /dev/null +++ b/src/ObservableCollections.Unity/Assets/Scenes/SampleScript.cs @@ -0,0 +1,78 @@ +using ObservableCollections; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; + +public class SampleScript : MonoBehaviour +{ + public Button prefab; + public GameObject root; + + public Button add; + public Button remove; + + int i = 0; + + void Start() + { + var oc = new ObservableRingBuffer(); + + var view = oc.CreateView(x => + { + var item = GameObject.Instantiate(prefab); + item.GetComponentInChildren().text = x.ToString(); + return item.gameObject; + }); + view.AttachFilter(new GameObjectFilter(root)); + + add.onClick.AddListener(() => + { + oc.AddLast(i++); + }); + + remove.onClick.AddListener(() => + { + oc.RemoveFirst(); + }); + + } + +} + +public class GameObjectFilter : ISynchronizedViewFilter +{ + readonly GameObject root; + + public GameObjectFilter(GameObject root) + { + this.root = root; + } + + public void OnCollectionChanged(ChangedKind changedKind, int value, GameObject view) + { + if (changedKind == ChangedKind.Add) + { + view.transform.SetParent(root.transform); + } + else if (changedKind == ChangedKind.Remove) + { + GameObject.Destroy(view); + } + } + + public bool IsMatch(int value, GameObject view) + { + return value % 2 == 0; + } + + public void WhenTrue(int value, GameObject view) + { + view.SetActive(true); + } + + public void WhenFalse(int value, GameObject view) + { + view.SetActive(false); + } +} diff --git a/src/ObservableCollections.Unity/Assets/Scenes/SampleScript.cs.meta b/src/ObservableCollections.Unity/Assets/Scenes/SampleScript.cs.meta new file mode 100644 index 0000000..8c3a13e --- /dev/null +++ b/src/ObservableCollections.Unity/Assets/Scenes/SampleScript.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e89d460dcf6b5db44a0e995732078819 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: