블로그 이미지
Every unexpected event is a path to learning for you. blueasa

카테고리

분류 전체보기 (2824)
Unity3D (874)
Programming (479)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (236)
협업 (64)
3DS Max (3)
Game (12)
Utility (140)
Etc (98)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (52)
Android (16)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (19)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday

[참고]
Visual Studio 설치 할 때, Git for Windows를 함께 설치하지 않았었는데,
제목과 같은 에러 이슈로 Visual Studio에서 Git for Windows를 추가 설치하고 재부팅 했다.
 
 

[링크] https://thenight-avicii.tistory.com/26

[Error] No 'git' executable was found.

executable 뜻 실행가능한 no가 앞에 붙었으니 실행가능한 git이 없다는 뜻 에러)[Package Manager Window] Error adding package: https://github.com/google-ar/arcore-unity-extensions.git#arf6.Unable to add package [https://git

thenight-avicii.tistory.com

 

반응형
Posted by blueasa
, |

[URP] CameraStackManager

Unity3D/URP / 2025. 6. 16. 13:46

Unity 6000.1.6f1

URP

----

 

URP를 사용해보려 하니 Camera 제어 방식이 BIRP와는 달라서 Camera를 어떻게 관리해야 할지 고민이었다.

나는 기본적으로 Scene 별로 분리하고 Scene마다 Camera를 따로 관리하는 편인데,

URP에서는 Base Camera를 1개 두고 나머지를 Overlay Camera로 둬서 Base Camera의 CameraStack에 추가해서 사용해야 한단다.

Overlay들의 렌더링 순서도 CameraStack List의 등록 순서라서 Sort를 해서 해결해야 될 듯하고..

 

그래서 이리저리 인터넷 뒤져보다보니 아래 링크의 github 소스가 나의 기존 BIRP Camera 사용방식에 적용가능 할 것 같아서 가져와서 조금 수정해봤다. (do-won-kim님 감사합니다.)

[참조] https://github.com/do-won-kim/CameraStack

 

GitHub - do-won-kim/CameraStack

Contribute to do-won-kim/CameraStack development by creating an account on GitHub.

github.com


 

일단 기존 BIRP의 카메라 제어 방식을 유지하기 위해 고민을 해보다보니,

CameraStack 등록용으로 새로운 Base Camera를 하나 추가하고, 나머지를 모두 Overlay로 해서 depth만 잘 관리하면 BIRP랑 구조가 같게 될 것 같다.

결과적으로 URP에서는 Base Camera 하나 더 추가하면 될 듯 하다.

그래서 구조를 아래와 같이 잡았다.

 

1) CameraStackManagerSGT(GameObject) 프리팹 생성 및 Main Scene(최초 생성 및 파괴되지 않는 Scene)에 올리기

    └ Camera (GameObject)

        └ Render Type : Base

        └ Projection : Othographic

        └ Culling Mask : Nothing

        └ CameraStackController(Component)

            └ fDepth : -1(Base 1개만 쓰기 때문에 현재 생각으로는 의미없어서 초기값)

            └ bIsBaseCamera - Check

 

2) 나머지 Camera에 CameraStackController(Component) 추가

    └ Render Type : Overlay

    └ Projection : 상황에 맞게

    └ Culling Mask : 상황에 맞게

    └ CameraStackController(Component)

        └ fDepth : BIRP의 Camera Depth와 같게 제어(숫자가 높을수록 위에 그려짐)

        └ bIsBaseCamera : UnCheck


        

CameraStackManagerSGT.cs와 CameraStackController.cs 소스 및 프리팹은 아래 첨부 파일 참조

 

CameraStackManagerSGT.cs
0.01MB
CameraStackController.cs
0.00MB
CameraStackManager.prefab
0.00MB

 

 

[결론]

위와 같은 카메라 관리 방식으로 하면 카메라 구조가 바뀌지 않아서 BIRP <-> URP 상호 변환 하더라도 구조적인 변경 없이 편하게 적용 용 할 수 있을 것 같다.

결국 BIRP -> URP로 갈 때는 카메라 한 대가 더 추가될 뿐이다.

반응형
Posted by blueasa
, |

[링크] https://github.com/do-won-kim/CameraStack

GitHub - do-won-kim/CameraStack

Contribute to do-won-kim/CameraStack development by creating an account on GitHub.

github.com

 

반응형
Posted by blueasa
, |

[링크] https://github.com/GeonhanLee/SceneStack

GitHub - GeonhanLee/SceneStack: SceneStack is a multi-scene management system with URP CameraStack support.

SceneStack is a multi-scene management system with URP CameraStack support. - GeonhanLee/SceneStack

github.com

 

반응형
Posted by blueasa
, |

[링크] https://zenn.dev/nikaera/articles/unity-ios-android-secret-manager

 

Unity で iOS/Android アプリの設定値をセキュアに扱う方法

はじめに iOS/Android でユーザーの情報をセキュアに扱う必要があったので、調査したところ Android には EncryptedSharedPreferences が存在することを知りました。iOS には Keychain Services が存在します。

zenn.dev

 

 

[링크] https://github.com/nikaera/Unity-iOS-Android-SecretManager-Sample

 

GitHub - nikaera/Unity-iOS-Android-SecretManager-Sample: EncryptedSharedPreferences および Keychain Services を Unity から

EncryptedSharedPreferences および Keychain Services を Unity から利用する Unity サンプルプロジェクト - nikaera/Unity-iOS-Android-SecretManager-Sample

github.com

 

반응형
Posted by blueasa
, |

[링크] https://apidog.com/kr/blog/unity-mcp-server-kr/

 

유니티 MCP 서버: 클로드와 함께 AI를 사용하여 유니티 프로젝트 제어하기

상상해 보세요, 몇 가지 자연어 프롬프트만으로 전체 게임을 만들 수 있는 세상을. 게임 개발과 AI 기반 창의성의 경계가 점점 모호해지는 Unity MCP의 세계에 오신 것을 환영합니다. 바이브 코딩이

apidog.com

 

[github] https://github.com/justinpbarnett/unity-mcp

 

GitHub - justinpbarnett/unity-mcp: A Unity MCP server that allows MCP clients like Claude Desktop or Cursor to perform Unity Edi

A Unity MCP server that allows MCP clients like Claude Desktop or Cursor to perform Unity Editor actions. - justinpbarnett/unity-mcp

github.com

 

반응형
Posted by blueasa
, |

[링크] https://overworks.github.io/unity/2018/08/30/finding-best-string-concatenation.html

 

그때는 맞고 지금은 틀리다 - 문자열 연결 시에 가장 효율적인 방법은 StringBuilder가 아닐 수도 있

StringBuilder.AppendFormat()에 대한 설명에 잘못된 점이 있어 수정했습니다. (2018.9.1)

overworks.github.io

 

반응형
Posted by blueasa
, |

Unity 2021.3.49f1

Blender 4.3

----

 

블랜더에서는 트위스트 본이 정상적으로 회전이 먹히는데 유니티에서 제대로 되지 않고 캔디 랩(Candy Wrap) 현상이 생겨서 보정하기 위해 찾아보고 남겨 둠.

 

아래는 Unity의 RotationConstraint 사용해서 처리 하는 영상이다.

 

[참조] https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Animations.RotationConstraint.html

 

Unity - Scripting API: RotationConstraint

Success! Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable. Close

docs.unity3d.com

 

위 영상에서는 손목 본과 트위스트 본이 엮여있지 않아서 RotationConstraint를 사용가능 하다.

본 구조를 수평적으로 바꿀 수 있으면 위 방식대로 하면 될 것 같다.

 

지금 프로젝트의 모델은 본 구조가 트위스트 본과 손목 본이 트리구조로 엮여있어서 어쩔 수 없이 아래 스크립트 처럼 위 본에 가중치만큼 더해주고, 아래에서 틀어지지 않게 가중치만큼 다시 빼주고 있다.

그리고 Eular 값을 사용하면서 유니티에서는 - 값의 각도를 넣어도 0 ~ 360도 사이 값으로 보정돼서(예: -10도 == 350도 와 같다.) 오히려 꼬이는 상황이 생겨서

180도 이상을 넘어가게 되면 360도를 빼서 마이너스 각도로 보정해서 계산하도록 했다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 모델링 CnadyWrap 보정 클래스
/// SourceBone이 자식(Child)으로 묶여 있을 때 사용
/// 자식으로 묶여있지 않으면 RotationConstraint 사용하면 됨
/// [참조] https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Animations.RotationConstraint.html
/// (이 스크립트는 DestBone에 추가해줘야 함)
/// </summary>
public class RotationConstraintController : MonoBehaviour
{
    private Transform m_trDestBone = null;   // 적용 대상(Dest) 본
    [SerializeField] private Transform m_trSourceBone;   // 참조(Source) 본

    [Range(0f, 1f)]
    [SerializeField] private float m_fWeight = 0.5f;

    void OnEnable()
    {
        if (null == m_trDestBone)
        {
            m_trDestBone = GetComponent<Transform>();
        }
    }

    void LateUpdate()
    {
        if (null == m_trTwistBone || null == m_trSourceBone)
            return;

        // 참조(Source) 본 회전값 가져오기
		float fY = m_trSourceBone.localRotation.eulerAngles.y;

		// 180도 넘어가면 -값으로 치환하기 위해서 -360 해줌
		if (180f <= fY)
		{
    		fY -= 360f;
		}

		// 가중치 적용(Default : 0.5f)
		fY *= m_fWeight;

		// Dest(대상) 본에 적용(필요시 축 제한)
		m_trDestBone.localRotation = Quaternion.Euler(m_trDestBone.localRotation.eulerAngles.x, 
        		                                        m_trDestBone.localRotation.eulerAngles.y + fY,
                		                                m_trDestBone.localRotation.eulerAngles.z);
		//  Source(참조) 본 보정
		m_trSourceBone.localRotation = Quaternion.Euler(m_trSourceBone.localRotation.eulerAngles.x,
        		                                        m_trSourceBone.localRotation.eulerAngles.y - fY,
                		                                m_trSourceBone.localRotation.eulerAngles.z);
    }
}

 

더 테스트는 해봐야겠지만 일단은 예상한대로 작동은 하는 것 같다.

 

 

[도움 및 출처] 삼님

반응형
Posted by blueasa
, |

Unity 2021.3.49f1
Xcode 16.2
----
 

 
Facebook iOS SDK 18.0.0 버전을 추가하면서 소스코드가 많이 늘어났는지 Xcode에서 위와 같은 빌드 에러가 뜬다.
결국 소스코드 양을 줄여야 된다는 말인데.. 전부터 느끼는 거지만 Facebook SDK는 쓸데없이 다 때려박아놔서 소스양이 많아서 이런저런 문제를 계속 만들어 내는 것 같다.
 
 
검색해보니 아래와 같은 내용이 있다.

[출처] https://issuetracker.unity3d.com/issues/ios-arm64-branch-out-of-range-747396072-max-is-plus-slash-128mb-xcode-error-when-building-development-build-with-script-debugging

 

Unity IssueTracker - [iOS] ARM64 branch out of range (747396072 max is +/-128MB) Xcode error when building development build wit

How to reproduce: 1. Open the 728989.zip project 2. Build the project for iOS with "development build" and "script debugging" enable...

issuetracker.unity3d.com

 
 
위 내용을 참조해서 iOS의 Managed Stripping Level을 현재 Minimal에서 Low로 한단계 올리니 빌드가 잘된다.

 

소스코드의 양이 문제면 다른 곳을 줄일 생각도 해야되나 싶지만, 간단하게 해결하려면 이게 편한 것 같다.

[추가]

Managed Stripping Level을 올리는 건 아무래도 찜찜해서 최후의 수단으로 두고,

난독화 툴에서 Dummy Code를 생성하는데 그 부분을 Off하고 빌드하니 빌드 잘돼서 일단 이렇게 두기로 했다.

 

 

[참조] https://docs.unity3d.com/kr/2021.3/Manual/ManagedCodeStripping.html

 

관리되는 코드 스트리핑 - Unity 매뉴얼

빌드 프로세스 중에 Unity는 관리되는 코드 스트리핑이라는 프로세스를 통해 사용하지 않거나 도달할 수 없는 코드를 제거하므로 애플리케이션의 최종 빌드 크기를 대폭 줄일 수 있습니다. 관리

docs.unity3d.com

 

[참조] https://www.cnblogs.com/billyrun/articles/18247631

 

Unity打包il2cpp编译链接时报错 - 冯校长 - 博客园

当il2cpp生成的C++文件过多时,部分版本(2022.3)的unity会遇到链接失败的问题(ios/android均存在,在部分打包机上几乎稳定重现)项目il2cpp目录下的cpp代码量约1000左右,大小接近2G打包失败具体表现为Library/

www.cnblogs.com

 

[참조] https://blog.yusong.me/unity/platform/ios

 

iOS Platform | Yusong

 

blog.yusong.me

 

 

반응형
Posted by blueasa
, |

Unity 2021.3.47f1

----

 

Dynamic Font의 옵션에 Include Font Data가 체크 돼 있으면,  AssetBundle 빌드 시 Font도 번들에 포함 되는 것 같다.

[참조] https://codingstarter.tistory.com/37

 

[Unity] AssetBundle & Addressable 폰트 중복 로드 문제

- UI를 번들에서 로드하도록 수정 했더니 메모리에 동일한 폰트가 중복으로 로드되는 현상이 발생 - 동일한 폰트여도 각 번들마다 개별적으로 로드되는 것으로 추정 - 폰트 에셋의 Include Font Data

codingstarter.tistory.com

 

AssetBundle 빌드는 스크립트로 하기 때문에 위 참조 링크의 내용대로

AssetBundle 빌드 전, IncludeFontData를 false로 하고,

AssetBundle 빌드 후, IncludeFontData를 true로 되돌리도록 처리했다.

 

기본적으로 Dynamic Font의 폴더를 지정은 해야되지만 폴더의 하위는 모두 훑어서 ttf파일은 모두 처리하도록 해뒀다.

        /// <summary>
        /// Dynamic Font Path
        /// 사용하는 Dynamic Font를 AssetBundle 빌드 할 때 포함 안되도록
        /// AssetBundle 빌드 시, false 했다가 되돌리기 위해 사용
        /// [주의] 실제 사용하는 다이나믹 폰트 Folder Path 체크 필요
        /// </summary>
        private static string m_strDynamicFontFolderPath = "Assets/Fonts/Dynamic";

        public static void ProcessIncludeFontData(string _strTargetDirectory, bool _bActive)
        {
            if (false == Directory.Exists(_strTargetDirectory))
                return;

            System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(_strTargetDirectory);
            foreach (System.IO.FileInfo fi in di.GetFiles())
            {

                if (fi.Extension.ToLower().CompareTo(".ttf") == 0)
                {
                    //string strFileNameOnly = fi.Name.Substring(0, fi.Name.Length - 4);
                    string strFullFilePath = fi.FullName.Replace("\\", "/");
                    Debug.LogWarningFormat("[strFullFilePath] {0}", strFullFilePath);

                    // 프로젝트 절대경로 제거하고 상대경로로 변경(Assets는 남기기)
                    string atrAssetPath = strFullFilePath.Replace(Application.dataPath, "Assets");
                    Debug.LogWarningFormat("[atrAssetPath] {0}", atrAssetPath);

                    TrueTypeFontImporter cImporter = AssetImporter.GetAtPath(atrAssetPath) as TrueTypeFontImporter;
                    if (null != cImporter)
                    {
                        cImporter.includeFontData = _bActive;
                        cImporter.SaveAndReimport();

                        Debug.LogWarningFormat("[atrAssetPath] {0} [cImporter.includeFontData] {1}", atrAssetPath, cImporter.includeFontData);
                    }
                }
            }

            foreach (System.IO.DirectoryInfo sdi in di.GetDirectories())
            {
                Debug.LogWarningFormat("[SubDirectory.FullName] {0}", sdi.FullName);
                ProcessIncludeFontData(sdi.FullName, _bActive);
            }
        }
        
        /// <summary>
        /// IncludeFontData 활성화
        /// </summary>
        public static void ActiveTrueTypeFont_IncludeFontData()
        {
            if (false == Directory.Exists(m_strDynamicFontFolderPath))
                return;

            ProcessIncludeFontData(m_strDynamicFontFolderPath, true);
        }

        /// <summary>
        /// IncludeFontData 비활성화
        /// </summary>
        public static void InActiveTrueTypeFont_IncludeFontData()
        {
            if (false == Directory.Exists(m_strDynamicFontFolderPath))
                return;

            ProcessIncludeFontData(m_strDynamicFontFolderPath, false);
        }

 

 

P.s. NGUI Font는 해당 옵션이 없어서 어떻게 처리해야될지 고민..

반응형
Posted by blueasa
, |