com.puzzlescapegames.services 1.0.2 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Editor/PuzzlescapeGames.Services.Editor.asmdef +3 -1
- package/README.md +5 -1
- package/Runtime/Common/AudioMixer.mixer +146 -0
- package/Runtime/Common/AudioMixer.mixer.meta +8 -0
- package/Runtime/Common.meta +8 -0
- package/Runtime/Plugins/SlicedFilledImage.cs +730 -0
- package/Runtime/Plugins/SlicedFilledImage.cs.meta +11 -0
- package/Runtime/Plugins/UIGradient/Editor/UIGradientEditor.cs +220 -0
- package/Runtime/Plugins/UIGradient/Editor/UIGradientEditor.cs.meta +11 -0
- package/Runtime/Plugins/UIGradient/Editor/uigradient_inspector_icon.png +0 -0
- package/Runtime/Plugins/UIGradient/Editor/uigradient_inspector_icon.png.meta +110 -0
- package/Runtime/Plugins/UIGradient/Editor.meta +8 -0
- package/Runtime/Plugins/UIGradient/Scripts/UIGradient.cs +511 -0
- package/Runtime/Plugins/UIGradient/Scripts/UIGradient.cs.meta +11 -0
- package/Runtime/Plugins/UIGradient/Scripts/Vector2Extension.cs +24 -0
- package/Runtime/Plugins/UIGradient/Scripts/Vector2Extension.cs.meta +11 -0
- package/Runtime/Plugins/UIGradient/Scripts.meta +8 -0
- package/Runtime/Plugins/UIGradient.meta +8 -0
- package/Runtime/Plugins/Vibration/Vibration/Example/VibrationExample.cs +82 -0
- package/Runtime/Plugins/Vibration/Vibration/Example/VibrationExample.cs.meta +11 -0
- package/Runtime/Plugins/Vibration/Vibration/Example.meta +8 -0
- package/Runtime/Plugins/Vibration/Vibration/Vibration.cs +263 -0
- package/Runtime/Plugins/Vibration/Vibration/Vibration.cs.meta +12 -0
- package/Runtime/Plugins/Vibration/Vibration.asmdef +18 -0
- package/Runtime/Plugins/Vibration/Vibration.asmdef.meta +7 -0
- package/Runtime/Plugins/Vibration/Vibration.meta +8 -0
- package/Runtime/Plugins/Vibration/iOS/HapticFeedback.mm +64 -0
- package/Runtime/Plugins/Vibration/iOS/HapticFeedback.mm.meta +37 -0
- package/Runtime/Plugins/Vibration/iOS/Vibration.h +26 -0
- package/Runtime/Plugins/Vibration/iOS/Vibration.h.meta +27 -0
- package/Runtime/Plugins/Vibration/iOS/Vibration.mm +73 -0
- package/Runtime/Plugins/Vibration/iOS/Vibration.mm.meta +37 -0
- package/Runtime/Plugins/Vibration/iOS.meta +8 -0
- package/Runtime/Plugins/Vibration.meta +8 -0
- package/Runtime/Plugins.meta +8 -0
- package/Runtime/PuzzlescapeGames.Services.asmdef +19 -2
- package/Runtime/Services/AudioService/AudioService.cs +82 -0
- package/Runtime/Services/AudioService/AudioService.cs.meta +3 -0
- package/Runtime/Services/AudioService/AudioServiceCustomInstaller.cs +29 -0
- package/Runtime/Services/AudioService/AudioServiceCustomInstaller.cs.meta +3 -0
- package/Runtime/Services/AudioService/AudioSource.cs +87 -0
- package/Runtime/Services/AudioService/AudioSource.cs.meta +3 -0
- package/Runtime/Services/AudioService/AudioSourceFactory.cs +6 -0
- package/Runtime/Services/AudioService/AudioSourceFactory.cs.meta +3 -0
- package/Runtime/Services/AudioService/IAudioService.cs +16 -0
- package/Runtime/Services/AudioService/IAudioService.cs.meta +3 -0
- package/Runtime/Services/AudioService.meta +8 -0
- package/Runtime/Services/NTPService/INTPService.cs +13 -0
- package/Runtime/Services/NTPService/INTPService.cs.meta +3 -0
- package/Runtime/Services/NTPService/NTPService.cs +153 -0
- package/Runtime/Services/NTPService/NTPService.cs.meta +3 -0
- package/Runtime/Services/NTPService/NTPServiceInstaller.cs +12 -0
- package/Runtime/Services/NTPService/NTPServiceInstaller.cs.meta +3 -0
- package/Runtime/Services/NTPService.meta +8 -0
- package/Runtime/Services/TickableService/TickableService.cs +29 -0
- package/Runtime/Services/TickableService/TickableService.cs.meta +3 -0
- package/Runtime/Services/TickableService/TickableServiceInstaller.cs +12 -0
- package/Runtime/Services/TickableService/TickableServiceInstaller.cs.meta +3 -0
- package/Runtime/Services/TickableService.meta +8 -0
- package/Runtime/Services/UIBlockingService/UIBlocker.cs +15 -0
- package/Runtime/Services/UIBlockingService/UIBlocker.cs.meta +3 -0
- package/Runtime/Services/UIBlockingService/UIBlockingService.cs +36 -0
- package/Runtime/Services/UIBlockingService/UIBlockingService.cs.meta +3 -0
- package/Runtime/Services/UIBlockingService/UIBlockingServiceInstaller.cs +17 -0
- package/Runtime/Services/UIBlockingService/UIBlockingServiceInstaller.cs.meta +3 -0
- package/Runtime/Services/UIBlockingService.meta +8 -0
- package/Runtime/Services/VibrationService/IVibrationService.cs +7 -0
- package/Runtime/Services/VibrationService/IVibrationService.cs.meta +3 -0
- package/Runtime/Services/VibrationService/VibrationService.cs +19 -0
- package/Runtime/Services/VibrationService/VibrationService.cs.meta +3 -0
- package/Runtime/Services/VibrationService/VibrationServiceInstaller.cs +12 -0
- package/Runtime/Services/VibrationService/VibrationServiceInstaller.cs.meta +3 -0
- package/Runtime/Services/VibrationService.meta +8 -0
- package/Runtime/Services.meta +8 -0
- package/package.json +1 -1
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
using UnityEngine;
|
|
2
|
+
using UnityEngine.Audio;
|
|
3
|
+
|
|
4
|
+
namespace PuzzlescapeGames.Services.AudioService
|
|
5
|
+
{
|
|
6
|
+
internal sealed class AudioService : IAudioService
|
|
7
|
+
{
|
|
8
|
+
private const string MIXER_MASTER = "MasterVolume";
|
|
9
|
+
private const string MIXER_MUSIC = "MusicVolume";
|
|
10
|
+
private const string MIXER_SFX = "SFXVolume";
|
|
11
|
+
|
|
12
|
+
private const string SFX = "SFX";
|
|
13
|
+
private const string MUSIC = "Music";
|
|
14
|
+
|
|
15
|
+
private AudioSource _musicSource;
|
|
16
|
+
|
|
17
|
+
private readonly AudioSourceFactory _audioFactory;
|
|
18
|
+
private readonly AudioMixer _audioMixer;
|
|
19
|
+
|
|
20
|
+
public AudioService( AudioSourceFactory audioFactory, AudioMixer audioMixer )
|
|
21
|
+
{
|
|
22
|
+
_audioFactory = audioFactory;
|
|
23
|
+
_audioMixer = audioMixer;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public void PlayMusic( AudioClip clip )
|
|
27
|
+
{
|
|
28
|
+
CreateMusic().PlayLoop( clip );
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public void MuteMusic( bool trigger )
|
|
32
|
+
{
|
|
33
|
+
CreateMusic().Mute( trigger );
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public void PlaySound( AudioClip clip )
|
|
37
|
+
{
|
|
38
|
+
CreateSound().PlayOnce( clip );
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public void SetMasterVolume( float value )
|
|
42
|
+
{
|
|
43
|
+
_audioMixer.SetFloat( MIXER_MASTER, value );
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public void SetMusicVolume( float value )
|
|
47
|
+
{
|
|
48
|
+
_audioMixer.SetFloat( MIXER_MUSIC, value );
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public void SetSoundVolume( float value )
|
|
52
|
+
{
|
|
53
|
+
_audioMixer.SetFloat( MIXER_SFX, value );
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private AudioSource CreateSound()
|
|
57
|
+
{
|
|
58
|
+
var source = _audioFactory.Create();
|
|
59
|
+
if ( _audioMixer != null )
|
|
60
|
+
{
|
|
61
|
+
source.Source.outputAudioMixerGroup = _audioMixer.FindMatchingGroups( SFX )[ 0 ];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return source;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private AudioSource CreateMusic()
|
|
68
|
+
{
|
|
69
|
+
if ( _musicSource == null )
|
|
70
|
+
{
|
|
71
|
+
_musicSource = _audioFactory.Create();
|
|
72
|
+
|
|
73
|
+
if ( _audioMixer != null )
|
|
74
|
+
{
|
|
75
|
+
_musicSource.Source.outputAudioMixerGroup = _audioMixer.FindMatchingGroups( MUSIC )[ 0 ];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return _musicSource;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
using PuzzlescapeGames.IoC;
|
|
2
|
+
using System;
|
|
3
|
+
using UnityEngine.Audio;
|
|
4
|
+
using Zenject;
|
|
5
|
+
|
|
6
|
+
namespace PuzzlescapeGames.Services.AudioService
|
|
7
|
+
{
|
|
8
|
+
public sealed class AudioServiceCustomInstaller : CustomInstaller
|
|
9
|
+
{
|
|
10
|
+
private readonly int _poolSize;
|
|
11
|
+
private readonly AudioMixer _audioMixer;
|
|
12
|
+
|
|
13
|
+
public AudioServiceCustomInstaller( int poolSize, AudioMixer audioMixer )
|
|
14
|
+
{
|
|
15
|
+
_poolSize = poolSize;
|
|
16
|
+
_audioMixer = audioMixer ?? throw new ArgumentNullException( nameof(audioMixer) );
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public override void Install( DiContainer container )
|
|
20
|
+
{
|
|
21
|
+
container.BindFactory< AudioSource, AudioSourceFactory >()
|
|
22
|
+
.FromMonoPoolableMemoryPool((x) => x.WithInitialSize( _poolSize )
|
|
23
|
+
.FromNewComponentOnNewGameObject())
|
|
24
|
+
.WhenInjectedInto<AudioService>();
|
|
25
|
+
container.BindInstance( _audioMixer ).WhenInjectedInto< AudioService >();
|
|
26
|
+
container.BindInterfacesTo< AudioService >().AsSingle();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
using Cysharp.Threading.Tasks;
|
|
2
|
+
using PuzzlescapeGames.Extensions;
|
|
3
|
+
using PuzzlescapeGames.IoC;
|
|
4
|
+
using UnityEngine;
|
|
5
|
+
|
|
6
|
+
namespace PuzzlescapeGames.Services.AudioService
|
|
7
|
+
{
|
|
8
|
+
[ RequireComponent(typeof(UnityEngine.AudioSource)) ]
|
|
9
|
+
internal sealed class AudioSource : ZenjectMonoPoolable
|
|
10
|
+
{
|
|
11
|
+
public UnityEngine.AudioSource Source
|
|
12
|
+
{
|
|
13
|
+
get
|
|
14
|
+
{
|
|
15
|
+
if ( _source == null )
|
|
16
|
+
{
|
|
17
|
+
_source = GetComponent< UnityEngine.AudioSource >();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return _source;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
private UnityEngine.AudioSource _source;
|
|
24
|
+
|
|
25
|
+
public bool IsPlaying
|
|
26
|
+
{
|
|
27
|
+
get => _isPlaying;
|
|
28
|
+
private set
|
|
29
|
+
{
|
|
30
|
+
_isPlaying = value;
|
|
31
|
+
PlayingChangedHandler();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
private bool _isPlaying = false;
|
|
35
|
+
|
|
36
|
+
public bool isLoop { get; private set; } = false;
|
|
37
|
+
|
|
38
|
+
public void PlayLoop( AudioClip clip )
|
|
39
|
+
{
|
|
40
|
+
Source.clip = clip;
|
|
41
|
+
Loop( true );
|
|
42
|
+
Source.Play();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public void PlayOnce( AudioClip clip )
|
|
46
|
+
{
|
|
47
|
+
Loop( false );
|
|
48
|
+
|
|
49
|
+
StartPlayDelay( clip.length );
|
|
50
|
+
Source.PlayOneShot( clip );
|
|
51
|
+
|
|
52
|
+
IsPlaying = true;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public void Mute( bool trigger )
|
|
56
|
+
{
|
|
57
|
+
Source.mute = trigger;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public void Loop( bool trigger )
|
|
61
|
+
{
|
|
62
|
+
isLoop = trigger;
|
|
63
|
+
Source.loop = trigger;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private void StartPlayDelay( float playTime )
|
|
67
|
+
{
|
|
68
|
+
PlayDelay( playTime ).Forget();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private async UniTask PlayDelay( float playTime )
|
|
72
|
+
{
|
|
73
|
+
await UniTask.WaitForSeconds( playTime, cancellationToken: ThreadingUtils.QuitToken );
|
|
74
|
+
await UniTask.WaitForSeconds( 0.16f, cancellationToken: ThreadingUtils.QuitToken );
|
|
75
|
+
|
|
76
|
+
IsPlaying = false;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private void PlayingChangedHandler()
|
|
80
|
+
{
|
|
81
|
+
if ( !IsPlaying )
|
|
82
|
+
{
|
|
83
|
+
DespawnIt();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
using UnityEngine;
|
|
2
|
+
|
|
3
|
+
namespace PuzzlescapeGames.Services.AudioService
|
|
4
|
+
{
|
|
5
|
+
public interface IAudioService
|
|
6
|
+
{
|
|
7
|
+
void PlayMusic( AudioClip clip );
|
|
8
|
+
void PlaySound( AudioClip clip );
|
|
9
|
+
|
|
10
|
+
void SetMasterVolume( float value );
|
|
11
|
+
void SetMusicVolume( float value );
|
|
12
|
+
void SetSoundVolume( float value );
|
|
13
|
+
|
|
14
|
+
void MuteMusic( bool trigger );
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
using Cysharp.Threading.Tasks;
|
|
2
|
+
using System;
|
|
3
|
+
using System.Net;
|
|
4
|
+
using System.Net.Sockets;
|
|
5
|
+
using System.Threading;
|
|
6
|
+
using UnityEngine;
|
|
7
|
+
using Zenject;
|
|
8
|
+
|
|
9
|
+
namespace PuzzlescapeGames.Services.NTPService
|
|
10
|
+
{
|
|
11
|
+
public sealed class NTPService : INTPService, IDisposable
|
|
12
|
+
{
|
|
13
|
+
public bool IsDateSynchronized { get; private set; } = false;
|
|
14
|
+
|
|
15
|
+
public DateTime Now
|
|
16
|
+
{
|
|
17
|
+
get
|
|
18
|
+
{
|
|
19
|
+
if ( IsDateSynchronized )
|
|
20
|
+
return _ntpDate.AddSeconds( Time.realtimeSinceStartup - _responseReceivedTime );
|
|
21
|
+
|
|
22
|
+
return DateTime.Now;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private string _ntpServer = "time.google.com";
|
|
27
|
+
private int _requestTimeout = 3;//sec
|
|
28
|
+
private float _awaitTime = 0.16f;
|
|
29
|
+
|
|
30
|
+
private DateTime _ntpDate;
|
|
31
|
+
private float _responseReceivedTime;
|
|
32
|
+
private byte[] _receivedNtpData;
|
|
33
|
+
private Socket _socket;
|
|
34
|
+
private Thread _syncThread;
|
|
35
|
+
private volatile bool _responseReceived;
|
|
36
|
+
private CancellationTokenSource _cancellationSource;
|
|
37
|
+
|
|
38
|
+
public NTPService()
|
|
39
|
+
{
|
|
40
|
+
IsDateSynchronized = false;
|
|
41
|
+
SynchronizeDateAsync().Forget();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public void Dispose()
|
|
45
|
+
{
|
|
46
|
+
_cancellationSource?.Cancel();
|
|
47
|
+
_cancellationSource?.Dispose();
|
|
48
|
+
_cancellationSource = null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public async UniTask< bool > AwaitSynchronization()
|
|
52
|
+
{
|
|
53
|
+
var aw= await UniTask.WhenAny(
|
|
54
|
+
UniTask.WaitWhile( () => !IsDateSynchronized ),
|
|
55
|
+
UniTask.WaitForSeconds( _awaitTime ) );
|
|
56
|
+
|
|
57
|
+
return aw == 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private async UniTask SynchronizeDateAsync()
|
|
61
|
+
{
|
|
62
|
+
while ( true )
|
|
63
|
+
{
|
|
64
|
+
if ( !IsDateSynchronized )
|
|
65
|
+
{
|
|
66
|
+
if ( Application.internetReachability != NetworkReachability.NotReachable ) //isConnection
|
|
67
|
+
{
|
|
68
|
+
SynchronizeDate();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
await UniTask.WaitForSeconds( _requestTimeout );
|
|
72
|
+
}
|
|
73
|
+
else
|
|
74
|
+
{
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private void SynchronizeDate()
|
|
81
|
+
{
|
|
82
|
+
_syncThread?.Abort();
|
|
83
|
+
_socket?.Close();
|
|
84
|
+
|
|
85
|
+
_cancellationSource?.Cancel();
|
|
86
|
+
_cancellationSource?.Dispose();
|
|
87
|
+
_cancellationSource = new();
|
|
88
|
+
|
|
89
|
+
_responseReceived = false;
|
|
90
|
+
_syncThread = new Thread( Request );
|
|
91
|
+
_syncThread.Start();
|
|
92
|
+
|
|
93
|
+
WaitForResponse( _cancellationSource.Token ).Forget();
|
|
94
|
+
|
|
95
|
+
Debug.Log( "[NTPDateTimeService] request started." );
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
private void Request()
|
|
99
|
+
{
|
|
100
|
+
var ntpData = new byte[48];
|
|
101
|
+
ntpData[ 0 ] = 0x1B;
|
|
102
|
+
|
|
103
|
+
try
|
|
104
|
+
{
|
|
105
|
+
IPAddress[] addresses = Dns.GetHostEntry( _ntpServer ).AddressList;
|
|
106
|
+
var ipEndPoint = new IPEndPoint( addresses[ 0 ], 123 );
|
|
107
|
+
|
|
108
|
+
_socket = new Socket( AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp );
|
|
109
|
+
|
|
110
|
+
_socket.Connect( ipEndPoint );
|
|
111
|
+
_socket.ReceiveTimeout = _requestTimeout * 1000;
|
|
112
|
+
_socket.Send( ntpData );
|
|
113
|
+
_socket.Receive( ntpData );
|
|
114
|
+
}
|
|
115
|
+
catch ( SocketException )
|
|
116
|
+
{
|
|
117
|
+
Debug.LogWarning( "[NTPDateTimeService] sync failed." );
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
finally
|
|
121
|
+
{
|
|
122
|
+
_socket?.Close();
|
|
123
|
+
_socket = null;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
_receivedNtpData = ntpData;
|
|
127
|
+
_responseReceived = true;
|
|
128
|
+
|
|
129
|
+
Debug.Log( "[NTPDateTimeService] response received." );
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
private async UniTask WaitForResponse( CancellationToken token )
|
|
133
|
+
{
|
|
134
|
+
while ( !_responseReceived )
|
|
135
|
+
{
|
|
136
|
+
await UniTask.Yield( cancellationToken: token );
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
_responseReceivedTime = Time.realtimeSinceStartup;
|
|
140
|
+
|
|
141
|
+
ulong intPart = ( (ulong)_receivedNtpData[ 40 ] << 24 ) | ( (ulong)_receivedNtpData[ 41 ] << 16 ) |
|
|
142
|
+
( (ulong)_receivedNtpData[ 42 ] << 8 ) | _receivedNtpData[ 43 ];
|
|
143
|
+
ulong fractPart = ( (ulong)_receivedNtpData[ 44 ] << 24 ) | ( (ulong)_receivedNtpData[ 45 ] << 16 ) |
|
|
144
|
+
( (ulong)_receivedNtpData[ 46 ] << 8 ) | _receivedNtpData[ 47 ];
|
|
145
|
+
|
|
146
|
+
ulong milliseconds = intPart * 1000 + fractPart * 1000 / 0x100000000L;
|
|
147
|
+
_ntpDate = new DateTime( 1900, 1, 1, 0, 0, 0, DateTimeKind.Utc ).AddMilliseconds( (long)milliseconds ).ToLocalTime();
|
|
148
|
+
|
|
149
|
+
IsDateSynchronized = true;
|
|
150
|
+
Debug.Log( "[NTPDateTimeService] Date is synchronized : " + Now );
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
using Zenject;
|
|
2
|
+
|
|
3
|
+
namespace PuzzlescapeGames.Services.NTPService
|
|
4
|
+
{
|
|
5
|
+
public sealed class NTPServiceInstaller : Installer< NTPServiceInstaller >
|
|
6
|
+
{
|
|
7
|
+
public override void InstallBindings()
|
|
8
|
+
{
|
|
9
|
+
Container.BindInterfacesTo< NTPService >().AsSingle().NonLazy();
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
using Cysharp.Threading.Tasks;
|
|
2
|
+
using PuzzlescapeGames.Extensions;
|
|
3
|
+
using System;
|
|
4
|
+
using System.Threading;
|
|
5
|
+
|
|
6
|
+
namespace PuzzlescapeGames.Services.TickableService
|
|
7
|
+
{
|
|
8
|
+
public sealed class TickableService
|
|
9
|
+
{
|
|
10
|
+
public event Action OnSecondsTick;
|
|
11
|
+
|
|
12
|
+
public TickableService()
|
|
13
|
+
{
|
|
14
|
+
SecondsTick( ThreadingUtils.QuitToken ).Forget();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
private async UniTask SecondsTick( CancellationToken token )
|
|
18
|
+
{
|
|
19
|
+
bool isCanceled = false;
|
|
20
|
+
|
|
21
|
+
while ( !isCanceled )
|
|
22
|
+
{
|
|
23
|
+
OnSecondsTick?.Invoke();
|
|
24
|
+
|
|
25
|
+
isCanceled = await UniTask.WaitForSeconds( 1f, cancellationToken: token ).SuppressCancellationThrow();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
using Zenject;
|
|
2
|
+
|
|
3
|
+
namespace PuzzlescapeGames.Services.TickableService
|
|
4
|
+
{
|
|
5
|
+
public sealed class TickableServiceInstaller : Installer< TickableServiceInstaller >
|
|
6
|
+
{
|
|
7
|
+
public override void InstallBindings()
|
|
8
|
+
{
|
|
9
|
+
Container.Bind< TickableService >().AsSingle().NonLazy();
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using UnityEngine;
|
|
3
|
+
|
|
4
|
+
namespace PuzzlescapeGames.Services.UIBlockingService
|
|
5
|
+
{
|
|
6
|
+
public sealed class UIBlocker : MonoBehaviour
|
|
7
|
+
{
|
|
8
|
+
public event Action OnButtonClicked;
|
|
9
|
+
|
|
10
|
+
public void OnButtonClick()
|
|
11
|
+
{
|
|
12
|
+
OnButtonClicked?.Invoke();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using Object = UnityEngine.Object;
|
|
3
|
+
|
|
4
|
+
namespace PuzzlescapeGames.Services.UIBlockingService
|
|
5
|
+
{
|
|
6
|
+
public sealed class UIBlockingService
|
|
7
|
+
{
|
|
8
|
+
public event Action OnBlockerClicked
|
|
9
|
+
{
|
|
10
|
+
add => _blocker.OnButtonClicked += value;
|
|
11
|
+
remove => _blocker.OnButtonClicked -= value;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
private readonly UIBlocker _blocker;
|
|
15
|
+
|
|
16
|
+
public UIBlockingService( UIBlocker blockerPrefab )
|
|
17
|
+
{
|
|
18
|
+
if ( blockerPrefab == null )
|
|
19
|
+
throw new ArgumentNullException( nameof(blockerPrefab) );
|
|
20
|
+
|
|
21
|
+
_blocker = Object.Instantiate( blockerPrefab );
|
|
22
|
+
Object.DontDestroyOnLoad( _blocker );
|
|
23
|
+
UnBlockUI();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public void BlockUI()
|
|
27
|
+
{
|
|
28
|
+
_blocker.gameObject.SetActive( true );
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public void UnBlockUI()
|
|
32
|
+
{
|
|
33
|
+
_blocker.gameObject.SetActive( false );
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
using UnityEngine;
|
|
2
|
+
using Zenject;
|
|
3
|
+
|
|
4
|
+
namespace PuzzlescapeGames.Services.UIBlockingService
|
|
5
|
+
{
|
|
6
|
+
[ CreateAssetMenu( fileName = "UIBlockingServiceInstaller", menuName = "Installers/UIBlockingServiceInstaller" ) ]
|
|
7
|
+
public sealed class UIBlockingServiceInstaller : ScriptableObjectInstaller< UIBlockingServiceInstaller >
|
|
8
|
+
{
|
|
9
|
+
[ SerializeField ] private UIBlocker _blocker;
|
|
10
|
+
|
|
11
|
+
public override void InstallBindings()
|
|
12
|
+
{
|
|
13
|
+
Container.BindInstance( _blocker ).WhenInjectedInto< UIBlockingService >();
|
|
14
|
+
Container.BindInterfacesAndSelfTo< UIBlockingService >().AsSingle().NonLazy();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
namespace PuzzlescapeGames.Services.VibrationService
|
|
2
|
+
{
|
|
3
|
+
internal sealed class VibrationService : IVibrationService
|
|
4
|
+
{
|
|
5
|
+
public VibrationService()
|
|
6
|
+
{
|
|
7
|
+
Vibration.Init();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
public void Vibrate()
|
|
11
|
+
{
|
|
12
|
+
#if UNITY_IOS
|
|
13
|
+
Vibration.VibrateIOS( ImpactFeedbackStyle.Soft );
|
|
14
|
+
#elif UNITY_ANDROID
|
|
15
|
+
Vibration.VibratePop();
|
|
16
|
+
#endif
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
using Zenject;
|
|
2
|
+
|
|
3
|
+
namespace PuzzlescapeGames.Services.VibrationService
|
|
4
|
+
{
|
|
5
|
+
public sealed class VibrationServiceInstaller : Installer< VibrationServiceInstaller >
|
|
6
|
+
{
|
|
7
|
+
public override void InstallBindings()
|
|
8
|
+
{
|
|
9
|
+
Container.BindInterfacesTo< VibrationService >().AsSingle();
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|