Merge remote-tracking branch 'origin/main' into work_branch
This commit is contained in:
@@ -1,11 +0,0 @@
|
||||
using VContainer;
|
||||
|
||||
namespace Darkmatter.App.LifetimeScopes
|
||||
{
|
||||
public class GameLifetimeScope : BaseLifetimeScope
|
||||
{
|
||||
protected override void Configure(IContainerBuilder builder)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ca410c053f074e1cba2f7041f500d34
|
||||
@@ -1,11 +1,6 @@
|
||||
using VContainer;
|
||||
|
||||
namespace Darkmatter.App.LifetimeScopes
|
||||
{
|
||||
public class RootLifetimeScope : BaseLifetimeScope
|
||||
{
|
||||
protected override void Configure(IContainerBuilder builder)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Darkmatter.Core.Contracts.Features.DrawingCatalog
|
||||
string Id { get; }
|
||||
string DisplayName { get; }
|
||||
Sprite DefaultThumbnail { get; }
|
||||
Sprite PaperBackground { get; }
|
||||
GameObject Prefab { get; }
|
||||
IReadOnlyList<ShapeSO> Pieces { get; }
|
||||
IReadOnlyList<ColorRegionDTO> Regions { get; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ddd3ece612334da5befd516d65ddc88c
|
||||
timeCreated: 1779952530
|
||||
@@ -0,0 +1,13 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Darkmatter.Core.Contracts.Features.GameplayFlow;
|
||||
|
||||
public interface IGameplaySceneRefs
|
||||
{
|
||||
RectTransform PaperRoot { get; }
|
||||
RectTransform SlotsParent { get; }
|
||||
RectTransform PiecesParent { get; }
|
||||
RectTransform RegionsParent { get; }
|
||||
RectTransform HudRoot { get; }
|
||||
RectTransform TrayPanel { get; }
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9794063828774e7e98d911a8252842c0
|
||||
timeCreated: 1779952541
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 68c97391df7846648bbb6d7847dafb18
|
||||
timeCreated: 1779950354
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Darkmatter.Core.Contracts.Features.DrawingCatalog;
|
||||
|
||||
namespace Darkmatter.Core.Contracts.Features.ShapeBuilder;
|
||||
|
||||
public interface IShapeBuilderController
|
||||
{
|
||||
UniTask InitializeAsync(CancellationToken ct);
|
||||
|
||||
UniTask BuildAsync(IDrawingTemplate template,
|
||||
IReadOnlyCollection<string> preSnappedIds, CancellationToken ct);
|
||||
|
||||
IReadOnlyCollection<string> GetSnappedPieceIds();
|
||||
void Clear();
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 218237e181434d4983ad55d38db77c74
|
||||
timeCreated: 1779950364
|
||||
@@ -2,7 +2,8 @@
|
||||
"name": "Core",
|
||||
"rootNamespace": "Darkmatter.Core",
|
||||
"references": [
|
||||
"GUID:f51ebe6a0ceec4240a699833d6309b23"
|
||||
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
||||
"GUID:9e24947de15b9834991c9d8411ea37cf"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Darkmatter.Core.Data.Static.Features.DrawingTemplate
|
||||
[field: SerializeField] public string Id { get; private set; }
|
||||
[field: SerializeField] public string DisplayName { get; private set; }
|
||||
[field: SerializeField] public Sprite DefaultThumbnail { get; private set; }
|
||||
[field: SerializeField] public Sprite PaperBackground { get; private set; }
|
||||
[field: SerializeField] public GameObject Prefab { get; private set; }
|
||||
[field: SerializeField] public IReadOnlyList<ShapeSO> Pieces { get; private set; }
|
||||
[field: SerializeField] public IReadOnlyList<ColorRegionDTO> Regions { get; private set; }
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace Darkmatter.Core.Enums.Services.Scenes
|
||||
{
|
||||
Boot,
|
||||
MainMenu,
|
||||
Colorbook,
|
||||
Gameplay,
|
||||
}
|
||||
}
|
||||
8
Assets/Darkmatter/Code/Features/AppBoot.meta
Normal file
8
Assets/Darkmatter/Code/Features/AppBoot.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3841157d2ef124a25b2c16956605ca40
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "Features.AppBoot",
|
||||
"rootNamespace": "Darkmatter.Features.AppBoot",
|
||||
"references": [
|
||||
"GUID:6a0a834eb41764f12ba55c3fb04a40cb",
|
||||
"GUID:c1c03c0e5b2f4412b9f2be1c20d6a9b1",
|
||||
"GUID:b0214a6008ed146ff8f122a6a9c2f6cc",
|
||||
"GUID:f51ebe6a0ceec4240a699833d6309b23"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a00b1d9e55c264fb785b78914db69e05
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Darkmatter/Code/Features/AppBoot/Flow.meta
Normal file
8
Assets/Darkmatter/Code/Features/AppBoot/Flow.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc7ecf57035f14a9897f40b12ad1b64f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
49
Assets/Darkmatter/Code/Features/AppBoot/Flow/AppBootFlow.cs
Normal file
49
Assets/Darkmatter/Code/Features/AppBoot/Flow/AppBootFlow.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Darkmatter.Core.Contracts.Services.Scenes;
|
||||
using Darkmatter.Core.Enums.Services.Scenes;
|
||||
using Darkmatter.Features.AppBoot.SceneRefs;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Video;
|
||||
using VContainer.Unity;
|
||||
|
||||
namespace Darkmatter.Features.AppBoot.Flow
|
||||
{
|
||||
public class AppBootFlow : IAsyncStartable
|
||||
{
|
||||
private readonly AppBootSceneRefs _sceneRefs;
|
||||
private readonly ISceneService _sceneService;
|
||||
|
||||
public AppBootFlow(AppBootSceneRefs sceneRefs, ISceneService sceneService)
|
||||
{
|
||||
_sceneRefs = sceneRefs;
|
||||
_sceneService = sceneService;
|
||||
}
|
||||
|
||||
public async UniTask StartAsync(CancellationToken cancellation = default)
|
||||
{
|
||||
var tcs = new UniTaskCompletionSource();
|
||||
var player = _sceneRefs.IntroVideoPlayer;
|
||||
|
||||
void OnDone(VideoPlayer vp)
|
||||
{
|
||||
vp.loopPointReached -= OnDone;
|
||||
tcs.TrySetResult();
|
||||
}
|
||||
|
||||
player.loopPointReached += OnDone;
|
||||
player.Play();
|
||||
await _sceneService.LoadSceneAsync(GameScene.MainMenu, null, cancellation);
|
||||
|
||||
await tcs.Task.AttachExternalCancellation(cancellation);
|
||||
|
||||
player.Stop();
|
||||
var rt = player.targetTexture;
|
||||
if (rt != null) rt.Release();
|
||||
|
||||
if (_sceneRefs.IntroCanvas != null)
|
||||
Object.Destroy(_sceneRefs.IntroCanvas.gameObject);
|
||||
Object.Destroy(player.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 892f636e24e0d41ce9423c7a989d717b
|
||||
8
Assets/Darkmatter/Code/Features/AppBoot/Installers.meta
Normal file
8
Assets/Darkmatter/Code/Features/AppBoot/Installers.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bfa843ca122db487f9a2defa353418a7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,21 @@
|
||||
using Darkmatter.Features.AppBoot.Flow;
|
||||
using Darkmatter.Features.AppBoot.SceneRefs;
|
||||
using Darkmatter.Libs.Installers;
|
||||
using UnityEngine;
|
||||
using VContainer;
|
||||
using VContainer.Unity;
|
||||
|
||||
namespace Darkmatter.Features.AppBoot.Installers
|
||||
{
|
||||
public class AppBootFeatureModule : MonoBehaviour, IModule
|
||||
{
|
||||
[SerializeField] private AppBootSceneRefs sceneRefs;
|
||||
|
||||
public void Register(IContainerBuilder builder)
|
||||
{
|
||||
if (sceneRefs != null)
|
||||
builder.RegisterComponent(sceneRefs);
|
||||
builder.RegisterEntryPoint<AppBootFlow>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a3a74c469f13e41a09665530aa744705
|
||||
3
Assets/Darkmatter/Code/Features/AppBoot/SceneRefs.meta
Normal file
3
Assets/Darkmatter/Code/Features/AppBoot/SceneRefs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 016a2252ff404eea98e7a84b80d0e4b1
|
||||
timeCreated: 1779955116
|
||||
@@ -0,0 +1,11 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Video;
|
||||
|
||||
namespace Darkmatter.Features.AppBoot.SceneRefs
|
||||
{
|
||||
public class AppBootSceneRefs : MonoBehaviour
|
||||
{
|
||||
[field: SerializeField] public VideoPlayer IntroVideoPlayer { get; private set; }
|
||||
[field: SerializeField] public GameObject IntroCanvas { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17fd08f85ba94bf694f285cdd48bee02
|
||||
timeCreated: 1779955127
|
||||
8
Assets/Darkmatter/Code/Features/Coloring.meta
Normal file
8
Assets/Darkmatter/Code/Features/Coloring.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 585a9b1ea84a5404d8726cb7e20e6398
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "Features.Coloring",
|
||||
"rootNamespace": "Darkmatter.Features.Coloring",
|
||||
"references": [
|
||||
"GUID:6a0a834eb41764f12ba55c3fb04a40cb",
|
||||
"GUID:c1c03c0e5b2f4412b9f2be1c20d6a9b1",
|
||||
"GUID:c176ee863a5e74e88a6517f9f102cf92",
|
||||
"GUID:b4c9f7fbf1e144933a1797dc208ece5f",
|
||||
"GUID:b0214a6008ed146ff8f122a6a9c2f6cc",
|
||||
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
||||
"GUID:80ecb87cae9c44d19824e70ea7229748"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4cede189a43c349069c614e305683720
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Darkmatter/Code/Features/Coloring/Installers.meta
Normal file
8
Assets/Darkmatter/Code/Features/Coloring/Installers.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e9ad07895989e445f8557096c4a1aa7a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,14 @@
|
||||
using Darkmatter.Libs.Installers;
|
||||
using UnityEngine;
|
||||
using VContainer;
|
||||
|
||||
namespace Darkmatter.Features.Coloring
|
||||
{
|
||||
public class ColoringFeatureModule : MonoBehaviour,IModule
|
||||
{
|
||||
public void Register(IContainerBuilder builder)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d0dc926588daf4a139e807f48f664baf
|
||||
8
Assets/Darkmatter/Code/Features/GameplayFlow.meta
Normal file
8
Assets/Darkmatter/Code/Features/GameplayFlow.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e69d4466105646aabc1668844cac5b7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "Features.GameplayFlow",
|
||||
"rootNamespace": "Darkmatter.Features.GameplayFlow",
|
||||
"references": [
|
||||
"GUID:6a0a834eb41764f12ba55c3fb04a40cb",
|
||||
"GUID:b0214a6008ed146ff8f122a6a9c2f6cc",
|
||||
"GUID:c1c03c0e5b2f4412b9f2be1c20d6a9b1"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 995166e584dda4ff98501f62b07aa9cb
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Darkmatter/Code/Features/GameplayFlow/Flow.meta
Normal file
8
Assets/Darkmatter/Code/Features/GameplayFlow/Flow.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: adb650c457f6843c2a5704f12bcd0160
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 46180d2f7b7a14e42b77afb776b3a129
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
using Darkmatter.Core.Contracts.Features.GameplayFlow;
|
||||
using Darkmatter.Features.GameplayFlow.SceneRefs;
|
||||
using Darkmatter.Libs.Installers;
|
||||
using UnityEngine;
|
||||
using VContainer;
|
||||
using VContainer.Unity;
|
||||
|
||||
namespace Darkmatter.Features.GameplayFlow
|
||||
{
|
||||
public class GameplayFlowFeatureModule : MonoBehaviour, IModule
|
||||
{
|
||||
[SerializeField] private GameplaySceneRefs sceneRefs;
|
||||
|
||||
public void Register(IContainerBuilder builder)
|
||||
{
|
||||
if (sceneRefs != null)
|
||||
builder.RegisterComponent<IGameplaySceneRefs>(sceneRefs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c784b80c101814d24bf8820233bb0f62
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 38e2583efd5f84627b5ff0fc7599bf03
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,24 @@
|
||||
using Darkmatter.Core.Contracts.Features.GameplayFlow;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Darkmatter.Features.GameplayFlow.SceneRefs
|
||||
{
|
||||
public class GameplaySceneRefs : MonoBehaviour, IGameplaySceneRefs
|
||||
{
|
||||
[SerializeField] private RectTransform paperRoot;
|
||||
[SerializeField] private RectTransform slotsParent;
|
||||
[SerializeField] private RectTransform piecesParent;
|
||||
[SerializeField] private RectTransform regionsParent;
|
||||
|
||||
[SerializeField] private RectTransform hudRoot;
|
||||
[SerializeField] private RectTransform trayPanel;
|
||||
|
||||
|
||||
public RectTransform PaperRoot => paperRoot;
|
||||
public RectTransform SlotsParent => slotsParent;
|
||||
public RectTransform PiecesParent => piecesParent;
|
||||
public RectTransform RegionsParent => regionsParent;
|
||||
public RectTransform HudRoot => hudRoot;
|
||||
public RectTransform TrayPanel => trayPanel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f2e39895945b94467b1677388b2fb896
|
||||
@@ -4,11 +4,6 @@ using UnityEngine;
|
||||
|
||||
namespace Darkmatter.Features.ShapeBuilder.Commands
|
||||
{
|
||||
/// <summary>
|
||||
/// Undoable snap. Captures the piece's pre-snap pose + parent at ctor time;
|
||||
/// Execute drives the normal snap tween; Undo restores the pre-snap state
|
||||
/// and re-enables drag.
|
||||
/// </summary>
|
||||
internal sealed class SnapPieceCommand : ICommand
|
||||
{
|
||||
private readonly ShapePiece _piece;
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
using Darkmatter.Core.Contracts.Features.ShapeBuilder;
|
||||
using Darkmatter.Core.Data.Static.Features.ShapeBuilder;
|
||||
using Darkmatter.Features.ShapeBuilder.Systems;
|
||||
using Darkmatter.Libs.Installers;
|
||||
using UnityEngine;
|
||||
using VContainer;
|
||||
using VContainer.Unity;
|
||||
|
||||
namespace Darkmatter.Features.ShapeBuilder.Installers
|
||||
{
|
||||
@@ -12,10 +15,8 @@ namespace Darkmatter.Features.ShapeBuilder.Installers
|
||||
public void Register(IContainerBuilder builder)
|
||||
{
|
||||
if (config != null)
|
||||
builder.RegisterInstance(config);
|
||||
|
||||
// ShapePiece instances are MonoBehaviours instantiated by the
|
||||
// ShapeBuilderController; nothing to register here for them.
|
||||
builder.RegisterComponent(config);
|
||||
builder.Register<IShapeBuilderController, ShapeBuilderController>(Lifetime.Singleton);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Darkmatter.Core.Contracts.Features.DrawingCatalog;
|
||||
using Darkmatter.Core.Contracts.Features.History;
|
||||
using Darkmatter.Core.Contracts.Features.ShapeBuilder;
|
||||
using Darkmatter.Core.Contracts.Services.Assets;
|
||||
using Darkmatter.Core.Contracts.Services.Audio;
|
||||
using Darkmatter.Core.Contracts.Features.GameplayFlow;
|
||||
using Darkmatter.Core.Data.Signals.Features.ShapeBuilder;
|
||||
using Darkmatter.Core.Data.Static.Features.ShapeBuilder;
|
||||
using Darkmatter.Features.ShapeBuilder.UI;
|
||||
using Darkmatter.Libs.Observer;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace Darkmatter.Features.ShapeBuilder.Systems
|
||||
{
|
||||
public class ShapeBuilderController : IShapeBuilderController, IDisposable
|
||||
{
|
||||
private const string PiecePrefabKey = "ShapeBuilder/Piece";
|
||||
|
||||
private string _currentTemplateId;
|
||||
private int _expected;
|
||||
private int _snapped;
|
||||
private GameObject _drawingInstance;
|
||||
private GameObject _piecePrefab;
|
||||
private IDisposable _snappedSub;
|
||||
|
||||
private readonly List<string> _snappedPieceIds = new();
|
||||
private readonly ShapeBuilderConfig _cfg;
|
||||
private readonly ISfxPlayer _sfx;
|
||||
private readonly IEventBus _bus;
|
||||
private readonly IUndoStack _undo;
|
||||
private readonly IAssetProviderService _assetProviderService;
|
||||
private readonly IEventBus _eventBus;
|
||||
private readonly IGameplaySceneRefs _refs;
|
||||
|
||||
|
||||
public ShapeBuilderController(
|
||||
ShapeBuilderConfig cfg,
|
||||
ISfxPlayer sfx,
|
||||
IEventBus bus,
|
||||
IUndoStack undo,
|
||||
IAssetProviderService assetProviderService,
|
||||
IEventBus eventBus,
|
||||
IGameplaySceneRefs refs)
|
||||
{
|
||||
_cfg = cfg;
|
||||
_sfx = sfx;
|
||||
_bus = bus;
|
||||
_undo = undo;
|
||||
_assetProviderService = assetProviderService;
|
||||
_eventBus = eventBus;
|
||||
_refs = refs;
|
||||
}
|
||||
|
||||
public async UniTask InitializeAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await TryLoadPiecePrefabAsync(cancellationToken);
|
||||
|
||||
_snappedSub = _eventBus.Subscribe<PieceSnappedSignal>(OnPieceSnapped);
|
||||
}
|
||||
|
||||
private void OnPieceSnapped(PieceSnappedSignal obj)
|
||||
{
|
||||
_snappedPieceIds.Add(obj.PieceId);
|
||||
CheckIfShapeAssembled();
|
||||
}
|
||||
|
||||
public async UniTask BuildAsync(
|
||||
IDrawingTemplate template,
|
||||
IReadOnlyCollection<string> preSnappedIds,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
Clear();
|
||||
|
||||
if (template.Prefab == null)
|
||||
throw new System.Exception($"No drawing layout prefab for '{template.Id}'");
|
||||
|
||||
_drawingInstance = Object.Instantiate(template.Prefab, _refs.PaperRoot);
|
||||
ct.ThrowIfCancellationRequested();
|
||||
|
||||
var slots = _drawingInstance.GetComponentsInChildren<SlotMarker>(includeInactive: true);
|
||||
|
||||
await TryLoadPiecePrefabAsync(ct);
|
||||
|
||||
int count = template.Pieces.Count;
|
||||
float trayW = _refs.TrayPanel.rect.width;
|
||||
float pitch = trayW / (count + 1);
|
||||
|
||||
_currentTemplateId = template.Id;
|
||||
_expected = count;
|
||||
_snapped = 0;
|
||||
|
||||
CreateShapePieceInstances(template, preSnappedIds, count, slots, pitch, trayW);
|
||||
|
||||
CheckIfShapeAssembled();
|
||||
}
|
||||
|
||||
private void CreateShapePieceInstances(IDrawingTemplate template, IReadOnlyCollection<string> preSnappedIds,
|
||||
int count,
|
||||
SlotMarker[] slots, float pitch, float trayW)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var shape = template.Pieces[i];
|
||||
var slot = FindSlotForShape(slots, shape);
|
||||
if (slot == null)
|
||||
{
|
||||
Debug.LogError($"[ShapeBuilder] No SlotMarker for '{shape.Id}' in '{template.Id}'");
|
||||
continue;
|
||||
}
|
||||
|
||||
var trayPos = new Vector2(pitch * (i + 1) - trayW * 0.5f, 0f);
|
||||
bool preSnapped = preSnappedIds != null && preSnappedIds.Contains(shape.Id);
|
||||
|
||||
var go = Object.Instantiate(_piecePrefab, _refs.TrayPanel);
|
||||
go.name = $"Piece_{shape.Id}";
|
||||
|
||||
var piece = go.GetComponent<ShapePiece>();
|
||||
piece.Setup(shape, slot, _cfg, _sfx, _bus, _undo, trayPos, preSnapped);
|
||||
|
||||
if (preSnapped) _snapped++;
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckIfShapeAssembled()
|
||||
{
|
||||
if (_expected > 0 && _snapped == _expected)
|
||||
_bus.Publish(new ShapeAssembledSignal(_currentTemplateId));
|
||||
}
|
||||
|
||||
private async UniTask TryLoadPiecePrefabAsync(CancellationToken ct)
|
||||
{
|
||||
if (_piecePrefab == null)
|
||||
{
|
||||
_piecePrefab = await _assetProviderService.LoadAssetAsync<GameObject>(
|
||||
PiecePrefabKey, progress: null, cancellationToken: ct);
|
||||
if (_piecePrefab == null)
|
||||
throw new System.Exception($"No piece prefab at '{PiecePrefabKey}'");
|
||||
}
|
||||
}
|
||||
|
||||
private static SlotMarker FindSlotForShape(SlotMarker[] slots, ShapeSO shape)
|
||||
{
|
||||
foreach (var s in slots)
|
||||
if (s.Shape == shape)
|
||||
return s;
|
||||
return null;
|
||||
}
|
||||
|
||||
public IReadOnlyCollection<string> GetSnappedPieceIds()
|
||||
{
|
||||
return _snappedPieceIds;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_snappedSub?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2964329afc8ef47fe8817d4a701b8fe1
|
||||
@@ -12,12 +12,6 @@ using UnityEngine.UI;
|
||||
|
||||
namespace Darkmatter.Features.ShapeBuilder.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Single-MB shape piece. Handles drag, reactive preview lerp, snap,
|
||||
/// and return-to-tray. Snap is wrapped in a <see cref="SnapPieceCommand"/>
|
||||
/// pushed onto the shared <see cref="IUndoStack"/> so it participates in
|
||||
/// the same undo/redo flow as coloring.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
public sealed class ShapePiece : MonoBehaviour,
|
||||
IBeginDragHandler, IDragHandler, IEndDragHandler
|
||||
@@ -116,7 +110,7 @@ namespace Darkmatter.Features.ShapeBuilder.UI
|
||||
_slot.RectTransform.anchoredPosition);
|
||||
|
||||
if (dist <= _cfg.SnapRadius)
|
||||
_undo.Push(new SnapPieceCommand(this)); // Push calls Execute → SnapInternal
|
||||
_undo.Push(new SnapPieceCommand(this));
|
||||
else
|
||||
ReturnToTray();
|
||||
}
|
||||
@@ -132,7 +126,6 @@ namespace Darkmatter.Features.ShapeBuilder.UI
|
||||
RectTransform.localRotation = Quaternion.Slerp(Quaternion.identity, slot.localRotation, t);
|
||||
}
|
||||
|
||||
// ---- Command-driven snap / un-snap ----
|
||||
internal void SnapInternal()
|
||||
{
|
||||
Lock();
|
||||
|
||||
8
Assets/Darkmatter/Code/Services/Audio/Installers.meta
Normal file
8
Assets/Darkmatter/Code/Services/Audio/Installers.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 46d6646913d0d423eaabd923f70ef127
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,22 @@
|
||||
using Darkmatter.Core.Contracts.Services.Audio;
|
||||
using Darkmatter.Core.Data.Static.Services.Audio;
|
||||
using Darkmatter.Libs.Installers;
|
||||
using UnityEngine;
|
||||
using VContainer;
|
||||
using VContainer.Unity;
|
||||
|
||||
namespace Darkmatter.Services.Audio
|
||||
{
|
||||
public class AudioServiceModule : MonoBehaviour, IModule
|
||||
{
|
||||
[SerializeField] private SfxCatalogSO sfxCatalog;
|
||||
|
||||
public void Register(IContainerBuilder builder)
|
||||
{
|
||||
if (sfxCatalog != null)
|
||||
builder.RegisterComponent(sfxCatalog);
|
||||
builder.Register<IAudioService, AudioService>(Lifetime.Singleton);
|
||||
builder.Register<ISfxPlayer, SfxPlayer>(Lifetime.Singleton);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fa11c3cff997e4a0a8263a29d804779f
|
||||
@@ -5,7 +5,8 @@
|
||||
"GUID:6a0a834eb41764f12ba55c3fb04a40cb",
|
||||
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
||||
"GUID:b0214a6008ed146ff8f122a6a9c2f6cc",
|
||||
"GUID:b4c9f7fbf1e144933a1797dc208ece5f"
|
||||
"GUID:b4c9f7fbf1e144933a1797dc208ece5f",
|
||||
"GUID:c1c03c0e5b2f4412b9f2be1c20d6a9b1"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
||||
8
Assets/Darkmatter/Code/Services/Audio/Systems.meta
Normal file
8
Assets/Darkmatter/Code/Services/Audio/Systems.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bbbd26e1f2def4991b74ecd2709fdb08
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Darkmatter/Code/Services/Scenes/Installers.meta
Normal file
8
Assets/Darkmatter/Code/Services/Scenes/Installers.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0d37521fbeb9c48fd99ee8968c4ce1cf
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,15 @@
|
||||
using Darkmatter.Core.Contracts.Services.Scenes;
|
||||
using Darkmatter.Libs.Installers;
|
||||
using UnityEngine;
|
||||
using VContainer;
|
||||
|
||||
namespace Darkmatter.Services.Scenes
|
||||
{
|
||||
public class SceneServiceModule : MonoBehaviour, IModule
|
||||
{
|
||||
public void Register(IContainerBuilder builder)
|
||||
{
|
||||
builder.Register<ISceneService, SceneService>(Lifetime.Singleton);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad17780c76afe4f33ac9f90931a18f76
|
||||
@@ -6,7 +6,9 @@
|
||||
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
||||
"GUID:593a5b492d29ac6448b1ebf7f035ef33",
|
||||
"GUID:9e24947de15b9834991c9d8411ea37cf",
|
||||
"GUID:84651a3751eca9349aac36a66bba901b"
|
||||
"GUID:84651a3751eca9349aac36a66bba901b",
|
||||
"GUID:c1c03c0e5b2f4412b9f2be1c20d6a9b1",
|
||||
"GUID:b0214a6008ed146ff8f122a6a9c2f6cc"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
||||
8
Assets/Darkmatter/Code/Services/Scenes/Systems.meta
Normal file
8
Assets/Darkmatter/Code/Services/Scenes/Systems.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aa48eed4801294ccc8263b26b874dbb7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user