목차

반응형

공을 쏴서 장애물로 바뀌고 장애물을 제거하면서 버텨나가는 하이퍼 캐쥬얼 장르의 게임을 출시하였는데 구현하는데 생각보다  어려웠고 구현하기 힘들었던 부분들을 정리하고자 한다.

어째서인지 국내 안드로이드 마켓에서는 검색이 되지 않는다...

 

 

https://play.google.com/store/apps/details?id=com.percent.jjtan

불러오는 중입니다...

https://itunes.apple.com/app/id1459980112

불러오는 중입니다...

 

목차는 아래와 같다.

JJTAN 개발 리뷰 시리즈

1. 프로토타입 수준의 오브젝트 및 환경 설정
2. 공 발사하는 캐논 설정
3. 인풋 설정, 공 발사
4. 장애물 생성
5. 장애물 적합한 사이즈 찾기
6. 장애물 색깔 그라데이션
7. 위험한 상황 줌인
8. 사망 판정
9. 데이터 저장과 이어하기
10. 한번 더 하기

추가 개발
튕기는 반사각 계산

 

원래 게임의 주인공이었으나 밀려난 비운의 주인공...

반응형
반응형

Problem

Attched collider 2d script, physical object loose bouncy after few bounce and slide along surface.

It would be easy to understand if you have a look at the video below.

 

 

reproduce project setting

 

 

 

reproduce project setting 

Test project looks like above, has 4 2d box collider and a circle collider which bounces inside a box.

 

 

 

attched script of a circle

The script just give a force on start of the project.

 

 

 

 

Physics Material 2D applied to walls and a circle.

This Physics Material 2D make the circle loose it's force gradually.

 

 

Cause

Theres is a setting in Unity Physics 2D which consider collision to inelastic collision, called velocity threshold.

 

 

 

 

 

Edit > Project Settings > Pysics (2D) > Velocity Threshold

When a collision has lower velocity than the threshold preset. It is considered as an inelastic collision.

 

 

 

Solution

Lower the Velocity Threshold value.

 

 

Result

The circle bounces well though has slow velocity

 

반응형
반응형

문제

유니티 포톤 연동 과정에서 에디터 애플리케이션과 빌드 애플리케이션 간의 연동이 안 되는 경우가 발생했다.

이해가 안되는 부분은 다음과 같다.

 

안드로이드 애플리케이션

노트북으로 작업중인 윈도 애플리케이션

맥 에디터 애플리케이션

 

위의 3개 애플리케이션간의 서버 접속은 잘 되지만

맥에서 빌드한 응용 애플리케이션은 자꾸 마스터가 되어서 방에 입장하지 않는 것이다.

 

원인

원인을 찾던 도중 region 설정이 가능하다는 것을 알았다.

마침 내가 맥을 영어 버전으로 사용하고 있던 것이 원이이었던 것일까 region을 하나로 통일하니까 잘 되었다.

 

해결

서버 세팅에서 fixed region을 하나로 바꾸니까 접속이 잘 된다.

반응형
반응형

오류

유니티에서 ios 빌드 xocde 프로젝트를 빌드하면 Mopub.h File Not Found 같은 오류가 나는 경우가 있다.

 

또는 프레임워크의 CocoaPods 설치 오류로 인하여

unity Setting up CocoaPods master repo fatal: not a git repository (or any of the parent directories): .git [!] The `master` repo is not a git repo. 

오류가 발생하는 경우가 있다.

 

원인

근본적인 원인은 유니티 ios 빌드하는 경우 cocoapods에 문제가 발생하여 프레임워크가 xcode 프로젝트에 정상적으로 안들어간 상태에서 빌드하는 경우 오류가 발생하였다.

cocoapods 문제로 mopub 광고 프레임워크가 xcode 프로젝트에 정상적으로 들어가지 않은 것 이다.

 

해결

해결하기 위해서는 cocoapods 재설치가 제일 깔끔한 것 같다.

먼저 문제가 있는지 확인을 하기 위하여 아래 디렉토리로 이동한다.

 

pod 파일이 있는 디렉토리로 이동

cd /Users/계정이름/.gem/ruby/2.3.0/bin/

 

pod setup 명령어를 치면 오류가 발생한다.(유니티에서도 위와 같은 오류가 발생 할 것이다.)

./pod setup 명령어를 쳐보면 문제가 있는지 확인 가능하다.

 

cocoapods 제거

sudo gem uninstall cocoapods 명령어로 모든 버전을 제거한다.

 

cocoapods 재설치

gem install --user-install cocoapods

 

pod setup

./pod setup 명령어로 설치를 진행한다.

 

대략 10분정도 걸렸는데 설치 후 유니티에서 ios 빌드를 하면 정상적으로 빌드가 된다.

반응형
반응형

유니티 플레이 스토어를 연동하려는 도중에 오류가 발생하였다.

앱에서 리더보드를 호출하면 아래와 같이 오류 로그가 찍힌다.

04-17 10:38:46.861 13360 13368 E DataBuffer: Internal data leak within a DataBuffer object detected!  Be sure to explicitly call release() on all DataBuffer extending objects when you are done with them. (internal object: com.google.android.gms.common.data.DataHolder@a4c3f4c)

04-17 10:38:46.880 13360 13368 E DataBuffer: Internal data leak within a DataBuffer object detected!  Be sure to explicitly call release() on all DataBuffer extending objects when you are done with them. (internal object: com.google.android.gms.common.data.DataHolder@ca40438)

04-17 10:38:47.012  3668 12103 E Parcel  : Class not found when unmarshalling: com.google.android.gms.auth.api.signin.internal.SignInConfiguration

04-17 10:38:47.012  3668 12103 E Parcel  : java.lang.ClassNotFoundException: com.google.android.gms.auth.api.signin.internal.SignInConfiguration

04-17 10:38:47.012  3668 12103 E Parcel  : at java.lang.Class.classForName(Native Method)

04-17 10:38:47.012  3668 12103 E Parcel  : at java.lang.Class.forName(Class.java:453)

04-17 10:38:47.012  3668 12103 E Parcel  : at android.os.Parcel.readParcelableCreator(Parcel.java:2843)

04-17 10:38:47.012  3668 12103 E Parcel  : at android.os.Parcel.readParcelable(Parcel.java:2797)

04-17 10:38:47.012  3668 12103 E Parcel  : at android.os.Parcel.readValue(Parcel.java:2700)

04-17 10:38:47.012  3668 12103 E Parcel  : at android.os.Parcel.readArrayMapInternal(Parcel.java:3067)

04-17 10:38:47.012  3668 12103 E Parcel  : at android.os.BaseBundle.unparcel(BaseBundle.java:257)

04-17 10:38:47.012  3668 12103 E Parcel  : at android.os.BaseBundle.getString(BaseBundle.java:1086)

04-17 10:38:47.012  3668 12103 E Parcel  : at android.content.Intent.getStringExtra(Intent.java:7706)

04-17 10:38:47.012  3668 12103 E Parcel  : at com.android.server.am.ActivityStarter.startActivity(ActivityStarter.java:468)

04-17 10:38:47.012  3668 12103 E Parcel  : at com.android.server.am.ActivityStarter.startActivityLocked(ActivityStarter.java:419)

04-17 10:38:47.012  3668 12103 E Parcel  : at com.android.server.am.ActivityStarter.startActivityMayWait(ActivityStarter.java:1308)

04-17 10:38:47.012  3668 12103 E Parcel  : at com.android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.java:6035)

04-17 10:38:47.012  3668 12103 E Parcel  : at com.android.server.am.ActivityManagerService.startActivity(ActivityManagerService.java:5887)

04-17 10:38:47.012  3668 12103 E Parcel  : at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:121)

04-17 10:38:47.012  3668 12103 E Parcel  : at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:3863)

04-17 10:38:47.012  3668 12103 E Parcel  : at android.os.Binder.execTransact(Binder.java:682)

04-17 10:38:47.012  3668 12103 E Parcel  : Caused by: java.lang.ClassNotFoundException: com.google.android.gms.auth.api.signin.internal.SignInConfiguration

04-17 10:38:47.012  3668 12103 E Parcel  : at java.lang.Class.classForName(Native Method)

04-17 10:38:47.012  3668 12103 E Parcel  : at java.lang.BootClassLoader.findClass(ClassLoader.java:1355)

04-17 10:38:47.012  3668 12103 E Parcel  : at java.lang.BootClassLoader.loadClass(ClassLoader.java:1415)

04-17 10:38:47.012  3668 12103 E Parcel  : at java.lang.ClassLoader.loadClass(ClassLoader.java:312)

04-17 10:38:47.012  3668 12103 E Parcel  : ... 17 more

04-17 10:38:47.012  3668 12103 E Parcel  : Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available

04-17 10:38:51.268 26157 26157 E ViewRootImpl@d3b955f[SignInActivity]: Attempting to destroy the window while drawing!

04-17 10:38:51.268 26157 26157 E ViewRootImpl@d3b955f[SignInActivity]:   window=android.view.ViewRootImpl@b7aaef1, title=com.google.android.play.games/com.google.android.gms.games.ui.signin.SignInActivity

04-17 10:38:51.345 26157 26157 E ViewRootImpl: sendUserActionEvent() returned.

04-17 10:38:52.621 25361 25361 E TokenFragment: Setting result error status code to: 16

04-17 10:39:03.358  5083  5249 E ContactsProvider_EventLog: Flush buffer to file cnt : 1 size : 1Kb duration : 1ms lastUpdatedAfter : 60119 ms mFlush_time_threasold : 2000 mCurrentSize : 593

04-17 10:39:08.527  3290  3290 E audit   : type=1400 audit(1555465148.514:65230): avc:  denied  { getattr } for  pid=26677 comm="netstat" path="/proc/crypto" dev="proc" ino=4026535594 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=0 SEPF_SM-G930S_8.0.0_0017 audit_filtered

04-17 10:39:08.528  3290  3290 E audit   : type=1400 audit(1555465148.514:65231): avc:  denied  { getattr } for  pid=26677 comm="netstat" path="/proc/last_kmsg" dev="proc" ino=4026535585 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=0 SEPF_SM-G930S_8.0.0_0017 audit_filtered

04-17 10:39:08.528  3290  3290 E audit   : type=1400 audit(1555465148.514:65232): avc:  denied  { getattr } for  pid=26677 comm="netstat" path="/proc/tsp_raw_data" dev="proc" ino=4026535583 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=0 SEPF_SM-G930S_8.0.0_0017 audit_filtered

04-17 10:39:08.528  3290  3290 E audit   : type=1400 audit(1555465148.514:65233): avc:  denied  { getattr } for  pid=26677 comm="netstat" path="/proc/usblog" dev="proc" ino=4026535540 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=0 SEPF_SM-G930S_8.0.0_0017 audit_filtered

04-17 10:39:08.528  3290  3290 E audit   : type=1400 audit(1555465148.514:65234): avc:  denied  { getattr } for  pid=26677 comm="netstat" path="/proc/sec_log" dev="proc" ino=4026535505 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=0 SEPF_SM-G930S_8.0.0_0017 audit_filtered

04-17 10:39:08.529  3290  3290 E audit   : type=1400 audit(1555465148.514:65235): avc:  denied  { getattr } for  pid=26677 comm="netstat" path="/proc/init_command" dev="proc" ino=4026535173 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=0 SEPF_SM-G930S_8.0.0_0017 audit_filtered

04-17 10:39:08.529  3290  3290 E audit   : type=1400 audit(1555465148.524:65236): avc:  denied  { getattr } for  pid=26677 comm="netstat" path="/proc/boot_stat" dev="proc" ino=4026535172 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=0 SEPF_SM-G930S_8.0.0_0017 audit_filtered

04-17 10:39:08.529  3290  3290 E audit   : type=1400 audit(1555465148.524:65237): avc:  denied  { getattr } for  pid=26677 comm="netstat" path="/proc/store_lastkmsg" dev="proc" ino=4026535171 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=0 SEPF_SM-G930S_8.0.0_0017 audit_filtered

04-17 10:39:08.530  3290  3290 E audit   : type=1400 audit(1555465148.524:65238): avc:  denied  { getattr } for  pid=26677 comm="netstat" path="/proc/reset_reason" dev="proc" ino=4026535170 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=0 SEPF_SM-G930S_8.0.0_0017 audit_filtered

04-17 10:39:08.530  3290  3290 E audit   : type=1400 audit(1555465148.524:65239): avc:  denied  { getattr } for  pid=26677 comm="netstat" path="/proc/user_fault" dev="proc" ino=4026535169 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=0 SEPF_SM-G930S_8.0.0_0017 audit_filtered

04-17 10:39:08.530  3290  3290 E audit   : type=1400 audit(1555465148.524:65240): avc:  denied  { getattr } for  pid=26677 comm="netstat" path="/proc/tima_secure_rkp_log" dev="proc" ino=4026535079 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=0 SEPF_SM-G930S_8.0.0_0017 audit_filtered

04-17 10:39:08.530  3290  3290 E audit   : type=1400 audit(1555465148.524:65241): avc:  denied  { getattr } for  pid=26677 comm="netstat" path="/proc/tima_debug_rkp_log" dev="proc" ino=4026535078 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=0 SEPF_SM-G930S_8.0.0_0017 audit_filtered

04-17 10:39:08.531  3290  3290 E audit   : type=1400 audit(1555465148.524:65242): avc:  denied  { getattr } for  pid=26677 comm="netstat" path="/proc/tima_secure_log" dev="proc" ino=4026535077 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=0 SEPF_SM-G930S_8.0.0_0017 audit_filtered

04-17 10:39:08.531  3290  3290 E audit   : type=1400 audit(1555465148.524:65243): avc:  denied  { getattr } for  pid=26677 comm="netstat" path="/proc/tima_debug_log" dev="proc" ino=4026535076 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=0 SEPF_SM-G930S_8.0.0_0017 audit_filtered

04-17 10:39:08.531  3290  3290 E audit   : type=1400 audit(1555465148.524:65244): avc:  denied  { getattr } for  pid=26677 comm="netstat" path="/proc/dmverity_odin_flag" dev="proc" ino=4026535075 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=0 SEPF_SM-G930S_8.0.0_0017 audit_filtered

04-17 10:39:08.532  3290  3290 E audit   : type=1400 audit(1555465148.524:65245): avc:  denied  { getattr } for  pid=26677 comm="netstat" path="/proc/partitions" dev="proc" ino=4026534988 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=0 SEPF_SM-G930S_8.0.0_0017 audit_filtered

04-17 10:39:08.532  3290  3290 E audit   : type=1400 audit(1555465148.524:65246): avc:  denied  { getattr } for  pid=26677 comm="netstat" path="/proc/diskstats" dev="proc" ino=4026534987 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=0 SEPF_SM-G930S_8.0.0_0017 audit_filtered

04-17 10:39:08.532  3290  3290 E audit   : type=1400 audit(1555465148.524:65247): avc:  denied  { getattr } for  pid=26677 comm="netstat" path="/proc/iostats" dev="proc" ino=4026534986 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=0 SEPF_SM-G930S_8.0.0_0017 audit_filtered

04-17 10:39:08.532  3290  3290 E audit   : type=1400 audit(1555465148.524:65248): avc:  denied  { getattr } for  pid=26677 comm="netstat" path="/proc/key-users" dev="proc" ino=4026534985 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=0 SEPF_SM-G930S_8.0.0_0017 audit_filtered

04-17 10:39:08.532  3290  3290 E audit   : type=1400 audit(1555465148.524:65249): avc:  denied  { getattr } for  pid=26677 comm="netstat" path="/proc/keys" dev="proc" ino=4026534984 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=0 SEPF_SM-G930S_8.0.0_0017 audit_filtered

04-17 10:39:13.098  3668  4168 E Watchdog: !@Sync 16389 [2019-04-17 10:39:13.098]

04-17 10:39:22.757  3668  3692 E memtrack: Couldn't load memtrack module

04-17 10:39:22.861  3668  3692 E memtrack: Couldn't load memtrack module

 

핵심은 아래 부분이다.

04-17 10:38:47.012  3668 12103 E Parcel  : Class not found when unmarshalling: com.google.android.gms.auth.api.signin.internal.SignInConfiguration

04-17 10:38:47.012  3668 12103 E Parcel  : java.lang.ClassNotFoundException: com.google.android.gms.auth.api.signin.internal.SignInConfiguration

 

찾아보니까 oatuh2.0 사인을 안해서 발생하는 오류라고 나오는데 앱을 먼저 출시를 하지 않으면 위와 같은 오류가 발생한다고 한다.

그래서 앱을 먼저 출시하였다.

 

 

앱을 출시하였더니 오류가 말끔히 사라지고 정상적으로 작동함을 확인하였다.

출시는 알파출시만 해도 되고 출시만 하면 바로 리더보드 연동이 확인 가능하다.

 

연동 결과창

 

반응형
반응형

유니티에서 파티클을 자동으로 제거하는 방법에 대해서 알아보자.

스크립트가 무조건 필요하다.

ParticleSystem.IsAlive(true)인지 질의하여 파티클을 삭제하는 스크립트를 추가하면 되는데 아래 에셋에서 더 좋은 기능이 첨부되어 있는 스크립트를 찾았다.

JMO Assets - Cartoon FX - 파티클 프리팹 - CFX_AutoDestructShuriken 스크립트

 

[RequireComponent(typeof(ParticleSystem))]
public class CFX_AutoDestructShuriken : MonoBehaviour
{
	// If true, deactivate the object instead of destroying it
	public bool OnlyDeactivate;
	
	void OnEnable()
	{
		StartCoroutine("CheckIfAlive");
	}
	
	IEnumerator CheckIfAlive ()
	{
		ParticleSystem ps = this.GetComponent();
		
		while(true && ps != null)
		{
			yield return new WaitForSeconds(0.5f);
			if(!ps.IsAlive(true))
			{
				if(OnlyDeactivate)
				{
					#if UNITY_3_5
						this.gameObject.SetActiveRecursively(false);
					#else
						this.gameObject.SetActive(false);
					#endif
				}
				else
					GameObject.Destroy(this.gameObject);
				break;
			}
		}
	}
}

요렇게 하면 좋은점은 프리팹에서 OnlyDeactivate를 체크하면 파티클이 플레이가 끝나도 파티클을 삭제하지 않고 비활성화만 해주는 추가적인 기능이 있어서 더 좋다.

반응형
반응형

프리팹을 통하여 게임 오브젝트에 대하여 일괄적으로 변경하는 방법

prefab으로 게임 오브젝트를 인스턴스화 시키면 scene 내에서 오브젝트가 파란색으로 변한다.

해당 인스턴스들은 원본 프리팹을 변경하면 일괄적으로 값이 바뀐다.

하지만 예외가 있으니 다음 내용을 참고하자



프리팹을 통하여 특정 속성값을 변경하여도 인스턴스중 이미 변경된 동일한 속성은 그대로 유지가 된다.

예를 들면 몇개의 인스턴의 색을 바꿔두면 프리팹에서 바꿔도 그 색이 유지가 된다.



물체 움직일때 스냅 그리드 사용하기

컨트롤을 누르고 이동하면 일정한 거리만큼 snap이 된다.

해당 snap거리를 바꾸는 메뉴는 Edit > Snap Settings 에 있다.




한번에 여러개 복사하고 정렬 하는 방법

snap을 활용하면 된다.

아래처럼 한다.



v를통해서 이동하는 방법 다른 물체에 snap 하는 방법

물체가 이미 떨어져 있어서 snap을 먹이기 힘들다면 오브젝트를 누르고 v를 누른상태에서 움직여주면 원하는 물체에 붙일 수 있다.


게임 씬 만지면서 개발할때는 Layers > UI는 꺼주기

UI를 켜두면 자꾸 인게임 오브젝트를 선택할때 잘 안된다.

따라서 우측 상단의  Layers에서 UI 부분을 꺼주자

반응형
반응형

벽돌깨기를 만들때 게임이 시작하기전에 공이 패드를 따라다니게만들때

public class Ball : MonoBehaviour
{
[SerializeField] private Paddle paddle1;

private Vector2 paddleToBallVector;

void Start()
{
paddleToBallVector = transform.position - paddle1.transform.position;
}

void Update()
{
Vector2 paddlePos = new Vector2(paddle1.transform.position.x, paddle1.transform.position.y);
transform.position = paddlePos + paddleToBallVector;
}
}

위와 같이 update문에 공을 패드위에 붙이면 되지만 패드를 빠르게 움직이면 공이 버벅이는 것을 볼 수 있다.


이럴 경우 script excution order를 보다 빠르게 바꿔주면 된다.


반응형

'Unity' 카테고리의 다른 글

유니티 파이어베이스 로그 비활성화  (2) 2020.02.05
유니티 꿀팁  (0) 2019.02.27
유니티 씬 관리  (0) 2019.02.17
유니티 모펍 광고 호출  (2) 2019.02.10
유니티 도전과제 구현  (0) 2019.01.30
반응형

유니티에서 신 넘어가는 방법에 대해서 적어보겠다.

해당 내용은 Udemy 코스를 들었는데 거기서 알려준 방식이다.

Game development & design. Learn Unity 2018 in C#. Your first 7 2D Unity games for web, Mac & PC. Includes Tilemap


원래는 보통 한 신에서 전부다 처리하고는 했는데 신 처리하는 방법이 그리 어렵지도 않고 깔끔하게 처리가 가능하다는 것을 배우고 나서는 신을 분리해서 개발하도록 하고 있다.


신이 3개가 있다고 하자

종료에서 다시 시작으로 넘어가는 부분을 제외하고 신의 전환이 순차적으로 진행된다고 가정하였을때

시작 -> 인게임 -> 종료

그리고 신의 인덱스값이 시작(0) 인게임(1) 종료(2)라고 하였을때


시작, 인게임 신에서는 아래와 같이 하면 다음 신으로 넘어간다.

SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);


그리고 종료씬에서 다시 시작씬으로 순환을 해줘야한다면

SceneManager.LoadScene(0)

위와 같이 해주면 된다.



반응형

'Unity' 카테고리의 다른 글

유니티 꿀팁  (0) 2019.02.27
유니티 물체 따라다니도록 하기  (0) 2019.02.24
유니티 모펍 광고 호출  (2) 2019.02.10
유니티 도전과제 구현  (0) 2019.01.30
유니티 사운드 미리 불러오기  (0) 2019.01.30
반응형

유니티 모펍 광고 호출하는 방법에 대하여 작성한다.


모펍이라는 광고 sdk는 내생각에는 타 광고 sdk에 비교해서 좀 불친절하다고 생각한다.

하지만 마케팅 하시는분의 말씀에 의하면 sdk의 친절함은 아래와 같지만

iorn source(매우친절) admob(적당히 친절) mopub(불친절)

광고 수익단가는 아래와 같다고 한다.

iorn source(낮음) admob(중간) mopub(높음)


그래서 하필 내가 mopub 광고를 붙이게 된 희생양이 되었다.

다행히도 요즘 수익성이 높아서 게임업계도 mopub 광고로 전환하는 추세라고 한다던데(카더라) 나의 경쟁력이 조금이라도 높아지지 않았을까 싶다...


잡설이 많아버렸네


일단 mopub sdk를 붙였다는 가정하에 내용을 포스팅한다.(모펍 sdk 광고 호출이지 sdk 부착이 아님)



Mopub Demoscene 프리팹 복사

본인의 프로젝트에 mopub 유니티 패키지를 불러왔다면 mopu demo scene이 있다. 열어보자

해당 신을 보면 MopubDemoGUI 프리팹이 있다. 이 프리팹을 이용할 것 이다.


본인의 프로젝트 scene에 해당 프리팹을 복사해서 넣는다.

그 상태로 실행하면 당연히 모펍 광고 호출하는 gui가 나오니까 수정해야한다.


Mopub AD unit 기입

MoPubDemoGUI.cs를 열어보자 내가 사용한 광고 종류는 아래와 같다.

_bannerAdUnits 배너 AD unit

_rewardedVideoAdUnits 비디오 광고 AD unit

광고 AD unit은 mopub에서 찾아 볼 수 있다.


광고 들어가보면 url에 ad-unit 이렇게 있는데 여기 url에 있는 광고 ad unit을 유니티에서 적합한 광고 유형에 넣어주면 된다.


Mopub 스크립트 수정

Awake부분의 AddAdUnitsToStateMaps 부분에 필요한 부분을 빼고 주석처리했다.

Start 부분의 sdk 이니셜라이즈는 이벤트가 로그에 찍힌다.

sdk 이니셜라이징 -> SDK initialization started

sdk 이니셜라이징 정상적으로 성공 -> SDK initialized and ready to display ads.

참고하면 좋다.


Start 부분의 LoadBannerPluginsForAdUnits 부분에 필요한 부분 외에는 주석처리했다.


OnGUI 부분은 사용하지 않기에 주석처리한다.


광고를 호출하는 부분을 작성해야한다.

본인의 경우 배너광고는 바로바로 보여지면 되니까 mopub sdk가 정상적으로 호출되면 배너광고를 생성하도록 하였다.

MoPubMnager.cs의 EmitSdkInitializedEvent 부분에 추가하였다.

그리고 비디오광고 또한 광고 소재를 불러오는 코드를 넣었다.

정확하게 어떻게 해야할지는 모르겠지만 찾아봐도 비디오 광고를 불러오는 가이드가 나오지 않아서 내가 이해한 개념과 방법을 적어놓겠다.


비디오 광고는 마치 총과 같다.

RequestRewardedVideo를 호출하여 광고 소재(총알)를 불러오고(장전) ShowRewardedVideo를 호출하여(발사) 광고를 보여준다.

ShowRewardedVideo를 사용하기만 하면 계속해서 비디오 광고를 보여주지 않아서 ShowRewardedVideo를 호출하기 전에 RequestRewardedVideo를 호출하여 광고를 불러와야한다.

그리고 RequestRewardedVideo를 호출하자마자 ShowRewardedVideo를 해버리면 광고가 아직 안불러와져서 정상적인 호출이 안되니 미리미리 호출을 해놔야한다.

본인의 경우 비디오 광고를 닫는 이벤트가 발생하자마자(EmitRewardedVideoClosedEvent) 새로운 광고를 바로 불러오도록 해놨다.


위는 비디오 광고를 종료하고나면 발생하는 이벤트다. 저 곳에 비디오 광고를 요청하도록 하였다.


위는 비디오 광고를 호출하는 부분이다.

게임을 5번 플레이하면 나오도록 하였다.


SDK가 정상적으로 호출되었을때 나오는 로그다.

SDK 불러오면 광고를 불러오도록 했으니까 위와 같이 로그가 찍힌다.


비디오 광고를 요청하였을때 로그


비디오 광고를 보여줄때 로그


비디오 광고가 끝났을때 로그

반응형