관리 메뉴

caLAB

[유니티 VR + 네트워크] 캐릭터 리깅 네트워크 동기화 본문

Unity/유니티VR

[유니티 VR + 네트워크] 캐릭터 리깅 네트워크 동기화

도이(doi) 2021. 11. 18. 10:52
728x90

이전 포스팅에서 VR 디바이스에 캐릭터를 리깅하는 것을 포스팅 하였습니다.

오늘 포스팅에서는 리깅된 캐릭터가 포톤 네트워크 상에서도 동일하게 리깅 되어서

움직이도록 네트워크 작업을 하는 방법에 대해서 정리해보도록 하겠습니다.

 

우선 포톤네트워크 관련 기본적인 설정이 전부 되어있다고 가정하고 설명하도록 하겠습니다.

포톤 서버 및 룸 접속까지 완성이 된 상태라 가정합니다.

 

그렇다면 제일 먼저 NetworkSpawned 스크립트를 만들어서 Network 플레이어를 생성하는 것과 관련된 스크립트를 작성합니다. 방에 입장하였을 때 Network Player를 Instantiate하고, 방에 나갈 때 Instantiate 되어 있던 Network Player를 삭제합니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;

namespace sync
{
    public class networkMgr : MonoBehaviourPunCallbacks
    {
        private GameObject spawnedPlayerPrefab;

        private void Awake()
        {
            PhotonNetwork.ConnectUsingSettings();
        }

        public override void OnConnectedToMaster()
        {
            base.OnConnectedToMaster();
            PhotonNetwork.JoinOrCreateRoom("room", new RoomOptions { MaxPlayers = 6 }, null);
        }

        public override void OnJoinedRoom()
        {
            base.OnJoinedRoom();
            //PhotonNetwork.Instantiate("PCplayerNetwork", Vector3.zero, Quaternion.identity);
            spawnedPlayerPrefab = PhotonNetwork.Instantiate("VRplayerNetwork", transform.position, transform.rotation);
        }

        public override void OnLeftRoom()
        {
            base.OnLeftRoom();
            PhotonNetwork.Destroy(spawnedPlayerPrefab);
        }
    }
}

동기화를 위해서는 우선 Network Player에 Photon View 컴포넌트를 추가해줍니다. Photon View의 역할은 동기화할 것들은 관찰해서 동기화 시켜주는 역할을 한다고 생각하면 됩니다.

그 후에 VR device장비에 rig되어 있던 부분들의 Transform을 체크할 수 있도록 Photon Transform View를 머리, 왼쪽, 오른쪽 컨트롤러에 추가해줍니다. 또한, 현재 위치를 추적하기 위해서 캐릭터에도 Photon Transform View를 추가해줍니다. * 캐릭터 spawned를 위해서 Project 윈도우에 'Resources' 폴더를 만들어서 prefab으로 Network Player를 만들어서 넣어줍니다.

위 작업이 모두 끝난 후에는 Network Player스크립트를 작성하여 spawned 될 Network Player에 스크립트를 추가해줍니다. *스크립트의 위치는 VR Rig를 해준 위치와 동일하게 해주어야 됩니다. 그렇지 않을 경우 위치가 꼬이는 현상이 발생하였습니다. 현재 VRnetwork Player Rig스크립트가 동기화 + 리깅을 해주는 스크립트 입니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine.XR.Interaction.Toolkit;

[System.Serializable]
public class VRMap
{
    public Transform vrTarget;
    public Transform rigTarget;
    public Vector3 trackingPositionOffset;
    public Vector3 trackingRotationOffset;

    public void Map()
    {
        rigTarget.position = vrTarget.TransformPoint(trackingPositionOffset);
        rigTarget.rotation = vrTarget.rotation * Quaternion.Euler(trackingRotationOffset);
    }
}

public class VRnetworkPlayerRig : MonoBehaviourPunCallbacks
{
    private Transform headRig;
    private Transform leftHandRig;
    private Transform rightHandRig;

    public VRMap head;
    public VRMap leftHand;
    public VRMap rightHand;

    public PhotonView PV;
    public GameObject vrPlayer;
    public Transform headConstraint;
    public Vector3 headBodyOffset;
    public float turnSmoothness = 3f;

    private void Start()
    {
        headBodyOffset = transform.position - headConstraint.position;
        XRRig rig = FindObjectOfType<XRRig>();

        head.vrTarget = GameObject.Find("VRplayer").transform.Find("Camera Offset/Main Camera");
        leftHand.vrTarget = GameObject.Find("VRplayer").transform.Find("Camera Offset/LeftHand Controller");
        rightHand.vrTarget = GameObject.Find("VRplayer").transform.Find("Camera Offset/RightHand Controller");
    }

    private void Update()
    {
        if (PV.IsMine)
        {
            vrPlayer.SetActive(false);

            transform.position = headConstraint.position + headBodyOffset;
            transform.forward = Vector3.Lerp(transform.forward,
            Vector3.ProjectOnPlane(headConstraint.up, Vector3.up).normalized, Time.deltaTime * turnSmoothness);

            head.Map();
            leftHand.Map();
            rightHand.Map();
        }
    }
}

스크립트에 대한 설명을 간략하게 하자면 현재 Network Player는 prefab으로 존재하기 때문에 VR Target을 run time에 동적으로 연결해주어야 합니다. 따라서, VR Target부분은 Network Player가 생성된 이후에 start 함수에서 동적으로 VR Player 하위에 있는 head(Main Camera), LeftHand Controller, RightHand Controller에 연결합니다. 나머지 부분은 VR Rig과 동일합니다. 

 

위와 같은 작업이 끝나면 rig된 VR 플레이어 캐릭터가 다른 유저에게도 보이게 됩니다. 

 

728x90
반응형
Comments