묻고 답해요
130만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
스프라이트 로그가 안됩니다. 이유를 모르겠어요...
아래와 같이 강좌를 통해서 이유를 찾고있는데요. 폴더에 있는 최신 참조 파일과도 다른 점이 없었고,유니티를 재부팅을 통해서도 확인해보았으나 현상은 동일했습니다. 33:40분에 이야기한 소문자 이야기에 계속 돌려서 보았으나 소문자 부분을 찾지 못하였습니다. 혹시 문제가 무엇일까요....? 디버그.로그를 통해서 확인해보니 최초에 정상 로드가 확인되지만, 이후 생성할려고 할때 Null 값이 노출되는 것을 확인하였습니다.. using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using Unity.Mathematics; using Unity.VisualScripting; using UnityEngine; public class ObjectManager { public PlayerController Player { get; private set; } // 플레이어는 따로 관리 public HashSet<MonsterController> Monsters { get; } = new HashSet<MonsterController>(); // 몬스터도 따로 관리 public HashSet<ProjectileController> Projectiles { get; } = new HashSet<ProjectileController>(); // 발사체도 따로 관리 public HashSet<GemController> Gems { get; } = new HashSet<GemController>(); // 잼 따로 관리 public T Spawn<T>( Vector3 position , int templateID = 0) where T : BaceController { System.Type type = typeof( T ); if( type == typeof(PlayerController) ) { GameObject go = Managers.Resource.Intantsiate("Slime_01.prefab", pooling: true);// 프리팹 불러오기 go.name = "Player"; /////////////////////////////////////////////////////////////////////// //// /// go.transform.position = position; // 좌표에 배치 /////////////////////////////////////////////////////////////////////// PlayerController pc = go.GetOrAddComponent<PlayerController>(); // 컨트롤러 불러오기 Player = pc; // 컨트롤러 붙이기 pc.Init(); //초기화 return pc as T; } else if (type == typeof(MonsterController)) { string name = (templateID == 0 ? "Goblin_01" : "Snake_01"); // 지금은 억지로 부여하지만, 데이터 테이블이 만들어지면 수정할 것 GameObject go = Managers.Resource.Intantsiate( name + ".prefab" , pooling: true ); /////////////////////////////////////////////////////////////////////// //// /// go.transform.position = position; // 좌표에 배치 /////////////////////////////////////////////////////////////////////// MonsterController mc = go.GetOrAddComponent<MonsterController>(); Monsters.Add( mc ); // 만들어지는 동시에 Monsters 안에 관리하에 들어가게 됨. mc.Init(); //초기화 return mc as T; } else if( type == typeof(ProjectileController)) { return null; } else if (type == typeof(GemController)) // 잼 컨트롤러 작동원리 { GameObject go = Managers.Resource.Intantsiate( Define.EXP_GEM_PREFAB , pooling: true); go.transform.position = position; GemController gc = go.GetOrAddComponent<GemController>(); Gems.Add( gc ); // 폴더에 추가 gc.Init(); //초기화 // 아이템 종류 변경하기. ( 하드코딩 : 확인용 ) string key = UnityEngine.Random.Range(0, 2) == 0 ? "EXPGem_01.sprite" : "EXPGem_02.sprite"; Sprite sprite = Managers.Resource.Load<Sprite>(key); go.GetComponent<SpriteRenderer>().sprite = sprite; UnityEngine.Debug.Log( sprite ); //Debug.Log($"sprite Name: {sprite.name}"); if (sprite) { UnityEngine.Debug.Log($"sprite Name: {sprite.name}"); } return gc as T; } return null; } // public void Despawn<T>(T obj) where T : BaceController { System.Type type = typeof(T); if (type == typeof(PlayerController)) { //? } else if (type == typeof(MonsterController)) { Monsters.Remove(obj as MonsterController); Managers.Resource.Destroy(obj.gameObject); } else if (type == typeof(ProjectileController)) { Projectiles.Remove(obj as ProjectileController); Managers.Resource.Destroy(obj.gameObject); } else if (type == typeof(GemController)) { Gems.Remove(obj as GemController); Managers.Resource.Destroy(obj.gameObject); } } } using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AddressableAssets; // 에셋 가져오고 using UnityEngine.ResourceManagement.AsyncOperations; // 회색은 필요없다느 뜻임 using System; using Object = UnityEngine.Object; public class ResourceManager { // 리소스를 계속 들고 있도록 Dictionary로 만든다. Dictionary<string, UnityEngine.Object> _resources = new Dictionary<string, UnityEngine.Object>(); // 리소스 로드 ( 이미 위의 Dictionary에서 이미 로드를 한 상태라 부담이 없다. ) public T Load<T>(string key) where T : Object { if (_resources.TryGetValue(key, out Object reource)) { return reource as T; } return null; } // Load 를 사용하여 리소스 된 후 인스텐션해서 복사본을 만든다. public GameObject Intantsiate(string key, Transform parent = null, bool pooling = false) { /////////////////////////////////////////////////////////////// // 원본 프리팹을 가져옴 GameObject prefab = Load<GameObject>($"{key}"); if (prefab == null) { Debug.Log($"Failed to load prefab :{key}"); return null; } /////////////////////////////////////////////////////////////// // Pooling if ( pooling ) { return Managers.Pool.Pop(prefab); } /////////////////////////////////////////////////////////////// /// 부하가 많이 걸리는 부분 => 그래서 오브젝트풀링( 활성/비활성화 )로 진행 GameObject go = Object.Instantiate( prefab , parent ); go.name = prefab.name; return go; } // 오브젝트 삭제 용도.(공용) ( 어드레서블로 만들어지지 않은 애들도 삭제됨 ) public void Destroy(GameObject go) { if ( go == null ) return; if ( Managers.Pool.Push(go) ) { return; } // Pool이 있으면 반납 Object.Destroy(go); // Pool이 없으면 삭제 } #region 어드레서블 public void LoadAsync<T>( string key, Action<T> callback = null ) where T : UnityEngine.Object //LoadAsysnc<T>( 키값 , 알려줄 무언가 ) { // 캐시 확인 if (_resources.TryGetValue(key, out Object resource)) // _resources 키값으로 리소스를 찾은적있다. { callback.Invoke(resource as T); return; // 2번째인경우 리턴 } string loadKey = key; if (key.Contains(".sprite")) loadKey = $"{key}[{key.Replace(".sprite", "")}]"; ////////////////////////////////////////////////////////////// // 리로스 비동기 로딩 시작. // 아래는 코드가 완성되면 처리가 끝나면 신호줌. var asyncOperation = Addressables.LoadAssetAsync<T>(loadKey); // 처음인 경우, 로드함. ( 비동기 방식으로 ) asyncOperation.Completed += (op) => { _resources.Add(key, op.Result); callback.Invoke(op.Result); }; } // 내가 원하는 라벨을 검색 후, public void LoadAllAsync<T>(string label, Action<string, int, int> callback ) where T : UnityEngine.Object //LoadAllAsync<T>( 라벨명 , 알려줄 무언가 ) { var opHandle = Addressables.LoadResourceLocationsAsync(label, typeof(T)); opHandle.Completed += (op) => { int loadCount = 0; int totalCount = op.Result.Count; foreach (var reult in op.Result) // 원하는 값이 나올때까지 반복 { LoadAsync<T>(reult.PrimaryKey, (obj) => // PrimaryKey 파일의 이름 // loadCount 몇번째인지 { loadCount++; callback?.Invoke(reult.PrimaryKey, loadCount, totalCount); }); } }; } #endregion } ///////////////////////////////// /// 추가함 using System; ///////////////////////////////// using System.Collections; using System.Collections.Generic; ///////////////////////////////// /// 추가함 using Unity.VisualScripting; ///////////////////////////////// using UnityEngine; ///////////////////////////////// /// 추가함 using UnityEngine.Diagnostics; using UnityEngine.EventSystems; public static class Extension // Extension문법은 (this GameObject go)에서 this를 함으로써 this.GetOrAddComponent와 같이 사용할수있는 문법 { public static T GetOrAddComponent<T>(this GameObject go) where T : UnityEngine.Component { return Utils.GetOrAddComponent<T>(go); } public static bool isValid(this GameObject go) { return go != null && go.activeSelf; } public static bool isValid(this BaceController bc) { return bc != null && bc.isActiveAndEnabled; } } using System.Collections; using System.Collections.Generic; using UnityEngine; public static class Define { public enum Scene { Unknown, DevScene, GameScene, } public enum Sound { Bgm, Effect, } public enum ObjectType { Player, Monster, Projectile, Env, } public const int PLAYER_DATA_ID = 1; public const string EXP_GEM_PREFAB = "EXPGem.prefab"; }
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
UI_gameoverpopup 관련
안녕하세요,강의 너무 감사합니다.게임을 진행하다보면 게임오버 팝업이 발동 후 종료를 클릭하게 되면 게임오버 팝업이 먼저 사라지고 scene 전환 애니메이션 활성화 후 마지막에 게임 배틀 장면 scene 이 노출되고 로비 scene으로 이동하게 됩니다. 혹시 마지막 게임 배틀 장면 scene을 노출 안되게 하는 방법이 있을까요?항상 감사합니다.
-
해결됨[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
Missing built-in guistyle ToolbarSeachCancelButtonEmpty 오류 관련 해결 방법 공유
안녕하세요혹시나 저와 같은 오류를 겪고 계신 분이 있을까봐 문제 및 해결 방법 공유드립니다 강사님께서 알려주신 그대로 진행했지만 빌드 옆에 검색창이 없고제목에 적어둔 것처럼 미싱 빌트인~ 오류가 발생했는데요유니티 측에서 search가 아닌 seach라는 사소한 오타를 낸 상태로 업그레이드를 진행하여 생긴 오류로 판단했고, 구글링해보니 저와 같은 오류를 겪고 있는 사람이 꽤 많고 상당히 오래된 오류로 보였습니다.(임의로 해결하는 방법이 여럿있었으나 저에게는 모두 먹히지 않았습니다)최종적인 해결 방법으로는 유니티 에디터 버전을 2021.3.29 -> 2022.2.2로 업그레이드 한 후 해당 프로젝트에서 어드레서블을 검색하여 설치합니다.이렇게 되면 프로젝트 이름/Library/PackageCache 폴더 안에 com.unity.addressables~ 라는 폴더가 생길텐데, 해당 폴더를 지금 작업하고 있는(강사님과 같은 유니티 버전인 2021 에디터)의 프로젝트 이름/Packages에 붙여넣기 합니다.제대로 진행했을 경우 아래 사진처럼 어드레서블(커스텀)이라고 바뀌고아래 사진과 같이 빌드 버튼 옆에 제대로 검색창이 나타나게 되며 콘솔창의 오류 또한 사라집니다.혹시나 저와 같은 오류를 겪고 당황해하는 분들이 계실까봐 공유합니다.
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
매니저 강의 중 16:00에 말한 파트3? 는 무엇인가요?
매니저 강의 중 16:00에 말한 파트3? 는 무엇인가요?
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
IsSubclassOf 질문입니다
else if(type == typeof(ProjectileController)) { GameObject go = Managers.Resource.Instantiate("FireProjectile.prefab", pooling: true); go.transform.position = position; ProjectileController pc = go.GetOrAddComponent<ProjectileController>(); Projectiles.Add(pc); pc.Init(); return pc as T; } 총알이 계속 안불러와져서 코드실수인가 해서 계속 체크하다가 중단점 잡고 보니else if (typeof(T).IsSubclassOf(typeof(ProjectileController)))이 부분을else if(type == typeof(ProjectileController))이렇게 바꾸고나니 총알이 제대로 불러와지더라구요 뭐가 문제인가요?? 강사님 코드에서는 isSubclassOf 를 쓰셔도 잘 발사가 되는거 같은데
-
해결됨[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
캐릭터가 가만히 있어도 계속 밀려요
캐릭터가 몬스터한테 둘러쌓여서 밀린후에 빠져나가고 가만히 있으면 아무런 동작을 하지 않음에도 캐릭터가 천천히 밀리고 있어요그래서 원래 코드인Vector3 dir =_moveDir * _speed * Time.deltaTime;transform.position += _dir;이 부분을 rigidbody를 가져와서 아래와 같이 바꿨는데Vector2 dir = _moveDir * _speed * Time.deltaTime;_rigid.MovePosition(_rigid.position + dir);문제 되는 부분이 있을까요?? 해결방법이 추후 강의목차에서 해결이 되나요?
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
CSV 파일로부터 데이터 로딩 모듈
안녕하세요.소스에 JSON 파일로부터 데이터 로딩하는 부분은 있는데, CSV 파일로부터 데이터 로딩하는 부빈이 없습니다.CSV 파일로부터 데이터 로딩하는 것을 구현할려고 하는데, 혹시 힌트 같은 것이 있을까요?
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
게임 최적화 관련해서 질문입니다.
안녕하세요. 올려주신 강의는 마지막까지 잘 들었습니다.강의 토대로 모작을 해보고 있는 중인데 올려주신 최종 코드로 게임을 돌려보면후반부에 프레임 드랍과 부하가 너무 심하더군요. 배치도 500 이상으로 올라가구요.아마도 몹수 보다는 경험치 보석 때문인거 같은데 어떻게 해결할 수 있을까요?보석은 중간 중간에는 자석으로 없앨 수 있지만 후반부에 몹들이 몰려와서 플레이어가 정지해 있으면서 보석이 쌓이는 구간에 들어서면 눈에 띄게 부하가 걸리는게 보입니다. 또한 모바일에서는 어느 정도 배치와 드로우콜을 목표로 개발해야 할지 알려주시면 좋겠습니다.
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
익명 함수의 인자값 op 의 출처는 어디인가요?
asyncOperation이 로드가 완료됐을때 complete안에 집어넣은 함수가 호출되는 구조는 이해했습니다.한가지 의문점은 op라는 값은 어디서 보내주는 값인지질문드립니다..
-
해결됨[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
장비의 옵션을 불러오는 부분에서 질문이 있습니다.
JSON 에서 데이터를 불러오고 장비 아이콘을 클릭 하였을때 장비의 아이콘과 옵션의 수치가 표시되는 부분이 궁금하여 뜯어보다가 질문이 생겼습니다.무기의 경우에는 HP보너스 스탯이 존재하지 않아도 JSON에서 0을 부여하고 추후에 UI_EquipmentinfoPopup에서 HP 스탯이 0인지 아닌지를 판별하여 장비의 아이콘과 옵션 수치를 표시하고 있는것을 확인 했어요.그런데 장비의 옵션 수치가 2개를 넘어서 더 여러가지가 되었을 경우에도 이런 방식으로 처리하는것이 효율적일까요? 아래 코드를 스위치문으로 변경하여 스탯에 맞는 아이콘과 옵션을 찾던가 JSON 구조 자체를 변경해야될것 같은데 어떤 방향으로 해야할지 잘 모르겠어서 선생님의 조언을 구합니다.
-
해결됨[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
안녕하세요. 7월 예정강의에 대해 질문이 있습니다.
유니티 & 웹서버(키우기 게임 + 웹서버) 강의가 7월 예정으로 들었는데 항상 강의 전달 말쯤에소식이 들렸는데 이번엔 아직 소식이 없어서 질문드립니다!관련해서 예정이 있으신건가요?
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
이 강의는 아직 완성되지 않은 강의인가요?
영상에서도 설명을 들었는데 갓챠부분이나 서버연동 부분에 대한 언급도있었고 3~4개월짜리 짧은 프로젝트로 계획중이라고 하신걸 들었는데 차후 이 강의에 추가 영상이 올라오나요? 미완성인 부분이 어떤 부분들이 있고 (EX. 갓챠, 서버연동, 그외??) 영상 업로드 계획은 언제쯤인지 궁금합니다!
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
sprite가 load되지 않습니다 2
6월 15일 같은 질문이 나왔었는데요,해당 질문글에 답변으로 적어주신 방법을 써서 스프라이트로 변환해서 잘 돌아가긴 하는데요, 아직 이해가 되지 않아 추가질문 드립니다.강의에서는 texture로 받지 않기 위해 ResourceManager.cs에서 키값을 EXPGem_01.sprite[EXPGem_01]으로 바꾸는 과정을 거쳤는데요, 그럼에도 불구하고 왜 변환이 안된 건가요? 강의에서는 잘 작동하는 것처럼 보입니다만,..혹시 유니티 버전에 따라 작동을 안하는 것일까요? 현재 22.3버전으로 쓰고 있습니다. 강의상 10분쯤에 해당내용 있습니다.감사합니다.
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
비주얼스튜디오 솔루션탐색기 관련 질문입니다
안녕하세요, 비주얼스튜디오 툴과 관련하여 질문이 있습니다.강의영상 내 루키스님 비주얼스튜디오를 보면 솔루션에 프로젝트가 1 프로젝트의~라고 뜨는데요, 저는 83개의 프로젝트가 포함되었다고 나옵니다.아래 사진처럼 Assembly-CSharp 이외의 프로젝트들을 언로드하면 빌드에러가 나는 문제가 생기는데요, 강의하시는 화면내 솔루션은 어떻게 프로젝트가 1개만 로드되어있는지 궁금합니다.감사합니다. 그리고, 좋은 강의 만들어주셔서 감사합니다.제가 오랫동안 찾던 이상적인 개발강의이기에, 정말 감사히 생각하며 듣고 있습니다.건강하세요.
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
소스 자료를 다운받아보니, Addressables group 이 하나도 없습니다.
[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작마지막 올려주신 소스 자료를 다운받아보니,Addressables group 이 하나도 없습니다.버전이 맞지 않아서 발생한 문제인가 생각하여,강의에서 사용한 2021.3.19f1 으로 실행해봐도 동일하게 에러가 발생합니다.
-
해결됨[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
sprite가 load가 되지않습니다
Managers.Resource._resources 에 아래 동작으로 sprite를 넣었는데 막상 저장된 곳을보면 sprite가 아닌 texture입니다 string loadKey = key; if (key.Contains(".sprite")) loadKey = $"{key}[{key.Replace(".sprite", "")}]"; // 리소스 비동기 로딩 시작. var asyncOperation = Addressables.LoadAssetAsync<T>(loadKey); 그래서 젬의 sprite가 변경이되지않습니다..코드는 첨부된걸로 해봐도 동일한데 유니티문제일까요?
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
안녕하세요 마지막 버전 프로젝트는
안녕하세요 마지막 프로젝트는 게임이 실행이 안되는거같은데아직 미완성이라 그런건가요?
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
섹션2 매니저 강의 중 프로퍼티로 인스턴스 리턴하는 부분 질문
싱글턴 구현을 위해 public static Managers Instance 프로퍼티를 만들고 Managers로 리턴하는것 까진 이해했습니다.근데, 다른 매니저 구현하는 부분에서DataManager _data = new DataManager(); 로인스턴스화 한 후,public static DataManager Data { get return Instance?._data;}}프로퍼티를 통해 리턴하는 부분이 이해가 안됩니다.강의에서는 싱글턴으로 구현된 매니저에 다른 매니저들을 붙이는 거라고 말씀하셨는데, 리턴문이 이해가 안되네요.?. 는 널체크고 사실상 Instance._data; 로 해도 실행은 잘되는것 같아서 저것만 가지고 질문을 드리자면Data 프로퍼티를 호출하면 Instance 프로퍼티에 _data 에 담긴 인스턴스를 입력(set)하고 리턴을 한다는건지..(근데 그와중에 Instance 프로퍼티에 set은 또 없고..)Instance 프로퍼티에서 get해서 가져오고 뭔가?를 해서 인스턴스를 리턴하는거같은데, 구문이 이해가 안가네요.. (문법실력이 부족한거같아서 구글링을 아무리해도 찾을수도 없네요 ㅜㅜ)보통 이렇게 점을 찍어서 하는건 클래스 내부 요소를 요청하거나 메서드 체이닝을 하거나 할 때 쓰는거 아닌가 싶은데,Instance라는 프로퍼티에 점을 찍은후 생성한 _data 인스턴스를 이어서 코딩하는건 도저히 이해가 안가네요 ㅠㅠ어떤부분을 제가 공부하면 이해가 잘될까요. 아 그리고 추가 질문 하나더 드리자면.. Data 프로퍼티를 통해 Instance를 거쳐 리턴되는 값은 DataManager 형식일텐데, Instance는 Managers 형식인데 어떻게 저렇게 리턴이 가능한건가요? 그냥 클래스 인스턴스끼리는 된다고 생각하면되나요?
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
텍스쳐에서 스프라이트로 변경하는 것 관련 질문입나디
젬 떨구기 강좌에서 png를 adrressable로 긁어올 때 png 대신 내부의 이름으로 읽는다는 부분을 이해했습니다.궁금한 점은 스프라이트 시트처럼 특정 텍스쳐 안의 다수의 스프라이트가 존재할 때 그 이름 별로 로드할 수 있는 방법이 있는 지 입니다.key값으로 걸어보니 스프라이트 시트의 이름으로 걸리고 하부 아이템들의 이름을 탐색할 방법을 못찾아서 일단은 임시로 리소스 폴더에 보관후 리소스 loadAll을 하는 중인데 addressable로도 관리할 방법이 있는 지 알고 싶습니다.
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
에셋 출처 질문
선생님 안녕하세요. 강의 너무 잘듣고 있습니다.다름이 아니라, 실제로 간단하게 출시를 해보려고 하는데 강의에서 사용하신 플레이어의 EgoSword와 다른 파티클 에셋들이 유니티 에셋스토어에서 구입 후 사용하신 에셋이라면 어떤 에셋인지 궁금해서 질문을 드리게 되었습니다.