묻고 답해요
156만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨AI 시대의 혁신적인 게임 개발 입문 with Unity6
Canvas 사이즈 관련 질문입니다.
실습 환경 : Mac OS M2 Pro유니티 자체가 처음이어서 질문이 방향을 벗어날 수도 있다는 점 양해 부탁드립니다. 강의에서 실습을 따라하다 보면 다른 설정들은 전부 동일하게 UI가 세팅이 되는데,Canvas 내에 들어가는 Item들은 전부 강의에서보다 제 환경에서 크기나 좌표들이 작게 세팅됩니다.(예를 들면, 강의에서는 Pos X를 350으로 두었을 때 거의 오른쪽 끝에 도달하는데 제 화면에서는 오른쪽 중앙 정도에 위치하거나, Item들을 같은 사이즈로 세팅해도 폰트나 이미지 크기가 강의에서보다 작게 세팅됩니다.)이렇게 되는 이유가 있는 걸까요? 강의랑 동일하게 재현하기 위한 설정이 따로 존재하는지도 궁금합니다. 감사합니다.
-
해결됨AI 시대의 혁신적인 게임 개발 입문 with Unity6
Player Input Setting 관련 질문입니다.
실습 환경 : Mac OS M2 Pro유니티 자체가 처음이어서 질문이 방향을 벗어날 수도 있다는 점 양해 부탁드립니다. 유니티에서 프로젝트를 생성한 뒤 Input 관련 코드를 작성하면 항상 아래와 같이 뜨는데요,InvalidOperationException: You are trying to read Input using the UnityEngine.Input class, but you have switched active Input handling to Input System package in Player Settings.구글링해 보니 Edit > Project Settings > Player의 Active Input Handling을 Both로 변경하면 해결된다고 하여 그렇게 세팅한 뒤 해결했습니다.다만 여기서 궁금한 점이 두 가지가 있는데요,해당 설정의 Default 값은 Input System Package (New) 인데 이게 Default인 이유가 있을 것 같은데 오류가 발생하는 걸 보면, 강의에서는 Input Manager (Old) 와 관련된 Input들로 진행이 된 걸까요? 만약 그렇다면 그렇게 진행한 이유가 궁금합니다.강의에서는 해당 오류가 발생하지 않은 걸 보면 기본 세팅 자체가 다른 게 아닌가 추측되는데, 기본적으로 해당 속성을 Both로 설정하신 건가요? 만약 그렇다면 저의 경우는 프로젝트가 생성될 때마다 해당 설정을 변경해줘야 했는데 어떻게 가능한 건지 방법이 궁금합니다.감사합니다.
-
미해결절대강좌! 유니티 6 - TPS 게임으로 배우는 유니티 마스터클래스
Barrel에 IDamagable 적용 관련 질문
안녕하세요.Damage를 입는 대상에 대해서 IDamagable 인터페이스를 적용하는 부분은 알겠습니다.다만, 지금과 같이 Barrel에 적용하였을 경우, Raycast의 설정된 거리 문제로 실제 화면에서는 barrel에 총알이 부딪히는 효과가 나타나지만 터지지 않는 문제가 발생할 수 있을 것 같은데, 단순히 거리를 늘려서 해결하는 것이 맞을지 아니면 다른 방법이 있을지 궁금합니다.Raycast를 추가하지 않고 해결하려면Raycast에서 거리 증가총알이 Raycast 감지 영역을 벗어났을 때 Relase이렇게 밖에 떠오르지 않아서요.
-
해결됨[Unity] 직접 구현하는 게임 알고리즘 & 게임 시스템 구현
수업코드 git이 있을까요?
안녕하세요 수업코드를 다운로드 받을수 있는 git이 있을까요?
-
미해결따라하면서 배우는 고박사의 유니티 기초
05-02 실습에서 마지막 부분을 해보니 죽는 키를 누르면 die 가 두번 재생됩니다
강의 마지막 부분을 실습할 때 저번 강의의 platformer에서 사용했던 코드에 Die부분들을 덧붙이고 z키를 누르면 playerDie로 전환되게 설정해놓았습니다. 그런데 실행시키고 animator 창을 보면 z를 눌렀을 때 idle에서 die로 넘어가고 die가 전부 실행된 후 idle로 다시 넘어갔다가 자동으로 die를 한번 더 재생하는 현상이 발생했습니다. 그런데 두번째 die실행에서는 'End of Die Animation' 이 나오지는 않습니다.
-
미해결[라이브 멘토링] 유니티 뱀파이어 서바이벌 장르 모작
젬 스프라이트가 로딩되지 않습니다.
스프라이트 리소스를 비동기 로딩할 때 EXPGem_01.sprite 키값을 EXPGem_01.sprite[EXPGem_01]형태로 수정하여 Addressables.LoadAssetAsync함수를 호출해도 Texture2D타입의 오브젝트가 로딩되는데 왜 이런 현상이 생길까요? string key = Random.Range(0, 2) == 0 ? "EXPGem_01.sprite" : "EXPGem_02.sprite"; Texture2D texture = Managers.Resource.Load<Texture2D>(key); Sprite sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f)); go.GetComponent<SpriteRenderer>().sprite = sprite;강제로 스프라이트를 생성해서 영상처럼 랜덤하게 젬이 드랍되긴 하는데 어디가 문제인지 모르겠어서 질문 드립니다.
-
해결됨[Unity] 함께 만들어가는 방치형 게임 개발
프로젝트 공유해주실수 있나요
메일 확인했습니다 감사합니다!
-
해결됨[Unity] 함께 만들어가는 방치형 게임 개발
작업한 프로젝트가 날아갔는데...
혹시 유니티 프로젝트를 공유받을 수 있을까요... ㅠㅠurea42@naver.com입니다.
-
미해결[유니티 실전 프로젝트] Burger Please 모작
Scripts 폴더 만들 때 왜 골뱅이(@) 붙이나요?
@Resources@Scenes@Scripts등 폴더 이름 지을 때 왜 앞에 @를 붙이나요?
-
해결됨두고두고 써먹는 유니티 VR
몹의 Nav mesh agent가 이상합니다
안녕하세요. 해당 강의를 수강하는 중 스포너까지 만들고 실행을 해보니 스폰은 되는데 호박 몹이 맵을 따라 이동하질 않습니다... 강의에서 말씀하신대로 radius랑 height설정했는데 그게 몹에 잘 적용이 안된것같기도 합니다.. 답변해주시면 감사하겠습니다!
-
해결됨[Unity6] 나만의 서바이벌 게임 만들기
Resources.RoadAll 질문
안녕하세요. 현재 프로젝트 진행중이라 강의를 잠시 쉬고 있지만 정말 큰 도움을 받아서 감사드립니다. ^^여쭤보고 싶은게 있어서요. 강의 외 질문이 있어서. 여쭤봅니다. Resources폴더에 scriptable파일을 15개 정도 두고 게임을 진행했는데 Resources.LoadAll이 함수에서 계속 걸려서 앞으로 나가지를 못하네요. 왜이렇게 시간이 걸리는건지?? 구글링 해 보니 대규모 프로젝트에서는 addressable을 많이 사용한다는데 파일 15개정도를 로드하는 것을 대규모라고 볼 수는 없을 것 같은데요. 조언 구합니다.
-
미해결1. 유니티가 어려운 입문자를 위한 강의
유니티 설치 질문
안녕하세요! 현재 시점 기준으로 유니티6까지 나왔는데,영상에서 소개해주신 버전으로 다운 받아야 강의 듣기 수월할까요?아니면 상관없나요?
-
해결됨AI 시대의 혁신적인 게임 개발 입문 with Unity6
수박게임 질문
수박게임 최초 개발자는 개발한 게임을 어디 플랫폼에 올리고 등록해서 거대한 부를 얻은건가요?
-
미해결유니티 머신러닝 에이전트 완전정복 (기초편)
dqn 인덱스 에러
dqn 학습 부분에서, index에러가 자꾸 납니다.. dqn.py는 github에 올려져 있는 것을 그대로 사용했습니다. < 에러 코드 >(colab) C:\Users\pss60\Desktop\ML-Agents_Project\agents>python dqn.py Traceback (most recent call last): File "C:\Users\pss60\Desktop\ML-Agents_Project\agents\dqn.py", line 218, in <module> state = preprocess(dec.obs[OBS], dec.obs[GOAL_OBS]) IndexError: list index out of range < GridAgent >using System; using UnityEngine; using System.Linq; using Unity.MLAgents; using Unity.MLAgents.Sensors; using Unity.MLAgents.Actuators; using UnityEngine.Rendering; using UnityEngine.Serialization; using System.Collections.Generic; public class GridAgent : Agent { [FormerlySerializedAs("m_Area")] [Header("Specific to GridWorld")] public GridArea area; public float timeBetweenDecisionsAtInference; float m_TimeSinceDecision; [Tooltip("Because we want an observation right before making a decision, we can force " + "a camera to render before making a decision. Place the agentCam here if using " + "RenderTexture as observations.")] public Camera renderCamera; VectorSensorComponent m_GoalSensor; private Transform agentTrans = null; private Vector3 moveRight = new Vector3(1, 0, 0); private Vector3 moveLeft = new Vector3(-1, 0, 0); private Vector3 moveUp = new Vector3(0, 0, 1); private Vector3 moveDown = new Vector3(0, 0, -1); public enum GridGoal { GreenPlus, RedEx, } // Visual representations of the agent. Both are blue on top, but different colors on the bottom - this // allows the user to see which corresponds to the current goal, but it's not visible to the camera. // Only one is active at a time. public GameObject GreenBottom; public GameObject RedBottom; GridGoal m_CurrentGoal; public GridGoal CurrentGoal { get { return m_CurrentGoal; } set { switch (value) { case GridGoal.GreenPlus: GreenBottom.SetActive(true); RedBottom.SetActive(false); break; case GridGoal.RedEx: GreenBottom.SetActive(false); RedBottom.SetActive(true); break; } m_CurrentGoal = value; } } [Tooltip("Selecting will turn on action masking. Note that a model trained with action " + "masking turned on may not behave optimally when action masking is turned off.")] public bool maskActions = true; const int k_NoAction = 0; // do nothing! const int k_Up = 1; const int k_Down = 2; const int k_Left = 3; const int k_Right = 4; EnvironmentParameters m_ResetParams; public override void Initialize() { m_GoalSensor = this.GetComponent<VectorSensorComponent>(); m_ResetParams = Academy.Instance.EnvironmentParameters; } public override void CollectObservations(VectorSensor sensor) { Array values = Enum.GetValues(typeof(GridGoal)); int goalNum = (int)CurrentGoal; // 현재 에이전트의 x, y 좌표 위치 값을 관측 정보에 추가 sensor.AddObservation(agentTrans.position.x); sensor.AddObservation(agentTrans.position.z); // 각각 도형에 대한 좌표 위치 값을 관측 정보에 추가 List<int> otherPos = area.otherPos; for (int i = 0; i < otherPos.Count; i++) sensor.AddObservation(otherPos[i]); // 목표 지점에 대한 정보 m_GoalSensor.GetSensor().AddOneHotObservation(goalNum, values.Length); } public override void WriteDiscreteActionMask(IDiscreteActionMask actionMask) { // Mask the necessary actions if selected by the user. if (maskActions) { // Prevents the agent from picking an action that would make it collide with a wall var positionX = (int)agentTrans.localPosition.x; var positionZ = (int)agentTrans.localPosition.z; var maxPosition = (int)m_ResetParams.GetWithDefault("gridSize", 5f) - 1; if (positionX == 0) { actionMask.SetActionEnabled(0, k_Left, false); } if (positionX == maxPosition) { actionMask.SetActionEnabled(0, k_Right, false); } if (positionZ == 0) { actionMask.SetActionEnabled(0, k_Down, false); } if (positionZ == maxPosition) { actionMask.SetActionEnabled(0, k_Up, false); } } } // to be implemented by the developer public override void OnActionReceived(ActionBuffers actionBuffers) { // 매 행동마다 -0.01 보상(패널티) 부여 AddReward(-0.01f); var action = actionBuffers.DiscreteActions[0]; // 에이전트가 이동하게 될 위치 값을 저장할 변수 (Vector3) var targetPos = agentTrans.position; switch (action) { case k_NoAction: // do nothing break; case k_Right: // 부여받은 행동이 오른쪽이라면, targetPos = agentTrans.position + moveRight; // 현재 위치에서 1만큼 x축 방향으로 설정 break; case k_Left: targetPos = agentTrans.position + moveLeft; break; case k_Up: targetPos = agentTrans.position + moveUp; break; case k_Down: targetPos = agentTrans.position + moveDown; break; default: throw new ArgumentException("Invalid action value"); } var hit = Physics.OverlapBox( targetPos, new Vector3(0.3f, 0.3f, 0.3f)); // 벽에 부딪히지 않았다면, if (hit.Where(col => col.gameObject.CompareTag("wall")).ToArray().Length == 0) { // 정해진 위치로 이동 agentTrans.position = targetPos; // +오브젝트 만났다면, if (hit.Where(col => col.gameObject.CompareTag("plus")).ToArray().Length == 1) { ProvideReward(GridGoal.GreenPlus); EndEpisode(); } // x오브젝트 만났다면, else if (hit.Where(col => col.gameObject.CompareTag("ex")).ToArray().Length == 1) { ProvideReward(GridGoal.RedEx); EndEpisode(); } } } private void ProvideReward(GridGoal hitObject) { if (CurrentGoal == hitObject) { SetReward(1f); } else { SetReward(-1f); } } // WASD 키보드로 에이전트 이동 public override void Heuristic(in ActionBuffers actionsOut) { var discreteActionsOut = actionsOut.DiscreteActions; discreteActionsOut[0] = k_NoAction; if (Input.GetKey(KeyCode.D)) { discreteActionsOut[0] = k_Right; } if (Input.GetKey(KeyCode.W)) { discreteActionsOut[0] = k_Up; } if (Input.GetKey(KeyCode.A)) { discreteActionsOut[0] = k_Left; } if (Input.GetKey(KeyCode.S)) { discreteActionsOut[0] = k_Down; } } // to be implemented by the developer public override void OnEpisodeBegin() { area.AreaReset(); Array values = Enum.GetValues(typeof(GridGoal)); CurrentGoal = (GridGoal)values.GetValue(UnityEngine.Random.Range(0, values.Length)); } public void FixedUpdate() { WaitTimeInference(); } void WaitTimeInference() { if (renderCamera != null && SystemInfo.graphicsDeviceType != GraphicsDeviceType.Null) { renderCamera.Render(); } if (Academy.Instance.IsCommunicatorOn) { RequestDecision(); } else { if (m_TimeSinceDecision >= timeBetweenDecisionsAtInference) { m_TimeSinceDecision = 0f; RequestDecision(); } else { m_TimeSinceDecision += Time.fixedDeltaTime; } } } }
-
해결됨AI 시대의 혁신적인 게임 개발 입문 with Unity6
타이핑 할 때 왜 자꾸 화면에 숫자x 이거 왜생기는거에요? 엄청 거슬리네요.
타이핑 할 때 왜 자꾸 화면에 숫자x 이거 왜생기는거에요? 엄청 거슬리네요.
-
해결됨AI 시대의 혁신적인 게임 개발 입문 with Unity6
초반 세팅시 버전 및 템플릿 질문
안녕하세요다른 분야 개발중인데 흥미가 생겨서 수강하게 되었습니다다름이 아니라 초반 세팅을 하면서 궁금한 점이 생겨서 문의를 남기게 되었는데요 현재(2025년 5월 26일) 기준으로 설치 가능한 유니티6 버전이LTS인 6.0(6000.0.49f1)Supported인(하지만 추천딱지가 붙어있는) 6.1(6000.1.3f1) 이렇게 두종류가 있던데 강의는 아무 버전으로 들어도 진행에 무리가 없을까요? 두번째로 첫 프로젝트를 생성하는 과정에서 템플릿을 선택할때저는 Universal 2D가 가장 위에 있던데, 상관없이 2D (Built-in Render Pipeline)을 선택하면 될까요?그걸 눌렀을때 오른쪽에 프로젝트 세팅 화면이 안나오고 템플릿을 다운로드 받으라는 버튼이 뜨길래 여쭤봅니다 감사합니다
-
해결됨유니티 시스템 프로그래밍 Pt.1 - 상용 게임 구현을 위한 핵심 시스템 올인원 패키지
캔버스를 여러 장 사용하는 이유
좋은 강의 감사드립니다. 현재 설계 상 각 씬마다 LobbyUIController, InGameUIController 각각 해당 씬의 UI 캔버스를 가지고 해당 씬 고유의 UI 를 그리고, UIManager 또한 스스로의 캔버스를 가지고 DontDestroyOnLoad 에 남아서 여러 씬에서 공통적으로 사용되는 UI 를 그리고 있는데요. UIManager 가 DontDestroyOnLoad 에 상주하면서 모든 UI 를 그리는 구조와 비교했을 때 장단점이 무엇일지 여쭤보고 싶습니다. 캔버스와 카메라가 많은 것보다 UI 관련 캔버스를 하나로 통일하고 싶은데 스스로 생각해보아도 두 설계의 장단점에 대해 구체적으로 결론내리기가 어려웠습니다. 감사합니다!
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
SocketAsyncEventArgs.BufferList에 관해 질문
void RegisterSend() { if (_disconnected == 1) return; while (_sendQueue.Count > 0) { ArraySegment<byte> buff = _sendQueue.Dequeue(); _pendingList.Add(buff); } _sendArgs.BufferList = _pendingList; try { bool pending = _socket.SendAsync(_sendArgs); if (pending == false) OnSendCompleted(null, _sendArgs); } catch (Exception e) { Console.WriteLine($"RegisterSend Failed {e}"); } } void OnSendCompleted(object sender, SocketAsyncEventArgs args) { lock (_lock) { if (args.BytesTransferred > 0 && args.SocketError == SocketError.Success) { try { _sendArgs.BufferList = null; _pendingList.Clear(); OnSend(_sendArgs.BytesTransferred); if (_sendQueue.Count > 0) RegisterSend(); } catch (Exception e) { Console.WriteLine($"OnSendCompleted Failed {e}"); } } else { Disconnect(); } } }해당 코드에 대한 질문이 있습니다.RegisterSend에서 sendQueue에 있는 패킷들을 다 빼내서 pendingList에 넣고 pendingList를 args.BuffList로 설정합니다.이후 OnSendComplete에 처리에 의문이 있습니다.TCP 특성상 부분 전송이 이루어질 수 있다고 생각합니다.부분 전송이 일어날 경우 확인을 안하고 pendingList.Clear해버리면 send패킷이 유실될 것 같습니다.BufferList에 넣으면 SendAsync시에 c#에서 무조건 전송을 보장해주는건가요? 아니면 BufferList를 사용하지 말고 recv버퍼처럼 해야할 것 같다는 생각이 들어 질문합니다.또한 BufferList에서 부분전송 체크할 방법이 있나요?
-
미해결절대강좌! 유니티6 - 네트워크 게임 개발 마스터클래스 (Part 1)
7강 재생
7강 재생이 안 되는데요. 혹시 비슷한 문제가 있을까요?
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진
GetComponent<Poolable> 질문드립니다.
C++과 다이렉트를 배우고 유니티를 배우기위해 학습하고있는 학생입니다 리소스 매니저에서 인스턴시에이트 시점에 각 오리지널 객체에대해 GetComponent함수를 통해 Poolable 객체의 보유여부를 판단하는 모습으로 보이는데요 C#과 유니티에 아직 미숙해서 문의를 남깁니다.GetComponent의 원리가 C++에서 각 컴포넌트를 일차원배열을 선형탐색하여 각각 폭포식으로 dynamic cast를 해보는것과 비슷한 수행성능을 낼 것으로 판단되는데이게맞다면 모든객체의 인스턴스화 시점에 많은 오버헤드를 일으키지않나요?만약 맞다면 풀 매니저에서 poolable을 지닌 객체와 안지닌 객체에대해 해시셋등의 자료구조를 통해 두가지의 경우를 캐싱을 하고최초로 검사하는경우에만 GetComponent를 호출해서 맞는 컨테이너에 캐싱후 결과를 반환하는 식으로 하면 어떨까 질문드립니다.예시로 만든 코드 남겨드립니다.