Browse Source

- Доработка модуля покупок для відключення реклами

dll_rework
Seraph 4 years ago
parent
commit
77e3605b77
  1. 7
      Assembly-CSharp.csproj
  2. BIN
      Assets/Prototype/Core/Core.dll
  3. BIN
      Assets/Prototype/Core/CoreEditor.dll
  4. 4
      Assets/Prototype/Custumization/Resources/CoreSettings.asset
  5. 218
      Assets/Prototype/Custumization/Scenes/Test.unity
  6. 40
      Assets_DLL/Core/Ads/AdsManager.cs
  7. 11
      Assets_DLL/Core/Ads/Bridges/DemoAds/DemoInterstitialAds.cs
  8. 22
      Assets_DLL/Core/Ads/Bridges/DemoAds/DemoRewardedAds.cs
  9. 24
      Assets_DLL/Core/Ads/RewardedButton.cs
  10. 2
      Assets_DLL/Core/Audio/AudioController.cs
  11. 4
      Assets_DLL/Core/CoreInitializer.cs
  12. 46
      Assets_DLL/Core/IAP/PurchaseButton.cs
  13. 72
      Assets_DLL/Core/IAP/PurchaseManager.cs
  14. 32
      Assets_DLL/Core/IAP/PurchaseManagerBase.cs
  15. 2
      Assets_DLL/Core/Localization/LocalizationManager.cs
  16. 2
      Assets_DLL/Core/SceneManagement/SceneLoader.cs
  17. 1
      Assets_DLL/Core/Settings/CoreSettingsData.cs
  18. BIN
      Assets_DLL/Core/obj/Debug/netstandard2.0/Core.csproj.AssemblyReference.cache
  19. 2
      Assets_DLL/Core/obj/Debug/netstandard2.0/Core.csproj.CoreCompileInputs.cache
  20. BIN
      Assets_DLL/Core/obj/Debug/netstandard2.0/Core.dll
  21. 47
      Assets_DLL/CoreEditor/IAP/PurchaseButtonEditor.cs
  22. 4
      Assets_DLL/CoreEditor/Localization/TextLocalizatorEditor.cs
  23. 4
      Assets_DLL/CoreEditor/SceneManagement/LoadSceneButtonEditor.cs
  24. 20
      Assets_DLL/CoreEditor/Settings/CoreSettingsWindow.cs
  25. BIN
      Assets_DLL/CoreEditor/obj/Debug/netstandard2.0/CoreEditor.csproj.AssemblyReference.cache
  26. 0
      Assets_DLL/CoreEditor/obj/Debug/netstandard2.0/CoreEditor.csproj.CopyComplete
  27. 2
      Assets_DLL/CoreEditor/obj/Debug/netstandard2.0/CoreEditor.csproj.CoreCompileInputs.cache
  28. BIN
      Assets_DLL/CoreEditor/obj/Debug/netstandard2.0/CoreEditor.dll
  29. 2
      Packages/manifest.json
  30. 2
      Packages/packages-lock.json

7
Assembly-CSharp.csproj

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<LangVersion>latest</LangVersion> <LangVersion>7.3</LangVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -47,11 +47,14 @@
<PropertyGroup> <PropertyGroup>
<ProjectTypeGuids>{E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> <ProjectTypeGuids>{E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<UnityProjectGenerator>Package</UnityProjectGenerator> <UnityProjectGenerator>Package</UnityProjectGenerator>
<UnityProjectGeneratorVersion>2.0.11</UnityProjectGeneratorVersion> <UnityProjectGeneratorVersion>2.0.15</UnityProjectGeneratorVersion>
<UnityProjectType>Game:1</UnityProjectType> <UnityProjectType>Game:1</UnityProjectType>
<UnityBuildTarget>Android:13</UnityBuildTarget> <UnityBuildTarget>Android:13</UnityBuildTarget>
<UnityVersion>2019.4.28f1</UnityVersion> <UnityVersion>2019.4.28f1</UnityVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<Analyzer Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\Extensions\Microsoft\Visual Studio Tools for Unity\Analyzers\Microsoft.Unity.Analyzers.dll" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Assets\Prototype\DOTween\Modules\DOTweenModuleAudio.cs" /> <Compile Include="Assets\Prototype\DOTween\Modules\DOTweenModuleAudio.cs" />
<Compile Include="Assets\Prototype\DOTween\Modules\DOTweenModuleEPOOutline.cs" /> <Compile Include="Assets\Prototype\DOTween\Modules\DOTweenModuleEPOOutline.cs" />

BIN
Assets/Prototype/Core/Core.dll

Binary file not shown.

BIN
Assets/Prototype/Core/CoreEditor.dll

Binary file not shown.

4
Assets/Prototype/Custumization/Resources/CoreSettings.asset

@ -30,7 +30,9 @@ MonoBehaviour:
- scene: Test - scene: Test
positions: 4 positions: 4
consumableProducts: [] consumableProducts: []
nonConsumableProducts: [] nonConsumableProducts:
- noads
nonConsumableProductsDisableAds: 010000000000
localizationTable: {fileID: 4900000, guid: 8906a0d6652cf524d95c802bef1d0b88, type: 3} localizationTable: {fileID: 4900000, guid: 8906a0d6652cf524d95c802bef1d0b88, type: 3}
availableLanguages: 1e000000260000000a000000 availableLanguages: 1e000000260000000a000000
musicVolume: 0.5 musicVolume: 0.5

218
Assets/Prototype/Custumization/Scenes/Test.unity

@ -280,6 +280,7 @@ RectTransform:
- {fileID: 1370401863} - {fileID: 1370401863}
- {fileID: 1127382359} - {fileID: 1127382359}
- {fileID: 1630259401} - {fileID: 1630259401}
- {fileID: 1095112902}
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_RootOrder: 1 m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@ -288,6 +289,145 @@ RectTransform:
m_AnchoredPosition: {x: 0, y: 0} m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0} m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 0} m_Pivot: {x: 0, y: 0}
--- !u!1 &1095112901
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1095112902}
- component: {fileID: 1095112906}
- component: {fileID: 1095112905}
- component: {fileID: 1095112904}
- component: {fileID: 1095112903}
m_Layer: 5
m_Name: PurchaseButton
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1095112902
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1095112901}
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: 1397823467}
m_Father: {fileID: 892138056}
m_RootOrder: 3
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: 0, y: -150}
m_SizeDelta: {x: 450, y: 75}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1095112903
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1095112901}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -53964576, guid: 2fd26ea99448fca48804f673704d54b7, type: 3}
m_Name:
m_EditorClassIdentifier:
_productId: noads
_onSucces:
m_PersistentCalls:
m_Calls: []
_onFailed:
m_PersistentCalls:
m_Calls: []
--- !u!114 &1095112904
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1095112901}
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: 1095112905}
m_OnClick:
m_PersistentCalls:
m_Calls: []
--- !u!114 &1095112905
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1095112901}
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_Maskable: 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 &1095112906
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1095112901}
m_CullTransparentMesh: 0
--- !u!1 &1127382358 --- !u!1 &1127382358
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -514,6 +654,84 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1370401862} m_GameObject: {fileID: 1370401862}
m_CullTransparentMesh: 0 m_CullTransparentMesh: 0
--- !u!1 &1397823466
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1397823467}
- component: {fileID: 1397823469}
- component: {fileID: 1397823468}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1397823467
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1397823466}
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: 1095112902}
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 &1397823468
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1397823466}
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_Maskable: 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: 1
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: Purchase NoADS
--- !u!222 &1397823469
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1397823466}
m_CullTransparentMesh: 0
--- !u!1 &1465904771 --- !u!1 &1465904771
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

40
Assets_DLL/Core/Ads/AdsManager.cs

@ -3,6 +3,7 @@ using UnityEngine;
using Core.Settings; using Core.Settings;
using Core.Ads.BridgeInterfaces; using Core.Ads.BridgeInterfaces;
using Core.Ads.Bridges.DemoAds; using Core.Ads.Bridges.DemoAds;
using Core.IAP;
namespace Core.Ads namespace Core.Ads
{ {
@ -14,7 +15,7 @@ namespace Core.Ads
private static IRewardedBridge _rewarded = null; private static IRewardedBridge _rewarded = null;
private static IBannerBridge _banner = null; private static IBannerBridge _banner = null;
public static void Init() internal static void Init()
{ {
GameObject holder = new GameObject("[AdsManager]"); GameObject holder = new GameObject("[AdsManager]");
@ -57,6 +58,15 @@ namespace Core.Ads
if (_banner == null) if (_banner == null)
throw new NullReferenceException("ads bridge object does not implement IBannerBridge"); throw new NullReferenceException("ads bridge object does not implement IBannerBridge");
PurchaseManager.OnPurchaseSuccess += (productId) =>
{
if (!CoreSettings.data.nonConsumableProducts.Contains(productId))
return;
if (CoreSettings.data.nonConsumableProductsDisableAds[CoreSettings.data.nonConsumableProducts.IndexOf(productId)])
HideBanner();
};
} }
if (CoreSettings.data.needRewarded) if (CoreSettings.data.needRewarded)
@ -69,10 +79,26 @@ namespace Core.Ads
if (_rewarded == null) if (_rewarded == null)
throw new NullReferenceException("ads bridge object does not implement IRewardedBridge"); throw new NullReferenceException("ads bridge object does not implement IRewardedBridge");
} }
}
public static bool IsAdsDisabled()
{
for (int i = 0; i < CoreSettings.data.nonConsumableProducts.Count; i++)
{
if (CoreSettings.data.nonConsumableProductsDisableAds[i] && PurchaseManager.IsProductPurchased(CoreSettings.data.nonConsumableProducts[i]))
return true;
}
return false;
} }
public static bool IsInterstitialReady() public static bool IsInterstitialReady()
{ {
if (IsAdsDisabled())
return false;
if (_interstitial == null) if (_interstitial == null)
throw new NullReferenceException("ads bridge object does not implement IInterstitialBridge"); throw new NullReferenceException("ads bridge object does not implement IInterstitialBridge");
@ -95,6 +121,9 @@ namespace Core.Ads
public static void ShowInterstitial() public static void ShowInterstitial()
{ {
if (IsAdsDisabled())
return;
if (_interstitial == null) if (_interstitial == null)
throw new NullReferenceException("ads bridge object does not implement IInterstitialBridge"); throw new NullReferenceException("ads bridge object does not implement IInterstitialBridge");
@ -106,6 +135,9 @@ namespace Core.Ads
public static bool IsRewardedReady() public static bool IsRewardedReady()
{ {
if (IsAdsDisabled())
return false;
if (_rewarded == null) if (_rewarded == null)
throw new NullReferenceException("ads bridge object does not implement IRewardedBridge"); throw new NullReferenceException("ads bridge object does not implement IRewardedBridge");
@ -117,6 +149,9 @@ namespace Core.Ads
public static void ShowRewarded(Action onSucces, Action onFailed) public static void ShowRewarded(Action onSucces, Action onFailed)
{ {
if (IsAdsDisabled())
return;
if (_rewarded == null) if (_rewarded == null)
throw new NullReferenceException("ads bridge object does not implement IRewardedBridge"); throw new NullReferenceException("ads bridge object does not implement IRewardedBridge");
@ -141,6 +176,9 @@ namespace Core.Ads
public static void ShowBanner(BannerPositions position) public static void ShowBanner(BannerPositions position)
{ {
if (IsAdsDisabled())
return;
if (_banner == null) if (_banner == null)
throw new NullReferenceException("ads bridge object does not implement IBannerBridge"); throw new NullReferenceException("ads bridge object does not implement IBannerBridge");

11
Assets_DLL/Core/Ads/Bridges/DemoAds/DemoInterstitialAds.cs

@ -19,7 +19,10 @@ namespace Core.Ads.Bridges.DemoAds
if (_isVisible) if (_isVisible)
{ {
if (GUI.Button(new Rect(0f, 0f, Screen.width, Screen.height), "Interstitial Demo Ads")) if (GUI.Button(new Rect(0f, 0f, Screen.width, Screen.height), "Interstitial Demo Ads"))
CloseInterstitial(); {
_isVisible = false;
OnEnded?.Invoke();
}
} }
} }
@ -43,12 +46,6 @@ namespace Core.Ads.Bridges.DemoAds
Debug.LogError("AdsManager: Interstitial ads is not ready"); Debug.LogError("AdsManager: Interstitial ads is not ready");
} }
private void CloseInterstitial()
{
_isVisible = false;
OnEnded?.Invoke();
}
private IEnumerator InterstitialTimer() private IEnumerator InterstitialTimer()
{ {
_isInterstitialReady = false; _isInterstitialReady = false;

22
Assets_DLL/Core/Ads/Bridges/DemoAds/DemoRewardedAds.cs

@ -16,10 +16,16 @@ namespace Core.Ads.Bridges.DemoAds
if (_isVisible) if (_isVisible)
{ {
if (GUI.Button(new Rect(0f, 0f, Screen.width, Screen.height / 2f), "Rewarded success")) if (GUI.Button(new Rect(0f, 0f, Screen.width, Screen.height / 2f), "Rewarded success"))
OnSuccesClick(); {
onSucces?.Invoke();
_isVisible = false;
}
if (GUI.Button(new Rect(0f, Screen.height / 2f, Screen.width, Screen.height / 2f), "Rewarded close")) if (GUI.Button(new Rect(0f, Screen.height / 2f, Screen.width, Screen.height / 2f), "Rewarded close"))
OnFailedClick(); {
onFailed?.Invoke();
_isVisible = false;
}
} }
} }
@ -32,17 +38,5 @@ namespace Core.Ads.Bridges.DemoAds
_isVisible = true; _isVisible = true;
} }
private void OnSuccesClick()
{
onSucces?.Invoke();
_isVisible = false;
}
private void OnFailedClick()
{
onFailed?.Invoke();
_isVisible = false;
}
} }
} }

24
Assets_DLL/Core/Ads/RewardedButton.cs

@ -1,4 +1,6 @@
using Core.Ads; using Core.Ads;
using Core.IAP;
using Core.Settings;
using UnityEngine; using UnityEngine;
using UnityEngine.Events; using UnityEngine.Events;
using UnityEngine.UI; using UnityEngine.UI;
@ -31,5 +33,27 @@ namespace Core.Ads
); );
}); });
} }
private void OnEnable()
{
PurchaseManager.OnPurchaseSuccess += CheckAdsEnablingAfterPurchasing;
if (AdsManager.IsAdsDisabled())
gameObject.SetActive(false);
}
private void OnDisable()
{
PurchaseManager.OnPurchaseSuccess -= CheckAdsEnablingAfterPurchasing;
}
private void CheckAdsEnablingAfterPurchasing(string productId)
{
if (!CoreSettings.data.nonConsumableProducts.Contains(productId))
return;
if (CoreSettings.data.nonConsumableProductsDisableAds[CoreSettings.data.nonConsumableProducts.IndexOf(productId)])
gameObject.SetActive(false);
}
} }
} }

2
Assets_DLL/Core/Audio/AudioController.cs

@ -6,7 +6,7 @@ using Core.Settings;
public static class AudioController public static class AudioController
{ {
public static void Init() internal static void Init()
{ {
GameObject audioParent = new GameObject("[AudioController]"); GameObject audioParent = new GameObject("[AudioController]");

4
Assets_DLL/Core/CoreInitializer.cs

@ -2,14 +2,16 @@
using Core.SceneManagement; using Core.SceneManagement;
using Core.Ads; using Core.Ads;
using Core.Localization; using Core.Localization;
using Core.IAP;
namespace Core namespace Core
{ {
public sealed class CoreInitializer internal sealed class CoreInitializer
{ {
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
private static void Init() private static void Init()
{ {
PurchaseManager.Init();
AdsManager.Init(); AdsManager.Init();
LocalizationManager.Init(); LocalizationManager.Init();
AudioController.Init(); AudioController.Init();

46
Assets_DLL/Core/IAP/PurchaseButton.cs

@ -0,0 +1,46 @@
using Core.Ads;
using Core.IAP;
using Core.Settings;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
namespace Core.Ads
{
[RequireComponent(typeof(Button))]
public sealed class PurchaseButton : MonoBehaviour
{
[SerializeField] private string _productId = "";
[SerializeField] private UnityEvent _onSucces = null;
[SerializeField] private UnityEvent _onFailed = null;
private void Awake()
{
Button button = GetComponent<Button>();
button.onClick.AddListener(() =>
{
PurchaseManager.Buy(_productId);
});
}
private void OnEnable()
{
PurchaseManager.OnPurchaseSuccess += CheckAdsEnablingAfterPurchasing;
if (PurchaseManager.IsProductPurchased(_productId))
gameObject.SetActive(false);
}
private void OnDisable()
{
PurchaseManager.OnPurchaseSuccess -= CheckAdsEnablingAfterPurchasing;
}
private void CheckAdsEnablingAfterPurchasing(string productId)
{
if (_productId == productId)
gameObject.SetActive(false);
}
}
}

72
Assets_DLL/Core/IAP/PurchaseManager.cs

@ -0,0 +1,72 @@
using System;
using UnityEngine;
using UnityEngine.Purchasing;
namespace Core.IAP
{
public sealed class PurchaseManager : MonoBehaviour
{
private static PurchaseManager _instance = null;
private static PurchaseManagerBase _purchaseManager = null;
public static event Action<string> OnPurchaseSuccess = null;
public static event Action<string, PurchaseFailureReason> OnPurchaseFailed = null;
internal static void Init()
{
GameObject gameObject = new GameObject("[SceneLoader]");
_instance = gameObject.AddComponent<PurchaseManager>();
DontDestroyOnLoad(_instance);
_purchaseManager = new PurchaseManagerBase();
_purchaseManager.InitializePurchasing();
_purchaseManager.OnPurchaseSuccess += (productId) => OnPurchaseSuccess(productId);
_purchaseManager.OnPurchaseFaile += (productId, error) => OnPurchaseFailed(productId, error);
}
public static bool IsProductPurchased(string productId) =>
_purchaseManager.IsProductPurchased(productId);
public static string GetLocalizedPrice(string productId) =>
_purchaseManager.GetLocalizedPrice(productId);
public static void Buy(string productId)
{
if (Application.isEditor)
_instance.TryPurchaseInEditor(productId);
else
_purchaseManager.BuyProduct(productId);
}
private bool _isVisible = false;
private string _productId = "";
private void OnGUI()
{
if (_isVisible && !string.IsNullOrWhiteSpace(_productId))
{
if (GUI.Button(new Rect(0f, 0f, Screen.width, Screen.height / 2f), $"Confirm purchasing \"{_productId}\""))
{
_purchaseManager.BuyProduct(_productId);
_productId = "";
_isVisible = false;
}
if (GUI.Button(new Rect(0f, Screen.height / 2f, Screen.width, Screen.height / 2f), "Cancel purchasing"))
{
OnPurchaseFailed?.Invoke(_productId, PurchaseFailureReason.UserCancelled);
_productId = "";
_isVisible = false;
}
}
}
private void TryPurchaseInEditor(string productId)
{
_productId = productId;
_isVisible = true;
}
}
}

32
Assets_DLL/Core/IAP/PurchaseManagerBase.cs

@ -5,14 +5,17 @@ using UnityEngine.Purchasing;
namespace Core.IAP namespace Core.IAP
{ {
public sealed class PurchaseManagerBase : IStoreListener internal sealed class PurchaseManagerBase : IStoreListener
{ {
public event Action<string> OnPurchaseSuccess; public event Action<string> OnPurchaseSuccess;
public event Action<Product, PurchaseFailureReason> OnPurchaseFaile; public event Action<string, PurchaseFailureReason> OnPurchaseFaile;
private IStoreController _storeController; private IStoreController _storeController;
private IExtensionProvider _storeExtensionProvider; private IExtensionProvider _storeExtensionProvider;
private bool IsInitialized =>
_storeController != null && _storeExtensionProvider != null;
public bool IsProductPurchased(string productID) => public bool IsProductPurchased(string productID) =>
PlayerPrefs.GetString(productID.ToString() + "_purchased", "false") == "true"; PlayerPrefs.GetString(productID.ToString() + "_purchased", "false") == "true";
@ -29,15 +32,12 @@ namespace Core.IAP
UnityPurchasing.Initialize(this, builder); UnityPurchasing.Initialize(this, builder);
} }
public bool IsInitialized()
{
return _storeController != null && _storeExtensionProvider != null;
}
public void BuyProduct(string productId) public void BuyProduct(string productId)
{ {
if (Application.isEditor) if (Application.isEditor)
{ {
PlayerPrefs.SetString(productId + "_purchased", "true");
if (OnPurchaseSuccess != null) if (OnPurchaseSuccess != null)
OnPurchaseSuccess(productId); OnPurchaseSuccess(productId);
@ -46,7 +46,7 @@ namespace Core.IAP
return; return;
} }
if (IsInitialized()) if (IsInitialized)
{ {
Product product = _storeController.products.WithID(productId); Product product = _storeController.products.WithID(productId);
@ -68,7 +68,7 @@ namespace Core.IAP
if (Application.isEditor) if (Application.isEditor)
return "0.99$"; return "0.99$";
if (IsInitialized()) if (IsInitialized)
{ {
string price = _storeController.products.WithID(productID).metadata.localizedPriceString; string price = _storeController.products.WithID(productID).metadata.localizedPriceString;
@ -82,7 +82,7 @@ namespace Core.IAP
public void OnInitialized(IStoreController controller, IExtensionProvider extensions) public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
{ {
Debug.Log("OnInitialized: PASS"); Debug.Log("OnInitialized IAP");
_storeController = controller; _storeController = controller;
_storeExtensionProvider = extensions; _storeExtensionProvider = extensions;
@ -94,15 +94,15 @@ namespace Core.IAP
GetLocalizedPrice(product); GetLocalizedPrice(product);
} }
public void OnInitializeFailed(InitializationFailureReason error) public void OnInitializeFailed(InitializationFailureReason error) =>
{
Debug.Log("OnInitializeFailed InitializationFailureReason:" + error); Debug.Log("OnInitializeFailed InitializationFailureReason:" + error);
}
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs purchaseEvent) public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs purchaseEvent)
{ {
string productId = purchaseEvent.purchasedProduct.definition.id; string productId = purchaseEvent.purchasedProduct.definition.id;
PlayerPrefs.SetString(productId + "_purchased", "true");
OnPurchaseSuccess?.Invoke(productId); OnPurchaseSuccess?.Invoke(productId);
Debug.Log(productId + " Buyed!"); Debug.Log(productId + " Buyed!");
@ -112,9 +112,11 @@ namespace Core.IAP
public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason) public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason)
{ {
OnPurchaseFaile?.Invoke(product, failureReason); string productId = product.definition.storeSpecificId;
OnPurchaseFaile?.Invoke(productId, failureReason);
Debug.Log(string.Format("OnPurchaseFailed: FAIL. Product: '{0}', PurchaseFailureReason: {1}", product.definition.storeSpecificId, failureReason)); Debug.Log(string.Format("OnPurchaseFailed: FAIL. Product: '{0}', PurchaseFailureReason: {1}", productId, failureReason));
} }
} }
} }

2
Assets_DLL/Core/Localization/LocalizationManager.cs

@ -51,7 +51,7 @@ namespace Core.Localization
} }
} }
public static void Init() internal static void Init()
{ {
if (CoreSettings.data.localizationTable != null) if (CoreSettings.data.localizationTable != null)
{ {

2
Assets_DLL/Core/SceneManagement/SceneLoader.cs

@ -23,7 +23,7 @@ namespace Core.SceneManagement
private static bool _isSceneLoading = false; private static bool _isSceneLoading = false;
public static void Init() internal static void Init()
{ {
GameObject gameObject = new GameObject("[SceneLoader]"); GameObject gameObject = new GameObject("[SceneLoader]");
_instance = gameObject.AddComponent<SceneLoader>(); _instance = gameObject.AddComponent<SceneLoader>();

1
Assets_DLL/Core/Settings/CoreSettingsData.cs

@ -49,6 +49,7 @@ namespace Core.Settings
public List<string> consumableProducts = new List<string>(); public List<string> consumableProducts = new List<string>();
public List<string> nonConsumableProducts = new List<string>(); public List<string> nonConsumableProducts = new List<string>();
public List<bool> nonConsumableProductsDisableAds = new List<bool>();
#endregion #endregion

BIN
Assets_DLL/Core/obj/Debug/netstandard2.0/Core.csproj.AssemblyReference.cache

Binary file not shown.

2
Assets_DLL/Core/obj/Debug/netstandard2.0/Core.csproj.CoreCompileInputs.cache

@ -1 +1 @@
0321155518328e34ad4bff3066618efe2296813f f6ca9d77415befe9f9b6e116c90544ba7c334a44

BIN
Assets_DLL/Core/obj/Debug/netstandard2.0/Core.dll

Binary file not shown.

47
Assets_DLL/CoreEditor/IAP/PurchaseButtonEditor.cs

@ -0,0 +1,47 @@
using Core.Ads;
using Core.Settings;
using System.Collections.Generic;
using UnityEditor;
namespace CoreEditor.Localization
{
[CustomEditor(typeof(PurchaseButton))]
public sealed class PurchaseButtonEditor : Editor
{
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.Space(5);
SerializedProperty productId = serializedObject.FindProperty("_productId");
List<string> products = new List<string>();
products.AddRange(CoreSettings.data.consumableProducts);
products.AddRange(CoreSettings.data.nonConsumableProducts);
int currentIndex = products.IndexOf(productId.stringValue);
if (currentIndex < 0 || currentIndex >= products.Count)
currentIndex = 0;
if (products.Count == 0)
products = new List<string> { "None" };
currentIndex = EditorGUILayout.Popup("Product ID:", currentIndex, products.ToArray());
productId.stringValue = products[currentIndex];
EditorGUILayout.Space(10);
EditorGUILayout.PropertyField(serializedObject.FindProperty("_onSucces"));
EditorGUILayout.Space(5);
EditorGUILayout.PropertyField(serializedObject.FindProperty("_onFailed"));
serializedObject.ApplyModifiedProperties();
}
}
}

4
Assets_DLL/CoreEditor/Localization/TextLocalizatorEditor.cs

@ -12,6 +12,8 @@ namespace CoreEditor.Localization
{ {
serializedObject.Update(); serializedObject.Update();
EditorGUILayout.Space(5);
SerializedProperty key = serializedObject.FindProperty("_key"); SerializedProperty key = serializedObject.FindProperty("_key");
List<string> keys = (List<string>)LocalizationManager.Keys; List<string> keys = (List<string>)LocalizationManager.Keys;
@ -28,6 +30,8 @@ namespace CoreEditor.Localization
key.stringValue = keys[currentIndex]; key.stringValue = keys[currentIndex];
EditorGUILayout.Space(5);
serializedObject.ApplyModifiedProperties(); serializedObject.ApplyModifiedProperties();
} }
} }

4
Assets_DLL/CoreEditor/SceneManagement/LoadSceneButtonEditor.cs

@ -12,10 +12,14 @@ namespace CoreEditor.SceneManagement
{ {
serializedObject.Update(); serializedObject.Update();
EditorGUILayout.Space(5);
SerializedProperty scene = serializedObject.FindProperty("_scene"); SerializedProperty scene = serializedObject.FindProperty("_scene");
scene.stringValue = CoreGUILayout.ScenesPopup("Scene: ", scene.stringValue); scene.stringValue = CoreGUILayout.ScenesPopup("Scene: ", scene.stringValue);
EditorGUILayout.Space(5);
serializedObject.ApplyModifiedProperties(); serializedObject.ApplyModifiedProperties();
} }
} }

20
Assets_DLL/CoreEditor/Settings/CoreSettingsWindow.cs

@ -202,7 +202,7 @@ namespace CoreEditor.Settings
_coreSettings.interstitialSettings[i] = CoreGUILayout.ScenesPopup(_coreSettings.interstitialSettings[i]); _coreSettings.interstitialSettings[i] = CoreGUILayout.ScenesPopup(_coreSettings.interstitialSettings[i]);
if (GUILayout.Button("Remove")) if (GUILayout.Button("Remove", GUILayout.MaxWidth(128)))
_coreSettings.interstitialSettings.RemoveAt(i); _coreSettings.interstitialSettings.RemoveAt(i);
EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal();
@ -242,7 +242,7 @@ namespace CoreEditor.Settings
CoreSettings.data.bannerSettings[i] = setting; CoreSettings.data.bannerSettings[i] = setting;
if (GUILayout.Button("Remove")) if (GUILayout.Button("Remove", GUILayout.MaxWidth(128)))
_coreSettings.bannerSettings.RemoveAt(i); _coreSettings.bannerSettings.RemoveAt(i);
EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal();
@ -302,7 +302,7 @@ namespace CoreEditor.Settings
_coreSettings.loadingScreenForRandom[i] = (LoadingScreen)EditorGUILayout.ObjectField(_coreSettings.loadingScreenForRandom[i], typeof(LoadingScreen), false); _coreSettings.loadingScreenForRandom[i] = (LoadingScreen)EditorGUILayout.ObjectField(_coreSettings.loadingScreenForRandom[i], typeof(LoadingScreen), false);
if (GUILayout.Button("Remove")) if (GUILayout.Button("Remove", GUILayout.MaxWidth(128)))
_coreSettings.loadingScreenForRandom.RemoveAt(i); _coreSettings.loadingScreenForRandom.RemoveAt(i);
EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal();
@ -509,7 +509,7 @@ namespace CoreEditor.Settings
_coreSettings.consumableProducts[i] = GUILayout.TextField(_coreSettings.consumableProducts[i]); _coreSettings.consumableProducts[i] = GUILayout.TextField(_coreSettings.consumableProducts[i]);
if (GUILayout.Button("Remove")) if (GUILayout.Button("Remove", GUILayout.MaxWidth(128)))
_coreSettings.consumableProducts.RemoveAt(i); _coreSettings.consumableProducts.RemoveAt(i);
EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal();
@ -541,8 +541,15 @@ namespace CoreEditor.Settings
_coreSettings.nonConsumableProducts[i] = GUILayout.TextField(_coreSettings.nonConsumableProducts[i]); _coreSettings.nonConsumableProducts[i] = GUILayout.TextField(_coreSettings.nonConsumableProducts[i]);
if (GUILayout.Button("Remove")) GUILayout.Space(5);
_coreSettings.nonConsumableProductsDisableAds[i] = GUILayout.Toggle(_coreSettings.nonConsumableProductsDisableAds[i], " Disable ADS", GUILayout.MaxWidth(128));
if (GUILayout.Button("Remove", GUILayout.MaxWidth(128)))
{
_coreSettings.nonConsumableProducts.RemoveAt(i); _coreSettings.nonConsumableProducts.RemoveAt(i);
_coreSettings.nonConsumableProductsDisableAds.RemoveAt(i);
}
EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal();
} }
@ -550,7 +557,10 @@ namespace CoreEditor.Settings
GUILayout.Space(5); GUILayout.Space(5);
if (GUILayout.Button("Add")) if (GUILayout.Button("Add"))
{
_coreSettings.nonConsumableProducts.Add("ProductID"); _coreSettings.nonConsumableProducts.Add("ProductID");
_coreSettings.nonConsumableProductsDisableAds.Add(false);
}
EditorGUILayout.EndVertical(); EditorGUILayout.EndVertical();
} }

BIN
Assets_DLL/CoreEditor/obj/Debug/netstandard2.0/CoreEditor.csproj.AssemblyReference.cache

Binary file not shown.

0
Assets_DLL/CoreEditor/obj/Debug/netstandard2.0/CoreEditor.csproj.CopyComplete

2
Assets_DLL/CoreEditor/obj/Debug/netstandard2.0/CoreEditor.csproj.CoreCompileInputs.cache

@ -1 +1 @@
3e580022314eb2bd79ab49c90af6937d4423889c 11bcacb5e6198468d31724d89237cbc3f0ee9953

BIN
Assets_DLL/CoreEditor/obj/Debug/netstandard2.0/CoreEditor.dll

Binary file not shown.

2
Packages/manifest.json

@ -6,7 +6,7 @@
"com.unity.analytics": "3.3.5", "com.unity.analytics": "3.3.5",
"com.unity.collab-proxy": "1.8.0", "com.unity.collab-proxy": "1.8.0",
"com.unity.ide.rider": "1.2.1", "com.unity.ide.rider": "1.2.1",
"com.unity.ide.visualstudio": "2.0.11", "com.unity.ide.visualstudio": "2.0.15",
"com.unity.ide.vscode": "1.2.3", "com.unity.ide.vscode": "1.2.3",
"com.unity.multiplayer-hlapi": "1.0.8", "com.unity.multiplayer-hlapi": "1.0.8",
"com.unity.purchasing": "3.2.2", "com.unity.purchasing": "3.2.2",

2
Packages/packages-lock.json

@ -54,7 +54,7 @@
"url": "https://packages.unity.com" "url": "https://packages.unity.com"
}, },
"com.unity.ide.visualstudio": { "com.unity.ide.visualstudio": {
"version": "2.0.11", "version": "2.0.15",
"depth": 0, "depth": 0,
"source": "registry", "source": "registry",
"dependencies": { "dependencies": {

Loading…
Cancel
Save