묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
사운드 사용 문의
안녕하세요. 사운드 관련 사용 범위를 알고 싶어 문의드립니다. 이 프로젝트에 사용된 사운드는 제가 개발하고 있는 게임에 사용해도 되는지 궁금합니다.
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
어드레서블 로드 시 스프라이트는 하위객체의 찐이름으로 로드하는 이유가 뭔가요?
Addressables.LoadAssetAsync<T>(loadKey) 부분에서loadKey = "name.sprite[name]" 형식으로 들어가길래 에디터 어드레서블 그룹에서 찾아보니스프라이트 하위의 객체(?) 이름이더군요스프라이트만 이렇게 로딩하는 이유가 무엇일까요?
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
not exist in the namespace 에러가 납니다
error CS0234: The type or namespace name 'AddressableAssets' does not exist in the namespace 'UnityEngine' (are you missing an assembly reference?) error CS0234: The type or namespace name 'ResourceManagement' does not exist in the namespace 'UnityEngine' (are you missing an assembly reference?) 이 두 부분에서 에러가 뜨는데 어떻게 해결해야 하나요?
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
상업적출시를 위한 에셋 사용범위 문의
우선 좋은 강의 감사합니다.강의해주신 내용 토대로, 좀 더 디벨럽한뒤에 마켓에 출시하고자 합니다. 커뮤니티 게시판에 일부 에셋은 사용해도된다고 하였는데, 확인 차 문의드립니다.캐릭터와 UI/ UX 수정은 하지만, 몬스터 디자인이 맘에 들어 그대로 사용하려고 합니다. 사용해도 되는지 여부와, 몬스터 이미지 에셋 판매 계획이 있으신지 문의드립니다!
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
PoolManager Pool.OnGet에러질문드립니다.
팝업창에서 하위 ui item 자식들을 삭제하고 생성하고를 반복하다보면 어느순간 삭제된 오브젝트를 참조했다고 Pool.OnGet에서 오류가 출력됩니다. void OnGet(GameObject go)에 go는 null값이들어오는데 이유를 모르겠습니다. 버튼을 누르면 모든자식을 DestroyChilds를 통해 삭제하고 makesubitem을 통해서 다시 여러개를 출력합니다. 어떻게 null값이 나오는지 모르겠습니다. 오류내용은 아래와같습니다,MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it.Your script should either check if it is null or you should not destroy the object.Pool.OnGet (UnityEngine.GameObject go)
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
보스와 인공지능에서 질문있습니다.
안녕하세요.보스와 인공지능에서 보스의 캐릭터가 영상처럼 공격을 하고 다시 찾고 하지 않습니다.혹시 몰라서 보스와 인공지능의 프로젝트파일로 열어서 확인해보아도 동일한 현상이 발생하였습니다.그래도 혹시 몰라서 코드와 파일을 복사 붙어넣기해도 동일한 증상이 발생하였습혹시 짐작되는 부분이 있을까요? 추가 정보MonsterController 의 UpdateController가 작동이 안되는 것을 확인하였습니다.BossController 의 UpdateMoving도 작동안되는 것을 확인했습니다.Play 와 CrossFade 도 같은 증상입니다.
-
해결됨[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
상업적 출시를 목적으로 한 게임에 코드를 재사용해도 되는지 질문드립니다.
안녕하세요.C# 서버 강의와 실전 코드 리뷰 강의들로 공부할 때 많은 도움을 받고 있습니다.아트를 제외한 소스코드 부분을 일부 수정하여 상업적으로 출시할 게임에 재사용해도 되는지 질문드립니다.감사합니다.
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
Addressable 에러납니다...
Addressable설치 하고 에디터 Play하면 위와 같은 에러가 발생합니다... 버전 업/다운을 해봐도 마찬가지네요... 찾아보니 대략 이런 내용인거 같은데 해결을 못하겠네요 https://forum.unity.com/threads/addressablesgroupwindow-missing-styles-in-2022-3-1.1445899/
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
GetComponent 할때 AddComponent 질문입니다!
항상 예외나 문제가될 사항에 준비하라고 말씀해주셧는데GetComponent 를 해서 어떤 컴포넌트를 가져올때if (GetComponent == null ){ AddComponent<>();} 이런식으로 만약 추가가안되있다면 추가해주는 방식을 추가해주는거는 어떤가요? 너무 사용이 많아져서 오버된 행동일까요??
-
해결됨[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
스킬중에 주변을 도는 파티클은 충돌체크를 어떤식으로 할까요?
안녕하세요.뱀서류 게임을보면 캐릭터 주변을 돌면서 적에게 충돌하면 데미지를주는 스킬들이 있는데요이경우는 충돌체크를 어떤식으로 해야할까요?스킬이 제자리에서 사용되거나 정지해 있는경우가 아니라 움직이는경우라 질문드립니다.
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
스킬개론에서 설명한 xml이 엑셀 상태일땐...
스킬개론에서 설명한 xml이 엑셀 상태일땐 어떤 형태인지가 궁금해 지네요. 관련되어서 예시 이미지나 관련 정보 페이지가 있을까요?계층구조라서 엑셀로는 어떻게 만들어야하는지헷갈리네요;엑셀에서 표를 만들어 나오면xml 파일로 수정하고 내부의 내용을 순서대로 정렬하고이런 작업을 추가적으로 해야하는 것처럼 보여서요.
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
스프라이트 로그가 안됩니다. 이유를 모르겠어요...
아래와 같이 강좌를 통해서 이유를 찾고있는데요. 폴더에 있는 최신 참조 파일과도 다른 점이 없었고,유니티를 재부팅을 통해서도 확인해보았으나 현상은 동일했습니다. 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라는 값은 어디서 보내주는 값인지질문드립니다..