Total: Today: Yesterday:
노하우/Linux | 2021. 7. 22. 12:10 | Posted by 자수씨

top이라는 명령어만으로는 머신 상태를 확인하기에는 부족함이 있다.

페이스북에서 과거의 오늘이라며 8년 전 글을 보여줬는데 지금 봐도 충격과 공포이다.

 

 

요즘에는 AWS EC2 머신을 주로 사용하므로 해당 머신에 설치하는 방법을 공유하고자 한다.

 

htop

top의 대안으로 나온 프로그램으로 c언어로 된 오픈소스이다. Ncurses를 이용하여 키보드 커서도 이용할 수 있다.

 

 

설치 방법은 간단하다.

 

# 설치
sudo install -y htop

# 실행
htop

 

iotop

프로세스 별 io 통계를 볼 수 있는 프로그램이다.

 

 

이것 또한 설치 방법은 간단하다. 실행 시에는 root 권한이 필요하여 sudo를 이용한다.

 

# 설치
sudo yum install -y iotop

# 실행
sudo iotop

 

iftop

네트워크 연결 목록 및 상태를 보여주는 프로그램이다. 실시간 트래픽 확인에 도움이 된다.

 

 

EC2의 경우 기본적으로 EPEL 리포지토리가 활성화가 되어 있지 않기 때문에 다음과 같은 설정이 필요하다.

 

# 1. EC2 리눅스 버전 확인
cat /etc/-release

# 2-1. Amazon Linux AMI 2018.03 의 경우
sudo yum-config-manager --enable epel

# 2-2. Amazon Linux 2 의 경우
sudo sudo yum-config-manager --enable epel

# 3. epel-release 설치
sudo yum install epel-release

# 4. iftop 설치
sudo yum install iftop

# 실행
sudo iftop

 

iotop 과 마찬가지로 root 권한이 요구되어 실행시 sudo를 이용한다.

개발/Unity | 2021. 7. 22. 11:33 | Posted by 자수씨

유니티에서 쓰는 Dictionary는 직렬화가 되지 않기 때문에 Inspector에서 제어가 되지 않는다. key-value 쌍으로 관리해야 하는 데이터가 있는 경우 불편함이 있는데, 이전에 검색을 통해 적용했던 Dictionary 보다 사용성이 좋아서 테스트 해 보았다. (2021년 3월에 업데이트 된 것으로 보인다.)

 

관련 사이트: https://wiki.unity3d.com/index.php/SerializableDictionary

 

SerializableDictionary - Unify Community Wiki

Author: Fredrik Ludvigsen (Steinbitglis) Notice 1 This collection has been updated (as of Mar. 2021). Check the document history for the old version. Notice 2 A much more advanced version is now available at Rain Games office server. This can be added as a

wiki.unity3d.com

 

설치

Project Settings > Package Manager에 새로운 Registry를 추가한다. (2020 이상 버전부터 사용 가능)

 

Package Manager에서 SerializableDictionary 패키지를 설치한다.

 

사용 예

public class 클래스이름 : MonoBehaviour
{

    [SerializeField] private SerializableDictionary<int, GameObject> m_MonsterRepository;

    ...
}

위와 같이 public이나 SerializeField로 선언되면 Inspector에 아래와 같이 표시가 된다.

key가 enum으로도 지원이 되는지는 별도로 테스트 해 볼 예정이다.

개발/Unity | 2021. 7. 21. 22:19 | Posted by 자수씨

unity Cannot perform upm operation: EBUSY: resource busy or locked, open

 

Project Manager를 통해 새로운 package를 설치하다보면 위와 같은 오류가 발생할 수 있다. 여러가지 원인이 있겠지만 검색한 유니티 포럼에 의하면 스크립트 편집을 위한 VS Code를 열어두어서 발생할 수 있다고 한다.

 

VS Code 종료 후 설치하니 오류 없이 진행된다.

개발/Unity | 2021. 7. 21. 12:05 | Posted by 자수씨

테스트를 위해 새로운 프로젝트를 생성하여 Play를 하게 되면 Hierarchy의 Scene 트리가 접히는 문제가 있었다. 처음에는 대수롭지 않게 생각했는데, 게임오브젝트를 선택하려면 씬 트리를 열어야 하는 불편함이 생겼다.

유니티 포럼에 비슷한 문제를 겪는 사람들이 있었다.

#if UNITY_EDITOR
         UnityEditor.EditorGUIUtility.PingObject (gameObject);
#endif

처음 시도했던 방법은 씬에 포함되어 있는 GameObject의 스크립트에 위와 같은 코드를 삽입하는 것이다. 매번 코드에 삽인하는 것은 해결책이 되지 않을 것 같아 포럼 댓글들을 더 찾아보았다.

 

댓글에 있는 링크를 따라가다보니 Addressable 관련 버그라고 하며 Simulate Groups (advanced)로 설정되어 있는 경우 발생하는 문제로 보여진다. Use Asset Database (fastest)로 설정하면 해당문제가 발생하지 않는다.

개발/Unity | 2021. 7. 20. 23:52 | Posted by 자수씨

기존에 진행하던 프로젝트에 Unity를 최신버전으로 적용한 이후 Unity Editor를 실행할 때 마다 아래와 같은 오류가 발생하였다. (2020.1.16ff >> 2020.3.11f1)

 

여러 사이트를 조회해본 결과 Spine 초기화 시에 발생하는 문제로 추측되었다. 기존에는 3.8 버전을 사용했는데 아래의 문제로는 해결이 되지 않았다.

--- a/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs
+++ b/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs
@@ -97,7 +97,7 @@ namespace Spine.Unity.Editor {
 
 #region Initialization
                static SpineEditorUtilities () {
-                       Initialize();
+                       EditorApplication.delayCall += () => Initialize();
                }
 
                static void Initialize () {

Spine 라이브러리를 제거한 후 Unity Editor를 재시작하였더니 해당 오류가 발생하지 않는 것을 봐서는 문제의 원인이 맞는 것 같다.

 

Spine-Unity 다운로드 페이지에서 최신버전(4.0)을 설치한 이후에도 오류가 발생하지 않았다.

아직까지 다른 문제가 발생하지 않으므로 본 포스트는 마무리한다.

개발/Unity | 2020. 8. 11. 12:14 | Posted by 자수씨

PlayServicesResolver 를 프로젝트에 추가한 이후로 빌드 시 마다 아래와 같은 에러가 발생한다.

 

Assembly 'Assets/PlayServicesResolver/Editor/Google.IOSResolver_v1.2.135.0.dll' will not be loaded due to errors:
Unable to resolve reference 'UnityEditor.iOS.Extensions.Xcode'. Is the assembly missing or incompatible with the current platform?
Reference validation can be disabled in the Plugin Inspector.

 

실행에는 문제가 없으나 항상 뜨는 오류라서 신경이 쓰여서 구글링을 하였으나 만족할만한 결과는 찾지 못하였다.

 

 

혹시나 하는 생각에 iOS 모듈을 추가로 설치했더니 오류가 사라졌다. 윈도우라서 iOS 빌드가 안될 것 같아 설치를 안했는데 PlayServicesResolver 를 추가한 경우에는 iOS 모듈도 설치가 필요한 것으로 보인다.

 

개발/Unity | 2020. 8. 10. 16:36 | Posted by 자수씨

안드로이드 빌드 시 keystore 를 설정한 후 빌드를 하게 되면 Project Settings 에서 keystore 에 대한 패스워드를 지정해야 한다.

 

Unity 의 보안 정책인지 모르겠지만 Unity Editor 를 재시작하게 되면 패스워드가 초기화 된다.

 

BuildPipeline.BuildPlayer() 로 빌드할 경우 항상 패스워드를 설정해주어야 하는 불편함이 발생한다.

 

구글링을 통해 확인된 해결 방법은 keystore 패스워드를 스크립트에서 설정하는 것인데, BuildPlayer 바로 위에 설정할 경우 동일한 에러가 발생한다.

PlayerSettings.Android.keystorePass = "$$password$$";
PlayerSettings.Android.keyaliasPass = "$$password$$";

BuildPipeline.BuildPlayer(...);

 

 

[InitializeOnLoad]  Attribute 와 static 생성자(?) 를 이용하여 설정하게되면 스크립트 내에서 패스워드 설정이 가능한 것을 확인하였다.

[InitializeOnLoad]
public class LocalBuild : MonoBehaviour
{
    static LocalBuild()
    {
        PlayerSettings.Android.keystorePass = "$$password$$";
        PlayerSettings.Android.keyaliasPass = "$$password$$";
    }
    ...
    
}

 

ㅁ 참고자료

https://answers.unity.com/questions/757834/publishing-settings-keystore-password-not-saving.html

개발/Unity | 2020. 8. 7. 18:48 | Posted by 자수씨

Facebook 로그인 테스트를 위해 사이트(https://developers.facebook.com/docs/unity/) 에서 SDK 를 내려받고 매뉴얼(https://developers.facebook.com/docs/unity/gettingstarted)을 보고 초기화 설정까지 완료했는데, 앱을 빌드하고 로그인 로직이 처리되는 순간 crash 가 발생한다.

FB.LogInWithPublishPermissions() 메소드를 호출하는 순간 발생하는 것 같은데...

구글링을 하다보니 LogInWithReadPermissions, LogInWithPublishPermissions 메소드의 차이로 인해 발생하는 것으로 보인다.

var perms = new List<string>(){"public_profile", "email"};
FB.LogInWithReadPermissions(perms, AuthCallback);

public_profileemail 조회 시에는 LogInWithReadPermissions 를 사용한다.

참고자료

개발/Unity | 2020. 8. 7. 14:29 | Posted by 자수씨

Unity 빌드를 Jenkins 로 이용하고 있는데, Editor 를 최신버전으로 업데이트 한 이후부터 아래와 같은 오류가 발생한다.

 

Could not open file /Users/*****/Documents/unity/2020.1.1f1/PlaybackEngines/AndroidPlayer/modules.asset for read 
(Filename: ./Runtime/File/OpenFileCache.cpp Line: 61)
 
Assertion failed on expression: 'res' 
(Filename: ./Runtime/Serialize/SerializationCaching/FileCacherRead.cpp Line: 133)
 
Unknown error occurred while loading '/Users/*****/Documents/unity/2020.1.1f1/PlaybackEngines/AndroidPlayer/modules.asset'. 
(Filename:  Line: 0)
 
[Unity Package Manager (Upm)]
Parent process [30691] was terminated

 

Jenkins 는 추후 iOS 빌드를 위해 MacOS 환경에 구축되었는데, MacOS 에서 Unity Editor 로 빌드를 하면 오류가 발생하지 않는다.

 

한가지 특이한 사항은 이전 버전이 2019.3.0f6 인데 경로가 Documents 가 아닌 Developments 라고 별도의 경로에 있었다. 기억을 더듬어 보니 기존에도 이러한 이슈가 발생한 것 같은데 정리를 안해 놓은 듯...

 

기존 버전과 같이 Unity Editor 를 /Users/[사용자]/Documents 가 아닌 다른 경로(/Users/[사용자]/Developments) 로 이동시키고 빌드를 했더니 오류가 발생하지 않았다.

 

Jenkins 프로세스가 MacOS 의 권한으로 인해 Documents 에 접근이 안되는 것으로 마무리 짓는다.

(이전에는 관련된 정보를 찾았던 것 같은데 기억이 나지 않는다...)

개발/Unity | 2020. 6. 10. 12:11 | Posted by 자수씨

어드레서블에 대한 이해를 하고자 해보았으나 실제 사용하는 방법은 약간 차이가 있다.

일단 하던 번역은 마무리하고 실제 사용 전략에 대해 정리할 예정이다.

2020/06/09 - [개발/Unity] - Addressable Assets development cycle (1)
2020/06/10 - [개발/Unity] - Addressable Assets development cycle (2)

컨텐츠 업데이트 빌드 (Building for content updates)

컨텐츠 업데이트를 빌드하려면 다음을 수행한다.

  1. 유니티 에디터에서 Addressable Groups window 를 연다 (Window > Asset Management > Addressables > Gruops)
  2. Addressable Groups window 에서 탑 메뉴의 Build > Update a Previous Build 를 선택한다.
  3. 빌드 데이터 파일 (Build Data File) 다이얼로그 팝업이 열리면 addressable_content_state.bin 파일을 선택한다.

빌드를 통해 컨텐츠 카탈로그, 해시 파일 및 에셋번들이 생성된다.

생성된 컨텐츠 카탈로그는 선택된 애플리케이션 빌드의 카탈로그와 동일한 이름을 가지며 이전 카탈로그 및 해시 파일을 겹쳐 쓴다. 애플리케이션은 새 카탈로그가 사용가능한지 판별하기 위해 해시 파일을 로드한다. 시스템은 애플리케이션과 함께 제공되거나 이미 다운로드 된 기존 번들에서 수정되지 않은 에셋을 로드한다.

시스템은 addressables_content_state.bin 에서 컨텐츠 버전 문자열과 위치 정보를 사용하여 에셋 번들을 생성한다. 업데이트 된 컨텐츠를 포함하지 않는 에셋 번들은 업데이트를 위해 선택된 빌드의 파일 이름과 동일한 이름을 사용하여 작성된다. 에셋 번들에 업데이트 된 컨텐츠가 포함된 경우 원래 파일과 공존할 수 있도록 업데이트가 된 컨텐츠를 포함하는 새 에셋 번들이 새로운 파일 이름으로 작성된다. 새 파일 이름을 가진 에셋 번들만 컨텐츠를 호스팅 하는 위치로 복사되어야 한다.

또한 시스템은 변경할 수 없는 컨텐츠에 대한 에셋 번들을 빌드하지만 어드레서블 에셋 항목이 참조하지 않으므로 컨텐츠 호스팅 위치에 업로드할 필요는 없다.

새 플레이어를 빌드하고 컨텐츠를 업데이트 하는 (예: 플레이어 코드, 어드레서블) 빌드 스크립트를 변경해서는 안된다. 애플리케이션에서 예기치 않은 동작이 발생될 수 있다.

 

 

런타임 시 컨텐츠 업데이트 확인 (Checking for content updates at runtime)

새로운 어드레서블 컨텐츠 업데이트가 있는지 정기적으로 확인하기 위해 사용자 정의 스크립트를 추가할 수 있다. 다음 함수 호출을 사용하여 업데이트를 시작한다.

public static AsyncOperationHandle<List<string>> CheckForCatalogUpdates(bool autoReleaseHandle = true)

리턴 값의 List<string> 은 수정된 위치 ID 목록이 포함된다. 이 ID를 필터링하여 특정 ID 만 업데이트하거나 완전히 UpdateCatalogs API 로 전달할 수 있다.

새로운 컨텐츠가 있는 경우 업데이트를 수행할 수 있는 버튼을 사용자에게 제공하거나 자동으로 수행할 수 있다. 오래된 에셋이 릴리즈되었는지 확인하는 것은 개발자의 책임이다.

카탈로그 목록은 null이 될 수 있으며, 필요한 경우 다음 스크립트는 업데이트가 필요한 모든 카탈로그를 업데이트한다.

public static AsyncOperationHandle<List<IResourceLocator>> UpdateCatalogs(IEnumerable<string> catalogs = null, bool autoReleaseHandle = true)

리턴 값은 업데이트 된 위치 목록이다.

 

 

컨텐츠 업데이트 예 (Content update examples)

이 예제에서 제공된 애플리케이션은 다음 그룹을 인식한다.

Local_Static Remote_Static Remote_NonStatic
AssetA AssetL AssetX
AssetB AssetM AssetY
AssetC AssetN AssetZ

참고: Local_StaticRemote_StaticCannot Change Post Release 그룹의 일부이다.

이 버전은 라이브 버전이므로 디바이스에 Local_Static 를 가지고 있는 플레이어가 있고 원격 번들 중 하나 또는 둘 모두가 로컬로 캐시되어 있을 수 있다.

각 그룹에서 하나의 에셋 (AssetA, AssetL, AssetX) 을 수정한 다음 Check for Content Update Restrictions 를 실행하면 로컬 어드레서블 설정의 결과는 아래와 같다.

Local_Static Remote_Static Remote_NonStatic content_update_group (non-static)
    AssetX AssetA
AssetB AssetM AssetY AssetL
AssetC AssetN AssetZ  

참고: 준비 작업은 실제로 Cannot Change Post Release 그룹을 편집하므로 직관적이지 않을 수 있다.그러나 핵심은 시스템이 위의 레이아웃을 빌드하지만 이러한 그룹에 대한 빌드 결과를 버리는 것이다. 따라서 플레이어의 관점에서 다음과 같이 정리된다.

 

Local_Static
AssetA
AssetB
AssetC

Local_Static 번들은 변경할 수 없는 플레이어 장치에 이미 있다. 이 이전 버전 AssetA 는 더 이상 참조되지 않는다. 대신 플레이어 장치에 죽은 데이터로 남아있게 된다.

 

Remote_Static
AssetL
AssetM
AssetN

Remote_Static 번들은 변경되지 않는다. AssetM 이나 AssetN 이 플레이어 장치에 아직 캐시되지 않은 경우 요청 시 다운로드 된다. AssetA 와 같이 이전 버전 AssetN 은 더 이상 참조되지 않는다.

 

Remote_NonStatic (old)
AssetX
AssetY
AssetZ

Remote_NonStatic 번들은 이제 오래되었다. 서버에서 삭제할 수 있으며 이 시점부터는 다운로드 되지 않는다. 캐시가 되더라도 결국 캐시에서 삭제된다. AssetAAssetL 처럼 이전 버전 AssetX 는 더 이상 참조되지 않는다.

 

Remote_NonStatic (new)
AssetX
AssetY
AssetZ

이전 Remote_NonStatic 번들은 해시 파일로 구별되는 새 버전으로 대체된다. 수정된 버전은 AssetX 가 새 번들로 업데이트 된다.

 

content_update_group
AssetA
AssetL

 

이전 content_update_group 번들은 전진 참조(referenced moving forward)될 수정된 에셋으로 구성되어 있다.

위의 예는 다음과 같은 의미를 갖는다.

  1. 변경된 로컬 에셋은 사용자 장치에서 영원히 사용되지 않은 상태로 유지된다.
  2. 사용자가 비정적(non-static) 번들을 이미 캐시한 경우 변경되지 않은 에셋 (예: AssetY, AssetZ) 을 포함하여 번들을 다시 다운로드해야 한다. 이상적으로 사용자는 번들을 캐시하지 않았으므로 새로운 Remote_NonStatic 번들을 다운로드하면 된다.
  3. 사용자가 이미 Static_Remote 번들을 캐시한 경우 업데이트 된 에셋만 다운로드하면 된다. ( 이 경우 AssetLcontent_update_group 을 통해). 이 경우에는 이상적이다. 사용자가 번들을 캐시하지 않은 경우 수정되지 않은 번들을 통해 content_update_group 을 통해 새로운 AssetL 과 수정되지 않은 Remote_Static 번들을 통해 현재 없어진 AssetL 을 모두 다운로드 해야 한다. 초기 캐시 상태와 상관없이, 어느 시점에 사용자는 장치에 기능이 없는 AssetL 을 갖게 되며, 액세스하지 않아도 무기한으로 캐시된다.