Announcement

Collapse
No announcement yet.

SkelControl 부분 네트워크 여쭤봐요 ㅠㅠ

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    SkelControl 부분 네트워크 여쭤봐요 ㅠㅠ

    안녕하세요
    niui이용해서 네트워크 게임을 만드는 중이랍니다 ㅠㅠ

    다름아니라 네트워크 상에서 캐릭터가 kinect로 움직이는 부분까진 되는데
    다른 클라이언트가 상대 캐릭터의 움직임을 전혀 읽지 못하는 문제가 생기고 있어요

    kinect로 캐릭터 bonerotation 값을 받아서 움직이는 쪽에서는 이상없이 값을 받는데
    로그 를 통해서 보면 서버나 다른 클라이언트 쪽은 전혀 값을 읽지 못하네요 ㅠ

    niuiSkelControl.BoneControllers[iter].BoneRotation = r_temp;
    여기 처럼 niuiSkelControl 이라는 actor 클래스에다 skelcontrolsingleBone 배열을 쭉 저장해서 kinect에 받은 rotation 값으로 캐릭터를 움직이는 부분이라 Pawn에서 rotation되는 부분만 replication해서 보여주면 상대방 클라이언트쪽에서도 보일거라고 생각은 하는데 도통 계속 안되네요 ㅠ

    simulated function rotator UpdateBoneOverride(float DeltaTime,Quat qOwner)
    {
    local rotator *****;
    local Quat qRot;

    if (Bound)
    {
    // Apply rotation but don't add it to the animation rotation.
    bApplyRotation = true;
    bAddRotation = false;

    // Get the bones rotation.
    qRot = QuatFromRotator(niuiCore.GetBoneRotation(UserID, intTargetBone));

    // Transform the cached delta by the OpenNI rotation.
    qROt = QuatProduct(qRot, self.qBoneRefRot);

    // Transform into world space based on the owner's orientation.
    ***** = QuatToRotator(QuatProduct(qOwner, qRot));


    // `log("BoneRotation 을 출력하라 : "$BoneRotation );
    }
    return *****;
    }
    위처럼 SkelcontrolSingbone 클래스를 만들어서 rotation값 *****을 리턴받은 뒤 Pawn에서 적용했는데 안되네요 ㅠㅠ

    꼭 답변좀 부탁드릴게요 ㅠ 혹시 소스 보셔야할꺼같으면 말씀주시면 보내드릴게요 ㅠ 부탁드려요!

    #2
    클라이언트가 위 함수의 실행 시점을 제공하는 경우(exec 함수, 클라이언트 자체 연산 시점 등)는

    서버에 동기화 시점을 제공해야 합니다.


    Code:
    exec function PlayerInput()
    {
         if (Role < Role_Authority)
              SyncProcessInput();
         ProcessInput();
    }
    
    server function SyncProcessInput()
    {
         ProcessInput();
    }
    
    function ProcessInput()
    {
         // some do
    }

    Comment


      #3
      그럼 그 동기화 시점을 제공해 주는 부분이 결정적으로 BONEROTATION을 지정해주는 값을 넣는 부분에 해야하나요?

      로그로 확인 해볼 결과 플레이하는 플레이어쪽 Pawn 클래스에서 Rotation 값이 정상적으로 나오나 서버에서 안나오는 경우 Pawn에서 서버 함수를 호출해줘야하는건가요?

      simulated function rotator UpdateBoneOverride(float DeltaTime,Quat qOwner)
      {
      local rotator *****;
      local Quat qRot;

      if (Bound)
      {
      // Apply rotation but don't add it to the animation rotation.
      bApplyRotation = true;
      bAddRotation = false;

      // Get the bones rotation.
      qRot = QuatFromRotator(niuiCore.GetBoneRotation(UserID, intTargetBone));

      // Transform the cached delta by the OpenNI rotation.
      qROt = QuatProduct(qRot, self.qBoneRefRot);

      // Transform into world space based on the owner's orientation.
      ***** = QuatToRotator(QuatProduct(qOwner, qRot));


      // `log("BoneRotation 을 출력하라 : "$BoneRotation );
      }
      return *****;
      }
      위 코드의 경우 skelcontrolsinglebone에 정의한 함수인데 여기서 가지고온 값을 pawn 상에서 서버와 동기화 시점을 제공해 주면 되는건가요??

      Comment


        #4
        동기화 시점이 플레이어 컨트롤러 또는 폰 또는 웨펀에서 시작되도록 하십시오.

        Comment


          #5
          너무 죄송해요 ㅠㅠ 지금 계속 해보는 중인데

          qOwner = QuatFromROtator(OwnerRot);

          BoneControllers[iter].bApplyRotation=true;
          BoneControllers[iter].bAddRotation=false;

          qRot = QuatFromRotator(niuiCOre.GetBoneRotation(NIUI_User ID, BoneControllers[iter].intTargetBone));

          // Transform the cached delta by the OpenNI rotation.
          qROt = QuatProduct(qRot, self.qBoneRefRot);

          // Transform into world space based on the owner's orientation.
          ***** = QuatToRotator(QuatProduct(qOwner, qRot));
          BoneControllers[iter].BoneRotation=*****;
          여기서 *****이라는 Rotation 값을 kinect로 얻어서 BoneRotation에 넣는데 계속 안되길래 *****에 임의의 값으로

          *****.Pitch=12342;
          *****.Roll=4564;
          *****.Yaw=2342;

          이렇게 넣어주니까 또 되네요 ㅠㅠ 대체 왜 이런거죠? ㅠㅠ 임의로 숫자값 하나 넣는건 되는데 kinect로 계산된 rotation 값은 계속 안나오니까 이유를 모르겠네요 ㅠㅠ 정말 이게 꼭 되야하는거라 ㅠㅠ 부탁드릴게요 ㅠㅠ

          Comment


            #6
            키넥트는 클라이언트에 연결되어 있고

            서버는 그 존재를 알지 못합니다.

            동기화할 때, 매개 변수로 키넥트 값을 같이 보내 주셔야 합니다.


            Code:
            exec function PlayerInput()
            {
                 int input = key.Code;
                 if (Role < Role_Authority)
                      SyncProcessInput(input);
                 ProcessInput(input);
            }
            
            server function SyncProcessInput(int syncCode)
            {
                 ProcessInput(syncCode);
            }
            
            function ProcessInput(int keyCode)
            {
                 // some do
            }

            Comment


              #7
              그럼 키넥트에서 받음 값들을 모두 계산한 뒤 bonerotation에 값을 넣는 pawn 함수 부분에서 rotation값을 동기화하여 넣어주면 되는건가요?? ㅠㅠ

              Comment


                #8
                연산을 어디까지 해서 보낼지는

                서버와 게임에 따라 다릅니다.


                많이 연산해서 보내줄 수록 서버의 부담은 줄어 들겠지만

                클라이언트를 변조하여 부정 행위를 할 가능성이 증가합니다.

                Comment


                  #9
                  계속 이렇게 질문드려서 너무너무 죄송해요 ㅠㅠ 말씀하신데로 서버 쪽에 동기화를 했는데 서버쪽에 값은 넘어가는데 다른 클라이언트 쪽에는 전혀 값이 넘어가질 않네요 ㅠㅠ

                  simulated function PlayerInput(float DeltaTime)
                  {
                  local rotator temp;
                  local int iter;
                  for (iter = 0; iter < niuiSkelControl.BoneControllers.Length; iter++)
                  {
                  temp=niuiSkelCOntrol.UpdateBoneOverides(DeltaTIme, self.Rotation, iter); // 키넥트에서 받은 값 연산해서 얻은 rotator 값이에요

                  if (Role < Role_Authority)
                  SyncProcessInput(DeltaTime,iter, temp);
                  UpdateSkeletalControls(DeltaTime,iter, temp);
                  }
                  }

                  reliable server function SyncProcessInput(float DeltaTime,int iter, Rotator temp)
                  {
                  niuiSkelControl.BoneControllers[iter].BoneRotation = temp;
                  UpdateSkeletalControls(DeltaTime,iter ,temp);

                  }

                  simulated function UpdateSkeletalControls(float DeltaTime, int iter, Rotator temp)
                  {
                  niuiSkelControl.BoneControllers[iter].BoneRotation = temp; // 뼈를 rotation하는 부분

                  }
                  위처럼 해서 실행해도 다른 클라이언트쪽에서는 전혀 움직임이 보이질 않네요 ㅠㅠ

                  이 부분이 정말정말 중요한부분이라 ㅠㅠㅠ 번번히 죄송해요 ㅠㅠ 부탁드릴게요 ㅠ

                  Comment


                    #10
                    서버 쪽에 값이 넘어간다면

                    그 이후는 엔진 몫입니다.


                    정상적으로 나와야 하며,

                    현재 의도하시려는 것과 오해가 있는 것인지 확인하겠습니다.


                    엔진의 기본 네트워크 모델은 서버-클라이언트 모델로,

                    각 클라이언트는 하나의 플레이어 컨트롤러와 하나의 폰을 각각 갖습니다.


                    서버는 이 컨트롤러와 폰의 사본을 가지고 있으며

                    클라이언트로부터 복제한 것이고,

                    (매 또는 몇)틱마다 다른 클라이언트에 다시 복제합니다.


                    즉, 여러 플레이어가 접속해 있다고 하면

                    그 서버에는 마찮가지로 여러 플레이어들 각각의 플레이어 컨트롤러와 폰의 사본이 있습니다.

                    만약 어떤 클라이언트가 동기화 데이터를 서버로 전송하면

                    그 클라이언트로부터 복제한 그 플레이어 컨트롤러 또는 폰에만 값이 반영됩니다.

                    그리고 그 업데이트는 엔진 및 네트워크 설정에 따라 현재 틱, 또는 다음 몇 틱 후에

                    다른 클라이언트로 복제, 전파됩니다.


                    만약 현재 작업하시려는 의도가,

                    하나의 클라이언트가 소유한 플레이어 컨트롤러, 또는 폰으로

                    모든 클라이언트의 플레이어 컨트롤러 또는 폰을 동기화하는 것이라면

                    서버의 네트워크 모델을 수정해야 합니다.


                    반면 기본 네트워크 모델이 맞다면

                    niui 등 다른 부분의 오류를 확인하십시오.

                    Comment


                      #11
                      계속 찾아보면서 해보다가 깨달은건데 이거 맞는지 확인 부탁드려요 ㅠ

                      아래 코드에서 PlyaerInput을 PlyerController에서 MyPawn.PlayerInput(DeltaTime); 이렇게 읽어야만 서버쪽에서 값을 가져가더라구요 처음에는 PlayerInput을 PAWN의 Tick()함수에 계속 호출하도록했는데 이렇게하니까 서버에서 전혀 못가져가더라구요 이건 왜 이런건가요? ㅜㅠ

                      그리고 다른 클라이언트쪽에서 bonerotation 되는 것이 전혀 안보이는 부분을 보다가 UpdateSkeletalControls(float DeltaTime, int iter, Rotator temp) 아래에서 이 함수를 호출해서 처음에 bonerotation을 할려고햇는데 이 함수를 호출하는 클라이언트에서 뼈는 계속 움직이지만 클라이언트쪽에서는 뼈가 전혀 움직이지 않는 걸 보니 이 함수에서 실행되는 niuiSkelControl.BoneControllers[iter].BoneRotation = temp; 이 부분이 Replication이 안되는게 아닌가 해서요 ㅠㅠ 계속 질문 드려서 죄송합니다 ㅠㅠ 정말정말 중요한 부분이구 이게 안되면 프로젝트가 진행이 안되서요 ㅠㅠ 부탁드릴게요!!


                      simulated function PlayerInput(float DeltaTime)
                      {
                      local rotator temp;
                      local int iter;
                      for (iter = 0; iter < niuiSkelControl.BoneControllers.Length; iter++)
                      {
                      temp=niuiSkelCOntrol.UpdateBoneOverides(DeltaTIme, self.Rotation, iter); // 키넥트에서 받은 값 연산해서 얻은 rotator 값이에요

                      if (Role < Role_Authority)
                      SyncProcessInput(DeltaTime,iter, temp);
                      UpdateSkeletalControls(DeltaTime,iter, temp);
                      }
                      }

                      reliable server function SyncProcessInput(float DeltaTime,int iter, Rotator temp)
                      {
                      niuiSkelControl.BoneControllers[iter].BoneRotation = temp;
                      UpdateSkeletalControls(DeltaTime,iter ,temp);

                      }

                      simulated function UpdateSkeletalControls(float DeltaTime, int iter, Rotator temp)
                      {
                      niuiSkelControl.BoneControllers[iter].BoneRotation = temp; // 뼈를 rotation하는 부분

                      }

                      Comment


                        #12
                        http://udn.epicgames.com/Three/Funct...icationKR.html
                        http://udn.epicgames.com/Three/Repli...levancyKR.html

                        네트워크에 관한 기초 정보들을 숙지하십시오.

                        Comment


                          #13
                          계속 질문드리네요 ㅠㅠ 그 부분 여러번 숙지후 다시 한번 쭉 살펴보면서 생각해봤는데 지금 NIUI_SkeletalController이라는 Actor를 만들어서 여기서 SkelSingleBoneControl을 정의해서 Pawn에서는 여기 있는 SkelControlSingleBone을 Rotation하는 방법으로 움직이고 있습니다.

                          reliable server function SyncProcessInput(float DeltaTime,int iter, Rotator temp) 이 코드의 경우 server에서 실행하라는 뜻이고 혹시

                          if (Role < Role_Authority)
                          SyncProcessInput(DeltaTime,iter, temp);
                          else if(Role == Role_Authority)
                          SyncProcessInput(DeltaTime,iter, temp); // 여긴 클라이언트가 실행하도록

                          이렇게 하여 서버와 클라이언트가 따로 실행하도록 하면 되는건가요??

                          값이 서버로 넘어가서 뿌려지는 변수부분은 해결이 된거같은데 클라이언트 쪽에서 Bone이 움직이면서 Pawn이 Replication 되는 부분이 전혀 안되네요 ㅠㅠ

                          귀찮으시겠지만 답변 꼭 부탁드릴게요 ㅠ

                          Comment


                            #14
                            서버 측에서 아래와 같이 로깅을 실시하십시오.

                            Code:
                            int CachedIter;
                            Rotator CachedTemp;
                            
                            simulated function UpdateSkeletalControls(float DeltaTime, int iter, Rotator temp)
                            {
                                  CachedIter = iter;
                                  CachedTemp = temp;
                                  niuiSkelControl.BoneControllers[iter].BoneRotation = temp; // 뼈를 rotation하는 부분
                            }
                            
                            defaultproperties
                            {
                                 CachedIter = -1;
                                 CachedTemp = (Roll=0, Yaw=0, Pitch=0);
                            }
                            
                            
                            event Actor.Tick(float DeltaTime)
                            {
                                 local MyPlayerController c;
                                 super.Tick(DeltaTime);
                                 foreach WorldInfo.AllControllers(class'MyPlayerController', c)
                                 {
                                       `log("Controller : " $ c $ " = Received Values = CachedIter : " $ c.CachedIter $ " CachedTemp : " $ c.CachedTemp);
                                 }
                            }

                            모두 기본값이면 전송 과정이 잘못된 것입니다.


                            다른 값을 갖는 컨트롤러가 있으면

                            네트워크는 제대로 작동하고 있는 것이며

                            다른 곳의 문제를 확인하십시오.


                            이제 더 이상은 답변해드릴만한 내용이 없습니다.

                            아무쪼록 잘 해결하시길 바랍니다.

                            Comment


                              #15
                              정말정말죄송해요 ㅠㅠ 제가 혹시 한가지 놓치고있는게 아닌지 여쩌봐요 ㅠㅠ 그럼 키넥트에서 연산한 값을 playercontroller에서 받아서 그 받은 값을 서버와 동기화 해준 다음에 pawn의 로테이션을 해주는 순서로 가야만 pawn이 replication이 되서 움직이는 건가에 대한거만 확인 부탁드려요 ㅠ
                              지금까지는 pawn안에서만 코드를 처리했거든요 ㅠㅠ 부탁드릴게요 ㅠㅠ

                              Comment

                              Working...
                              X