Unity3D 사용시 특정 디바이스에서 Audio 재생이 지연되는 문제에 대해…

개발 중인 게임이 현재 가지고 있는 테스트 폰 중에서 유독 L전자 핸드폰에서 AudioClip을 재생할 때에 재생 명령이후 실제 소리가 들릴 때까지 약간의 지연이 생기는 문제가 발생하고 있네요.

이런 저런 자료를 찾다보면

Unity3D 자체가 조금의 지연을 일으킨다는 이야기가 좀 나오는데요.

일부에서는 android.media.SoundPool 을 사용해서 Java 단에서 AudioClip 재생을 하도록 구현하면 조금 나아진다는 이야기들이 있습니다.

조금 번거롭긴 합니다만… 한번 만들어두면 이후 프로젝트에서도 써 먹을 수 있고 하니
한번 참고해 보세요.

참고자료)
SoundPool 문서
Unity3D관련 글

Unity 에서 장치 ID, MAC 주소 가져오기

Unity에서 장치의 고유한 식별 번호를 얻고 싶은데…


아이폰으로는 테스트를 못해 봤습니다만… 잘 되지 않을까 싶네요.


안드로이드에서 장치의 식별자로 쓸만한 것이 3개 있는데



  1. Settings.Secure 의 ANDROID_ID

  2. WiFi의 MAC 주소

  3. 전화 모듈의 식별자

입니다.
아래 코드에서는 위 순서대로 가져오기를 시도해서 잘 가져오는 것을 반환하게 했습니다.


당연히… 별다른 이상한 오류 상황이 아니면 ANDROID_ID를 가져 오겠지요?

	public string GetDeviceID ()
{
if (Application.platform == RuntimePlatform.Android)
{
try
{
using (AndroidJavaObject activity = new AndroidJavaClass (“com.unity3d.player.UnityPlayer”).GetStatic<AndroidJavaObject> (“currentActivity”))
{
// ANDROID_ID
try
{
using (AndroidJavaObject resolver = activity.Call<AndroidJavaObject> (“getContentResolver”))
{
using (AndroidJavaObject settingsSecure = new AndroidJavaObject (“android.provider.Settings.Secure”))
{
string deviceID = settingsSecure.CallStatic<string> (“getString”, resolver, settingsSecure.GetStatic<string> (“ANDROID_ID”));
if (!string.IsNullOrEmpty (deviceID))
{
return deviceID;
}
}
}
}
catch (System.Exception)
{
}

// WiFi MAC
try
{
using (AndroidJavaObject wifiManager = activity.Call<AndroidJavaObject> (“getSystemService”, activity.GetStatic<string>(“WIFI_SERVICE”)))
{
string macAddr = wifiManager.Call<AndroidJavaObject> (“getConnectionInfo”).Call<string> (“getMacAddress”);
if (!string.IsNullOrEmpty (macAddr))
{
return macAddr;
}
}
}
catch (System.Exception)
{
}

// IMEI/MEID code
try
{
using (AndroidJavaObject telephonyManager = activity.Call<AndroidJavaObject> (“getSystemService”, activity.GetStatic<string>(“TELEPHONY_SERVICE”)))
{
string imeiCode = telephonyManager.Call<string> (“getDeviceId”);
if (!string.IsNullOrEmpty (imeiCode))
{
return imeiCode;
}
}
}
catch (System.Exception)
{
}

}
}
catch (System.Exception)
{
}
}
else
{
// 이 방법은 안드로이드에서는 안된다. – Unity 4.3.4f1
try
{
var nics = NetworkInterface.GetAllNetworkInterfaces ();
if (nics.Length > 0)
{
return nics[0].GetPhysicalAddress ().ToString ();
}
}
catch (System.Exception)
{
}
}
return “”;
}


WiFi MAC 주소를 가져오려면 ACCESS_WIFI_STATE 권한이 필요합니다.


IMEI code 를 가져오려면 READ_PHONE_STATE 권한이 필요합니다.


그럼 이 권한은 어떻게 설정할까요?
만약 프로젝트 경로 아래에
Assets/Plugins/Android/AndroidManifest.xml 파일이 있다면 해당 파일을 수정하시면 됩니다.
이 파일이 없으시다면
(Unity 설치 경로)/Editor/Data/PlaybackEngines 폴더 밑에 있는
androidplayer 또는 androiddevelopmentplayer 폴더에 있는 파일을 복사해서 사용하시면 됩니다.


아래 내용을 추가하시면 되겠죠?



<uses-permission
android:name="android.permission.READ_PHONE_STATE"
>
</uses-permission>
<uses-permission
android:name="android.permission.ACCESS_WIFI_STATE"
>
</uses-permission>


Unity의 .NET Framework와의 호환

Unity 라는 녀석이 있습니다.


삼성에서 회사를 통째로 사고 싶어한다는 루머가 있지요.


이 녀석은 Mono 라는 녀석을 기반으로 삼고 있습니다.


Mono는 오픈 소스 .NET Framework 입니다.


그리고 그 Mono를 가지고 Unity 라는 녀석이 나왔습니다.


그런데 궁금하군요… Unity에서 호환 가능한 .NET Framework 버전은 얼마일까?



  • [Programmer J님의 포스트]에 따르면 Unity 4 버전은 Mono 2.6을 사용하고
    그래서 .NET Framework 3.5와 호환이 된다고 합니다.

  • 그런데 [Unity 질답 게시판 글]에 따라 코드를 만들어 테스트 하면 2.0으로 나옵니다.
    2.0 (Visual Studio built mono)

    Type type = Type.GetType("Mono.Runtime");
    if (type != null) {
    	MethodInfo mi = type.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static);
    	if (mi != null) {
    		print(mi.Invoke(null, null));
    	}
    }
    


  • 유니티 설치 후 MonoDevelop을 통해 Assembly-CSharp의 속성을 보면 3.5를 타겟으로 하고 있습니다.
    그리고 System, System.Core, System.Xml 이렇게 3개의 어셈블리를 참조한다고 되어 있군요.

  • [구글에서만 검색되고 Unity 사이트에서는 정상적으로 접근 할 수 없는 자료]에 따르면 2.0이라고 나옵니다.
    여기에서는 System, System.Core 만 보입니다.

결론은… 서버 프로그래밍이나 잘 하자 입니다. 하하하….