묻고 답해요
144만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
스킬중에 주변을 도는 파티클은 충돌체크를 어떤식으로 할까요?
안녕하세요.뱀서류 게임을보면 캐릭터 주변을 돌면서 적에게 충돌하면 데미지를주는 스킬들이 있는데요이경우는 충돌체크를 어떤식으로 해야할까요?스킬이 제자리에서 사용되거나 정지해 있는경우가 아니라 움직이는경우라 질문드립니다.
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
스킬개론에서 설명한 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"; }
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진
질문있습니다
여기서 찾아달라는 타입을 로그인씬이 아니라 베이스씬으로 해주는 이유가 있나요? 직관적으로 생각했을때는 로그인씬을 찾아줘야 되니까 로그인씬을 제너릭에 넣어줘야 할거 같아서요.. 그리고 저렇게 로그인씬을 찾고싶을때에도 베이스씬을 상속받았으니까 저렇게 해줘도 되는거네요?!
-
해결됨두고두고 써먹는 유니티 VR
apk문의
안녕하세요 선생님. 좋은 강의 감사합니다.만들어주신 내용을 토대로 퀘스트2용 apk를 빌드하려고 하는데, 유니티 허브 문제인지 컴퓨터가 이상한지, 도저히 Openjdk가 설치되지 않아 apk를 빌드할 수가 없습니다. 혹시, 만들어진 파일을 토대로 apk 파일을 받을 수 있을까요?간절한 마음으로 부탁드립니다. 감사합니다.
-
미해결유니티 Addressable 을 이용한 패치 시스템 구현
안녕하세요 빌드시... 용량이 줄지 않습니다.
안녕하세요.어드레시블을 사용하여 빌드를 하였는데요.빌드용량이 줄어들지 않아 문의드립니다. 참고 : 리소스 폴더는 없습니다.
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
UI_gameoverpopup 관련
안녕하세요,강의 너무 감사합니다.게임을 진행하다보면 게임오버 팝업이 발동 후 종료를 클릭하게 되면 게임오버 팝업이 먼저 사라지고 scene 전환 애니메이션 활성화 후 마지막에 게임 배틀 장면 scene 이 노출되고 로비 scene으로 이동하게 됩니다. 혹시 마지막 게임 배틀 장면 scene을 노출 안되게 하는 방법이 있을까요?항상 감사합니다.
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
솔루션 'Server'(0개의 프로젝트)로 생성이 되어버립니다.
'콘솔 앱(.NET Core)'가 존재 하지 않아서 '콘솔 애플리케이션'으로 프로젝트를 생성하였습니다. .NET 데스크톱 개발은 설치가 되어있습니다.개별 구성요소에서 .NET Core 3.1 Runtime(Out of support)를 체크하여 '콘솔 애플리케이션'을 만들었습니다. 프로젝트를 생성하였으나 솔루션에 프로젝트가 0개라고 떠서 더이상 진행 할 수 가 없습니다. 혹시 어떻게 해결하면 될까요??
-
해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진
스크립트템플릿 설정
똑같이 따라했는데 템플릿이 변경되지 않습니다 뭐가 문제일까요? 혹시나 해서 관리자 권한 메모장 실행해서 확인해봐도 변경된 걸로 확인되는데 스크립트를 만들어보면 변경되기 전으로 나옵니다
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
게임 룸 입장, 퇴장 관련 패킷이 궁금합니다
안녕하세요 게임 서버 개발자가 되고 싶어서 공부중입니다.카트라이더처럼 유저가 게임 룸을 만들고 원하는 룸에 입장하고, 퇴장하는 게임을 만들 때, 생성되어있는 게임 룸들의 리스트들을 서버에서 받아와야 하는데 이 때 룸 정보들을 요청하는 패킷, 예를들면 C_RoomList 같은 패킷이 필요할까요?그리고 룸에서 퇴장할 때도 C_LeaveRoom 같은 패킷이 필요한지 궁금합니다. 정확하게는 GameRoom 코드에서 LeaveGame과 ClientSession의 OnDisconnected가 어떻게 작동되는 것인지 궁금합니다.항상 좋은 강의 감사드립니다!!
-
해결됨[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
Missing built-in guistyle ToolbarSeachCancelButtonEmpty 오류 관련 해결 방법 공유
안녕하세요혹시나 저와 같은 오류를 겪고 계신 분이 있을까봐 문제 및 해결 방법 공유드립니다 강사님께서 알려주신 그대로 진행했지만 빌드 옆에 검색창이 없고제목에 적어둔 것처럼 미싱 빌트인~ 오류가 발생했는데요유니티 측에서 search가 아닌 seach라는 사소한 오타를 낸 상태로 업그레이드를 진행하여 생긴 오류로 판단했고, 구글링해보니 저와 같은 오류를 겪고 있는 사람이 꽤 많고 상당히 오래된 오류로 보였습니다.(임의로 해결하는 방법이 여럿있었으나 저에게는 모두 먹히지 않았습니다)최종적인 해결 방법으로는 유니티 에디터 버전을 2021.3.29 -> 2022.2.2로 업그레이드 한 후 해당 프로젝트에서 어드레서블을 검색하여 설치합니다.이렇게 되면 프로젝트 이름/Library/PackageCache 폴더 안에 com.unity.addressables~ 라는 폴더가 생길텐데, 해당 폴더를 지금 작업하고 있는(강사님과 같은 유니티 버전인 2021 에디터)의 프로젝트 이름/Packages에 붙여넣기 합니다.제대로 진행했을 경우 아래 사진처럼 어드레서블(커스텀)이라고 바뀌고아래 사진과 같이 빌드 버튼 옆에 제대로 검색창이 나타나게 되며 콘솔창의 오류 또한 사라집니다.혹시나 저와 같은 오류를 겪고 당황해하는 분들이 계실까봐 공유합니다.
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진
unity 강의에서 singleton 패턴 강의
8:00 instance에 자기 자신을 누군가 채워야한다? 라고 하신거 같은데 무슨 뜻인지 잘 모르겠습니다 왜 해야 하는 건가요???
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진
유니티 가격 정책에 대해 어떻게 생각하시나요?
대학생이고 제 주변에 해당 업종에 종사하시는 분이 안계셔서 마땅히 여쭤볼 곳이 없어 올려봅니다.현업 종사자셨던 루키스님께서는이번 유니티 가격 정책에 어떻게 생각하시는지 여쭤봐도 될까요?실제로 이번 정책으로 인해 유니티에서 엔진을 변경하는 개발사가 많을까요?프로젝트를 진행하는 중 엔진을 변경하는 경우가 많나요?위 주제들에서 벗어나기는 하는데, DirectX와 OpenGL 둘 중 하나를 공부한다면 어떤 걸 추천하시나요? 이유도 알려주시면 감사하겠습니다.(DirectX는 윈도우 환경에서 잘 돌아가지만, OpenGL이 각종 운영체제에 호환이 잘 되는 것으로 알고있습니다.게임 프로그래밍에 관해 찾아보다보면 DirectX를 공부하는 것이 중요하다고들 하시며, 국내 게임 업계 채용사이트를 참고하더라도 DirectX 지식이 있는 개발자를 우대하는데, OpenGL에 관한 우대사항이 없는 이유가 궁금합니다.)만약 4번에서 DirectX를 추천하신다면, DirectX9부터 11, 12 순으로 공부하는 것이 좋을까요? 아니면 12로 바로 들어가도 괜찮나요?
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
매니저 강의 중 16:00에 말한 파트3? 는 무엇인가요?
매니저 강의 중 16:00에 말한 파트3? 는 무엇인가요?
-
해결됨두고두고 써먹는 유니티 VR
vr기기로 실행하는데 고개가 돌아가지 않아요
플레이를 하면서 고개를 좌우 상하로 돌려도 정면만 바라보고 있고 아예 뒤를 돌아도 정면 그대로 나오는데 어느 부분이 오류인걸까요?
-
해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진
FindChild() 함수 이용 중 오류
Util 스크립트에서 만든 FindChild() 함수를 UI 오브젝트가 아닌 다른 오브젝트에서도 사용하고 싶어 사용하던 중 문제가 발생하여 질문이 있습니다.FindChild() 함수의 리턴 값이 null이 되면 이후의 코드들이 실행이 안되던데 이유를 모르겠습니다.void OnEnable() { partToRotate = Util.FindChild(gameObject, "PartToRotate", true).transform; firePoint = Util.FindChild(gameObject, "FirePoint", true).transform; // 이후의 코드들 }위의 partToRotate와 firePoint 변수는 OnEnable() 함수에서는 사용되는 일이 없고 Update() 함수에서 사용됩니다. Update 함수에서 변수 값이 null로 인해 오류가 나는 거면 이해를 하겠는데, OnEnable() 함수에서 FindChild() 함수의 리턴 값이 null이 되면 왜 이후의 코드들이 실행이 안되는지 모르겠습니다.널 조건 연산자인 ?로 해결은 했으나, 왜 안되는지 이유가 궁금합니다.
-
해결됨두고두고 써먹는 유니티 VR
빌드 파일 공유
수업 자료로 올려주신 완성본 파일로 빌드를 해도 오류가 나서 테스트를 못하고 있는데 혹시 빌드파일을 수업 자료로 올려주실수 있으신가요?
-
해결됨두고두고 써먹는 유니티 VR
oculus 2 기기에 프로젝트가 실행이 안되요.
강의를 보고 유니티 내에서 실행이 모두 되는 것을 확인하고 vr 기기로 직접 플레이를 해보고 싶어서 빌드후 프로젝트 연결까지 성공했는데 vr기기로 플레이를 하려고 앱을 누르자 마자 made with unity 화면까지만 켜지고 게임이 진행되지않고 프로젝트가 꺼져버리는데 어디서 잘못된건지 모르겠습니다. 혹시 답변 가능할까요?
-
미해결유니티 머신러닝 에이전트 완전정복 (기초편)
GridWorld, CollectObservations에서 에러 질문입니다.
비슷한 주제로 네번째 글을 올리게 되었습니다. -.-;매번 답변에 항상 감사드립니다.몇몇 실수를 교정한 현재의 현상을 나열해 드립니다. 책 및 github의 스크립트를 따랐을 때(1) 실행 코드 (2)에러 화면동영상 강의 내용을 따랐을 때(1) 실행코드(2) 에러화면null==sensor 를 null!=sensor로 교정하였을 때(답변해주신 글 도움 받음)(1) 실행코드(2) 에러 화면 ※ observation size (6)와 observation size (2)의 인식이 문제인 것 같습니다. 도움 부탁드립니다.
-
미해결C#과 유니티, 실전 게임으로 제대로 시작하기 (저자 직강)
교재 관련 질문
이 강의 교재인 '처음 배우는 C# 프로그래밍'을 e-book으로 출시하실 계획은 없으신가요? 휴대성 때문에 서적보다는 e-book을 선호하는 편이라 출시가 된다면 구매하고 싶습니다.