묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진
씬 관리 질문이 있습니다.
안녕하세요!로드맵 강의를 수강하고 현재 게임을 직접 만들고 있습니다.캐릭터를 선택창이나 로그인화면 아이템샵 메인로비 등이 있는 로비 화면을 현재 만들고 있는데요현재는 기능별로 Scene을 새로 계속 생성하여 만들고 있습니다.근데 UI 데모파일들을 몇개 보면 모두 한 씬에 레이아웃들을 만들어놓고 SetActive 함수로 UI를 제어하는 경우가 많았습니다.그래서 Scene을 계속 만드는 방식과 하나의 Scene에 레이아웃을 각각 만들어놓고 SetActive함수로 제어하는 방식 두 방식중에 어느 것이 더 효율적인가요? 각각에 장단점이 있을까요?실제로 현업에서는 어떤 방식을 주로 쓰는지도 궁금합니다!바쁘시겠지만 답변 부탁드리겠습니다.
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진
Action 중복으로 등록되는 문제
안녕하세요. 지금까지 강의를 통해 배운 내용을 바탕으로 간단한 게임을 제작하고 있는 학생입니다. 어떤 파트에 질문을 달아야 할까 고민하다 마무리 부분에 올립니다.GameManagerEx에 SkillLevelUp이라는 Action을 만들어놓고 UI_SkillPopup을 열면 아래의 코드를 통해 LevelUp 함수를 취소/등록합니다. 그런데 ClosePopupUI를 통해 UI_SkillPopup을 닫고 해당 팝업을 다시 켜게 되면 기존에 등록해놓았던 LevelUp 함수가 취소되지 않아 버그가 발생합니다. 제 생각으로는 처음 등록한 LevelUp 함수와 두번째로 등록한 함수의 이름은 같지만 다른 함수로 인식하여 중복으로 등록이 되는 것 같았습니다.일단은 아래의 코드와 같이 Init 에서는 LevelUp 함수를 추가만 하고 UI_SkillPopup을 닫을 때 LevelUp 함수를 제거하는 방식을 사용하여 해결을 하긴 했습니다만 썩 우아한 방법이 아닌 것 같아 질문드리게 되었습니다.먼저 제가 인식한 버그가 Action이 중복으로 등록되는 문제가 맞는지, 만약 그렇다고 한다면 이와 같은 상황에서는 Init에서 Managers.Game.SkillLevelUp에 LevelUp 함수를 취소/등록하는 과정을 통해 초기화를 할 수 없는지 궁금합니다.부족한 질문 봐주셔서 감사합니다.
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진
마지막 익스텐션 오류 + 에니메이션 오류
마지막 저 코드만 주석처리해서 실행하면 정상적으로 실행이되는데, 주석처리만 해제하면 NullReferenceException: Object reference not set to an instance of an objectUI_Base.AddUIEvent (UnityEngine.GameObject go, System.Action`1[T] action, Define+UIEvent type) (at Assets/Scripts/UI/UI_Base.cs:48)Extension.AddUIEvent (UnityEngine.GameObject go, System.Action`1[T] action, Define+UIEvent type) (at Assets/Scripts/Utils/Extension.cs:11)UI_Button.Start () (at Assets/Scripts/UI/UI_Button.cs:39)같은 오류가 발생합니다. 우선 코드 첨부합니다추가적으로 RUN00_F외에 다른 에니메이션(RUN))_L 등)을 사용하면 정상적으로 에니메이션이 이동에따라 속도증가 -> run, 멈춤 -> wait가 되는데, RUN))_F 에니메이션을 사용하면 저런 메시지와 함께 멈춥니다.
-
해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
사용프로그램 관련해서 질문드립니다.
서버 개발을 할 때 VSCode를 사용해도 괜찮을까요?VS가 아니라 VSCode를 사용하면 생기는 장단점이 궁금합니다.
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진
13분20초즘 TEXT가 UI_BUTTON에 안놓아져요
코드를 따라서 작성하고 있고,UI_Button에 이제 TEXT만 넣으면 되는데 마우스 포인터 대신에 O에 /가 그어진 모양만 뜨고 연결이 안되네요. 코드를 계속 확인해봐도 동일한테 왜그럴까요
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진
플레이어 몬스터 접근시 넘어지면서 걷는 버그
플레이어 컴포넌트에는 박스 콜라이더, 내브 메쉬에이전트가 적용되어 있고 몬스터에는 박스콜라이더가 접근 되어있습니다. is kinematic체크를 해서 충돌해제를 하더라도 기울어지면서 결국 넘어지고 걷는 행동을 하는데요 혹시 이런 경우 해결하신 분 계신가요? 마우스를 계속 클릭하고 있을 때에는 몬스터를 뚫고 넘어갑니다.몬스터에 마우스를 클릭했을 때 매우 근접해졌을 때 몬스터 콜라이더에 의해서 넘어지는 것 같습니다. 콜라이더 제거시 넘어지지 않습니다. (클릭한 자리로 이동하려고 애씀.)
-
미해결
유니티 urp 보라색 오브젝트
유니티에 에셋을 가져와 신을 펼쳤는데 보라색이 있어 urp로 바꾸는데 오류가 뜨면서일부가 바뀌질 않습니다추가로 경고표시로 이런게 콘솔 창에 떠요Could not create a custom UI for the shader 'Burning'. The shader has the following: 'CustomEditor = ASEMaterialInspector'. Does the custom editor specified include its namespace? And does the class either derive from ShaderGUI or MaterialEditor?UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)
-
해결됨두고두고 써먹는 유니티 VR
빌드 오류
이 오류와 함께 빌드가 안됩니다. 안드로이드랑 windows 빌드 독같이 오류가 뜨고 오큘러스 연결은 완료했습니다.DirectoryNotFoundException: Could not find a part of the path "C:\Users\Public\Documents\ESTsoft\CreatorTemp\tmp35509cb5.tmp".
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진
Invoke()의 쓰임에 대해서 질문드립니다.
Invoke()에 대해서 자세히 알아보려고 구글링을 했을때는, Invoke("함수 이름", 시간) 시간만큼 "함수 이름"의 함수가 실행되는것을 지연시키고 실행하게끔 하는 기능이라고 되어있는데 . . 이번 강의에서는 인자없는 Invoke()와 Enum을 인자로 받는 Invoke함수를 사용하셨는데 이게 어떤것을 의미하는지 이해를 못하고있습니다 ㅜㅜ F12로 들어가서 찾아봐도 아무인자를 받지 않는것과 enum을 받는 Inovke에 대해서는 나와있지 않은것 같아 질문남깁니다.
-
미해결유니티 2D 로그라이크 게임 만들기 [한글자막]
플레이어 캐릭터나 적이 이동하는게 느리네요
올린 움짤처럼 다음 칸으로 이동하는게 천천히 이동되네요... ㅜㅠ 완성본으로 실행해도 똑같이 천천히 이동되더라구요... 스크립트는 다른 질문에서 본거처럼 GetAxisRaw로 해놨습니다!아마 제 환경이 문제가 되는거 같은데 알고 싶습니다
-
해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
OnRecv 질문
위 부분에서 dataSize를 알아낸 후 그만큼 데이터가 도착했는지 판별하는 부분에서질문 1. 만일 서버에 같은 세션으로부터 동시다발적으로 혹은 매우 짧은 간격을두고 Send요청이 일어나 여러 패킷이 멀티스레드로 Recv된다면 Recv버퍼에 dataSize만큼 데이터를 수신받았다고 하더라도 그 데이터가 항상 온전한 한 패킷의 연속적인 데이터로 도착하게끔 보장이 되나요?질문 2. 만일 그렇지않고 여러 뒤죽박죽 섞인다면 어떻게 뒤섞인 데이터를 분리하나요?옅은 지식으로나마 TCP에서 데이터의 순서는 어느정도 보장해주는것으로 알고있는데 한 패킷이 온전하게 도착할때까지 다른 전송이 대기하는지, 아니면 여러 요청중에서 먼저 도착하는 조각들을 무지성으로 때려박는지 아무리 찾아봐도 알 수 없어서 질문 남깁니다 ㅜㅜ
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
시간 복잡도는 사실상 똑같지 않나요?
안녕하세요 루키스님!항상 강의 잘 듣고 있습니다. 다름이 아니라 기존에는 N^2 의 시간 복잡도라고 말씀해주셨습니다. 그 이유도 충분히 이해했습니다.그래서 GameRoom.cs의 _pendingList와 Flush 함수를 패킷 모아 보내는 용도로 사용하셨습니다. 그러나 사실상 Flush 내부를 자세히 보면 결국 N^2으로 시간 복잡도는 똑같다고 생각합니다. 왜냐하면 Flush 내부에서 세션용 foreach와Send함수 내부에서 List<ArraySegment<byte>> 용의 foreach로 인해서 총 2개의 foreach가 돌기 때문에 시간 복잡도는 여저힌 N^2이지 않나요? 만약 10명의 클라이언트가 접속했을 때,[패킷 모아 보내기 할 경우]100개의 패킷을 한 번에 보내는 것[패킷 모아 보내기 안 할 경우]10개의 패킷을 10번 보내는 것 으로 이해 했는데 맞을까요?
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
switch문과 딕셔너리 효율 질문입니다.
https://rito15.github.io/posts/cs-switch-case-vs-dictionary/이 내용을 보면 딕셔너리를 이용하는것보다 스위치문을 이용하는게 더 효율적인것으로 보이는데, 어떤것이 맞는지 모르겠어요
-
해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
코드 오류 질문드립니다..ㅠㅠ
유니티 연동 #1 을 공부하는 도중 아래와 같은 오류가 떴습니다.유니티 서버를 연동하는 부분이고 정상동작을 한다면 Hello Server I am 1 이 출력되어야 합니다.소켓 부분에서 에러가 나서 OnConnectedCompleted 함수를 제대로 실행하시 못하는것 같습니다. 강의 파일을 받아서 실행해도 동일한 오류가 뜨고 아무리 구글링을 해봐도 해결을 못하겠어서 번거로우시겠지만 질문을 드립니다...
-
해결됨유니티 머신러닝 에이전트 완전정복 (기초편)
A2C 알고리즘을 드론 환경에 적용하려면
안녕하세요, 드론 환경에서 A2C 알고리즘을 적용해서 실험해보려고 합니다.환경에 맞게 적용을 하기 위해 state_size, action_size를 각각 9와 3으로 설정하고, 이 외에도 여러 부분을 수정하여 돌려 보려고 했는데 잘 안 되네요.get_action() 함수를 손보거나, preprocess를 하는 부분을 수정해주어야 할 것 같은데, 어떻게 해결해야 할지 잘 모르겠습니다.현재 상태에서는 다음과 같은 오류가 발생하고 있습니다.A2C.py의 코드는 아래와 같습니다.import numpy as np import datetime import platform import torch import torch.nn.functional as F from torch.utils.tensorboard import SummaryWriter from collections import deque from mlagents_envs.environment import UnityEnvironment, ActionTuple from mlagents_envs.side_channel.engine_configuration_channel\ import EngineConfigurationChannel # A2C를 위한 파라미터 값 세팅 state_size = 9 action_size = 3 load_model = False train_mode = True discount_factor = 0.9 learning_rate = 0.00025 run_step = 100000 if train_mode else 0 test_step = 10000 print_interval = 10 save_interval = 100 # VISUAL_OBS = 0 # GOAL_OBS = 1 # VECTOR_OBS = 2 # OBS = VECTOR_OBS # 유니티 환경 경로 game = "Drone" os_name = platform.system() if os_name == 'Windows': env_name = f"C:/Users/user/anaconda3/envs/mlagents/Drone_0427/Drone_1002_3.exe" elif os_name == 'Darwin': env_name = f"../envs/{game}_{os_name}" # 모델 저장 및 불러오기 경로 date_time = datetime.datetime.now().strftime("%Y%m%d%H%M%S") save_path = f"./saved_models/{game}/A2C/{date_time}" load_path = f"./saved_models/{game}/A2C/20210709235643" # 연산 장치 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") print("CUDA is available" if torch.cuda.is_available() else "CPU is available") # A2C 클래스 -> Actor Network / Critic Network 정의 class A2C(torch.nn.Module): def __init__(self, **kwargs): super(A2C, self).__init__(**kwargs) self.d1 = torch.nn.Linear(state_size, 128) self.d2 = torch.nn.Linear(128, 128) self.pi = torch.nn.Linear(128, action_size) self.v = torch.nn.Linear(128, 1) def forward(self, x): x = F.relu(self.d1(x)) x = F.relu(self.d2(x)) return F.softmax(self.pi(x), dim=1), self.v(x) # A2CAgent 클래스 -> A2C 알고리즘을 위한 다양한 함수 정의 class A2CAgent(): def __init__(self): self.a2c = A2C().to(device) self.optimizer = torch.optim.Adam(self.a2c.parameters(), lr=learning_rate) self.writer = SummaryWriter(save_path) if load_model == True: print(f"... Load Model from {load_path}/ckpt ...") checkpoint = torch.load(load_path+'/ckpt', map_location=device) self.a2c.load_state_dict(checkpoint["network"]) self.optimizer.load_state_dict(checkpoint["optimizer"]) # 정책을 통해 행동 결정 def get_action(self, state, training=True): # 네트워크 모드 설정 self.a2c.train(training) #네트워크 연산에 따라 행동 결정 pi, _ = self.a2c(torch.FloatTensor(state).to(device)) action = torch.multinomial(pi, num_samples=1).cpu().numpy() return action def train_model(self, state, action, reward, next_state, done): state, action, reward, next_state, done = map(lambda x: torch.FloatTensor(x).to(device), [state, action, reward, next_state, done]) pi, value = self.a2c(state) # Value network with torch.no_grad(): _, next_value = self.a2c(next_state) target_value = reward + (1-done) * discount_factor * next_value critic_loss = F.mse_loss(target_value, value) #Policy network eye = torch.eye(action_size).to(device) one_hot_action = eye[action.view(-1).long()] advantage = (target_value - value).detach() actor_loss = -(torch.log((one_hot_action * pi).sum(1))*advantage).mean() total_loss = critic_loss + actor_loss self.optimizer.zero_grad() total_loss.backward() self.optimizer.step() return actor_loss.item(), critic_loss.item() # 네트워크 모델 저장 def save_model(self): print(f"... Save Model to {save_path}/ckpt ...") torch.save({ "network" : self.a2c.state_dict(), "optimizer" : self.optimizer.state_dict(), }, save_path+'/ckpt') # 학습 기록 def write_summray(self, score, actor_loss, critic_loss, step): self.writer.add_scalar("run/score", score, step) self.writer.add_scalar("model/actor_loss", actor_loss, step) self.writer.add_scalar("model/critic_loss", critic_loss, step) # Main 함수 -> 전체적으로 A2C 알고리즘을 진행 if __name__ == '__main__': # 유니티 환경 경로 설정 (file_name) engine_configuration_channel = EngineConfigurationChannel() env = UnityEnvironment(file_name=env_name, side_channels=[engine_configuration_channel]) env.reset() # 유니티 브레인 설정 behavior_name = list(env.behavior_specs.keys())[0] spec = env.behavior_specs[behavior_name] engine_configuration_channel.set_configuration_parameters(time_scale=12.0) dec, term = env.get_steps(behavior_name) # A2C 클래스를 agent로 정의 agent = A2CAgent() actor_losses, critic_losses, scores, episode, score = [], [], [], 0, 0 for step in range(run_step + test_step): if step == run_step: if train_mode: agent.save_model() print("TEST START") train_mode = False engine_configuration_channel.set_configuration_parameters(time_scale=1.0) #preprocess = lambda obs, goal: np.concatenate((obs*goal[0][0], obs*goal[0][1]), axis=-1) #state = preprocess(dec.obs[OBS]) #state = preprocess(dec.obs[OBS],dec.obs[GOAL_OBS]) state = dec.obs[0] action = agent.get_action(state, train_mode) action_tuple = ActionTuple() action_tuple.add_continuous(action) env.set_actions(behavior_name, action_tuple) env.step() dec, term = env.get_steps(behavior_name) done = len(term.agent_id) > 0 reward = term.reward if done else dec.reward next_state = term.obs[0] if done else dec.obs[0] score += reward[0] if train_mode: agent.append_sample(state[0], action[0], reward, next_state[0], [done]) # 학습 수행 actor_loss, critic_loss = agent.train_model() actor_losses.append(actor_loss) critic_losses.append(critic_loss) if done: episode += 1 scores.append(score) score = 0 # 게임 진행 상황 출력 및 텐서 보드에 보상과 손실함수 값 기록 if episode % print_interval == 0: mean_score = np.mean(scores) mean_actor_loss = np.mean(actor_losses) mean_critic_loss = np.mean(critic_losses) agent.write_summray(mean_score, mean_actor_loss, mean_critic_loss, step) actor_losses, critic_losses, scores = [], [], [] print(f"{episode} Episode / Step: {step} / Score: {mean_score:.2f} / " +\ f"Actor loss: {mean_actor_loss:.2f} / Critic loss: {mean_critic_loss:.4f}") # 네트워크 모델 저장 if train_mode and episode % save_interval == 0: agent.save_model() env.close()답변 주시면 감사하겠습니다!
-
미해결[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템
새로운 강의 일정 질문입니다.
안녕하세요 이전에 드렸던 질문이긴 하지만, 새로운 강의(스킬 시스템)은 10월 경에 정확히 수강 할 수 있는지 알 수 있나요?
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
혹시 어려워서 포기할까 생각하시는 분들 보고 힘 얻으세요
지금 3번째 들으면서 지나가는 수강생입니다진짜 첫 번째 들을 때 두 번째 들을 때 세 번째 들을 때 이해되는 범위가 다릅니다처음에는 그냥 코드 따라 치면서 완주만 해보세요. 두 번째는 코드의 흐름만 본다는 느낌으로 따라가고, 세 번째는 강의를 눈으로만 보고, 혼자 힘으로 코드를 완성해 보면 확실히 체득이 되는 느낌입니다!다들 화이팅입니다! 저 같은 말하는 감자도 하는데 여러분도 할 수 있습니다!ps. 루키스님 강의 찍으시랴, 부트캠프 준비하시랴 많이 바쁘실텐데 항상 감사합니다!
-
해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
출력 간격 이상
안녕하세요 선생님! 클라이언트에서 온 패킷이 자꾸 이렇게 띄엄띄엄 출력 되는데 왜 그런지 알 수 있을까요?
-
미해결[유니티 3D] 실전! 생존게임 만들기 - Advanced
전체 프로젝트 파일 받을 수 있을까요?
강의를 보고 코드를 치다가 한두 곳 오류가 나왔는데 문제점을 도저히 못 찾겠습니다. 그래서 전체 프로젝트를 보면서 비교 분석해보고 싶은데 가능 할까요...?
-
해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
안녕하세요 강의 시청중 궁금한점 생겨서 질문드립니다.
웹서버의 경우 실무에서 docker를 많이 사용하는 것 같은데요, 혹시 소켓 기반 실시간 게임서버개발에도 docker를 많이 사용하는지 궁금합니다!