1. 플레이어 닉네임 가져오기 

2. DeadReckoning 

3. 채팅창 만들기


1.플레이어 닉네임 가져오기 

1-1. 충돌체에 actornumber를 public 변수로 부여 

나는 cannon이라는 충돌체 script에 public actornumber = -1;이라고 입력해두었다.


1-2. 플레이어 닉네임 가져오는 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class userName : MonoBehaviourPunCallbacks, IPunObservable {
 
    public TextMeshProUGUI nickName;
 
    void Start () {
        //입력해서 저장된 userid지우는 코드 
        PlayerPrefs.DeleteAll();

  //플레이어의 닉네임을 가져오는
        nickName.text = photonView.Owner.NickName;
    }
 
 
    //원격지의 플레이어 nickname을 가져오는 
    string GetNickNameByActorNumber(int actorNumber)
    {
        foreach (Player player in PhotonNetwork.PlayerListOthers)
        {
            if (player.ActorNumber == actorNumber)
            {
                return player.NickName;
            }
        }
        return "Ghost";
    }
 
}
 
cs


1-3. 텍스트가 들어있는 게임오브젝트를 생성된 스크립트의 nickName 칸에 넣기


2. DeadReckoning (위치 동기화를 위한 추측항법 사용)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public class deadReckoning : MonoBehaviourPunCallbacks, IPunObservable {
  
    void Update () {
        //photonView.isMine 내 탱크는 내가 움직인다 
        if(photonView.IsMine && !isDie)
        {
            v = Input.GetAxis("Vertical");
            h = Input.GetAxis("Horizontal");
 
            tr.Translate(Vector3.forward * Time.deltaTime * v * speed);
            tr.Rotate(Vector3.up * Time.deltaTime * h * rotSpeed);
        }
        //내 게임에 접속한 다른 유저들의 움직임을 보정 
        else
        {
            //끊어지는 시간이 너무 길 때는 끊어준다 
            if((tr.position - currPos).sqrMagnitude >= 10.0f * 10.0f)
            {
                tr.position = currPos;
                tr.rotation = currRot;
            }
            else //끊어지는 시간이 적절할 때는 선형보간으로 끊어지지 않도록
            {
                tr.position = Vector3.Lerp(tr.position, currPos, Time.deltaTime * 10.0f);
                tr.rotation = Quaternion.Slerp(tr.rotation, currRot, Time.deltaTime * 10.0f);
            }
 
        }
 
    }
 
    private Vector3 currPos;
    private Quaternion currRot;
 
    public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
        //네트워크에 자신의 자료를 보냄 
        if(stream.IsWriting)
        {
            stream.SendNext(tr.position);
            stream.SendNext(tr.rotation);
        }
        //동기화된 자료를 받음 
        else
        {
            currPos = (Vector3) stream.ReceiveNext();
            currRot = (Quaternion) stream.ReceiveNext();
        }
    }
}
 
cs



3. 채팅창 만들기 

3-1. canvas생성하기(아래와 같이 생성하기)



3-2. 빈 게임오브젝트 생성 후 이름을 GameManager로 변경 후 GameManager 스크립트를 생성한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine.UI;
 
public class GameManager : MonoBehaviourPunCallbacks {
 
    public Text msgList;
    public InputField ifSendMsg;
 
    public void OnSendChatMsg()
    {
        string msg = string.Format("[{0}] {1}"
                                   , PhotonNetwork.LocalPlayer.NickName
                                   , ifSendMsg.text);
        photonView.RPC("ReceiveMsg", RpcTarget.OthersBuffered, msg); //buffer는 적재되어있던 것을 한 번에 가져옴
        ReceiveMsg(msg);
    }
 
    [PunRPC]
    void ReceiveMsg(string msg)
    {
        msgList.text += "\n" + msg;
    }
}
 
cs


3-3. InputField 게임오브젝트에 OnEndEdit에 GameManager 추가하기 GameManager.OnSendMsg() 함수 선택하기


3-4. 생성한 GameManager 게임 오브젝트에 txt 연결하기


4. 로비 생성하기 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

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

public class PhotonInit : MonoBehaviourPunCallbacks
{
    public enum ActivePanel
    {
        LOGIN = 0,
        ROOMS = 1
    }

    public ActivePanel activePanel = ActivePanel.LOGIN;

    private string gameVersion = "1.0";
    public string userId = "cuttySexy";
    public byte maxPlayer = 20;

    public TMP_InputField txtUserId;
    public TMP_InputField txtRoomName;

    public GameObject[] panels;

    private void Awake()
    {
        //같은 룸에 들어온 모든 유저들의 씬을 동기화 
        PhotonNetwork.AutomaticallySyncScene = true;
    }

    //아이디를 저장하는 (초기에는 랜덤한 유저 이름이 들어간다)
    void Start()
    {
        txtUserId.text = PlayerPrefs.GetString("USER_ID", "User_" + Random.Range(1, 999));
        txtRoomName.text = PlayerPrefs.GetString("ROOM_NAME", "ROOM" + Random.Range(1, 999));
    }
 #region SELF_CALLBACK_FUNCTION
    public void OnLogin()
    {
        PhotonNetwork.GameVersion = this.gameVersion;
        PhotonNetwork.NickName = txtUserId.text;

        PhotonNetwork.ConnectUsingSettings();

        PlayerPrefs.SetString("USER_ID", PhotonNetwork.NickName);
        ChangePanel(ActivePanel.ROOMS);
    }

    public void OnCreateRoomClick()
    {
        PhotonNetwork.CreateRoom(txtRoomName.text
                                 , new RoomOptions { MaxPlayers = this.maxPlayer });
    }

    public void OnJoinRandomRoomClick()
    {
        PhotonNetwork.JoinRandomRoom();
    }
 #endregion
    //패널 바꾸기 
    private void ChangePanel(ActivePanel panel)
    {
        foreach (GameObject _panel in panels)
        {
            _panel.SetActive(false);
        }

        panels[(int)panel].SetActive(true);
    }

 #region PHOTON_CALLBACK_FUNCTIONS
    //랜덤룸 입장에 실패하면 룸 생성하기
    public override void OnJoinRandomFailed(short returnCode, string message)
    {
        Debug.Log("fail");
        PhotonNetwork.CreateRoom(null
                                 , new RoomOptions { MaxPlayers = this.maxPlayer });
    }
    //룸에 들어가기 
    public override void OnJoinedRoom()
    {
        Debug.Log("join room");
        PhotonNetwork.IsMessageQueueRunning = false;
        SceneManager.LoadScene("Level01");
    }
#endregion
}

#region의 기능은 참조형이다. 부분을 접었다 폈다 폴딩할 수 있다. 

끝은 항상 #endregion으로 끝맞추어야 한다. 


Posted by 도이(doi)
,