Unity/Unity 이슈

[IAP] IDE에서 IAP테스트를 하고 싶을 때

lipnus 2021. 11. 17. 14:16
반응형

NullReferenceException: Object reference not set to an instance of an object
UnityEngine.Purchasing.UIFakeStore.InstantiateDialog () (at Library/PackageCache/com.unity.purchasing@3.1.0/Runtime/Stores/FakeStore/UIFakeStore.cs:175)

 

 

코드에는 Prefab을 Instantiate하도록 넣어놨으면서 prefab은 구성요소로 안넣어놨음.

Resources폴더의 UIFakeStoreCanvas.prefab 파일 없음

 

 

 

Solution1


https://forum.unity.com/threads/iap-not-working-debug-window-not-showing-up-due-to-nullreferenceexception.1073807/

 

최신으로 업데이트 하기.

본인의 경우 특정 IAP버전에 겨우겨우 최적화를 해놓았기 때문에 이렇게 못함

 

 

 

Solution2


프리팹이 있기만 하면 됨.

IAP 샘플 프로젝트를 받아서 내부의 프리팹을 복사해서 넣어줌.

 

 

 

GitHub - sassembla/Autoya: thin framework for Unity.

thin framework for Unity. Contribute to sassembla/Autoya development by creating an account on GitHub.

github.com

요거넣으니까 됨. 이거 받아도 된다.

 

 

UIFakeStore.cs

간단한 구조이기 때문에, 코드 보고 그냥 GameObject이름 맞춰서 만들어도 될 것 같음.

/// <summary>
		/// Creates the UI from a prefab. Configures the UI. Shows the dialog. 
		/// </summary>
		private void InstantiateDialog()
		{
			if (m_CurrentDialog == null)
			{
				Debug.LogError(this + " requires m_CurrentDialog. Not showing dialog.");
				return;
			}

			// Load this once
			if (UIFakeStoreCanvasPrefab == null)
			{
				UIFakeStoreCanvasPrefab = Resources.Load("UIFakeStoreCanvas") as GameObject;
			}

			Canvas dialogCanvas = UIFakeStoreCanvasPrefab.GetComponent<Canvas>();

			// To show, and to configure UI, first realize it on screen
			m_Canvas = Object.Instantiate(dialogCanvas);

			// TRICKY: I support one dialog at a time but there's a delay between a request
			// to the UI system to destroy a UI element and the UI system completing the destruction.
			// To avoid conflicts with partially destroyed dialogs hanging around too long we add a 
			// custom behavior to the scene explicitly to notify me when the UI has been destroyed.

			LifecycleNotifier notifier = m_Canvas.gameObject.AddComponent<LifecycleNotifier>() as LifecycleNotifier;
			notifier.OnDestroyCallback = () =>
			{
				// Indicates we've completely closed our dialog
				m_CurrentDialog = null;
			};

			m_ParentGameObjectPath = m_Canvas.name + "/Panel/";

			// Ensure existence of EventSystem for use by UI
			if (Object.FindObjectOfType<EventSystem>() == null)
			{
				// No EventSystem found, create a new one and add to the Canvas
				m_EventSystem = new GameObject("EventSystem", typeof(EventSystem));
				m_EventSystem.AddComponent<StandaloneInputModule>();
				m_EventSystem.transform.parent = m_Canvas.transform;
			}

			// Configure the dialog
			var qt = GameObject.Find(m_ParentGameObjectPath + "HeaderText");
			Text queryTextComponent = qt.GetComponent<Text>();
			queryTextComponent.text = m_CurrentDialog.QueryText;

			Text allowText = GetOkayButtonText();
			allowText.text = m_CurrentDialog.OkayButtonText;

			Text denyText = GetCancelButtonText();
			denyText.text = m_CurrentDialog.CancelButtonText;
		
			// Populate the dropdown
			GetDropdown().options.Clear(); // Assume it has defaults prepopulated
			foreach (var item in m_CurrentDialog.Options)
			{
				GetDropdown().options.Add(new Dropdown.OptionData(item));
			}

			if (m_CurrentDialog.Options.Count > 0)
			{
				m_LastSelectedDropdownIndex = 0;
			}

			// Ensure the dropdown renders its default value
			GetDropdown().RefreshShownValue();

			// Wire up callbacks
			GetOkayButton().onClick.AddListener(() => { 
				this.OkayButtonClicked(); 
			});
			GetCancelButton().onClick.AddListener(() => { 
				this.CancelButtonClicked(); 
			});
			GetDropdown().onValueChanged.AddListener((int selectedItem) => {
				this.DropdownValueChanged(selectedItem);
			});

			// Honor FakeStoreUIMode 
			if (UIMode == FakeStoreUIMode.StandardUser)
			{
				GetDropdown ().onValueChanged.RemoveAllListeners ();
				GameObject.Destroy (GetDropdownContainerGameObject ());
			} 
			else if (UIMode == FakeStoreUIMode.DeveloperUser)
			{
				GetCancelButton().onClick.RemoveAllListeners();
				GameObject.Destroy (GetCancelButtonGameObject ());
			}
		}
반응형