VioletaBabel

61. Photon Tutorial (7) 본문

BCA/8. Photon
61. Photon Tutorial (7)
Beabletoet 2018. 8. 6. 16:16

My Robot Kyle에 PhotonView.cs를 붙여준다.

Observe option을 unreliable On Change로 한다.


--Observe option

Off : RPC 전용일 때 유용

Unreliable : 업데이트가 있는 그대로 전송되나 손실될 수 있음. 위치 등 잘 변하지 않는 데이터에는 최적이나, 무기를 바꾸는 등의 트리거에는 적합하지 않음. 게임 오브젝트의 위치를 동기화하는 경우에는 게임 오브젝트가 이동하지 않아도 항상 업데이트를 전송하니 주의해야 함.

Unreliable on Change : 업데이트 때마다 변경된 것을 확인함. 값이 바뀌면 전송하고, 값이 바뀌지 않으면 전송을 중지함.

Reliable Delta Compressed : 갱신된 값을 이전과 비교. 변경되지 않은 값은 생략하고, 수신 측에서 단순히 이전의 값을 교체.





Transform을 동기화하자.

동기화 할 My Robot Kyle 오브젝트에 PhotonTransformView를 컴포넌트로 불러온 후, Photon View의 Observed Components에 넣은 컴포넌트를 드래그해 넣는다.

PhotonTransformView에서 Synchronize Position, Synchronize Rotation을 체크한다.

그리고 Synchronize Position의 Interpolate Option을 Lerp로 바꾸고, Lerp Speed로 10을 준다.





이번엔 애니메이션을 동기화하자.

My Robot Kyle에 PhotonAnimatorView를 컴포넌트로 추가한다.

이것도 Photon View의 Observed Components를 +해서 넣는다.

그 뒤 Synchronize Parameters에서 Speed, Direction, Jump를 Discrete, Hi를 Disabled로 한다. (disable을 하면 사용되지 않으니 대역폭을 절약한다.)

Discrete는 OnPhotonSerializeView에서 초당 10번 값이 전송된다. 값이 부드러운 전환을 유지하며 순서대로 적용된다.

Continuous는 매 프레임마다 전송된다.





사용자의 입력을 관리하기 위해 PlayerAnimatorManager.cs 를 연다.


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
//PlayerAnimatorManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class PlayerAnimatorManager : Photon.MonoBehaviour
{
    public float DirectionDampTime = 0.25f;
    private Animator animator;
    // Use this for initialization
    void Start()
    {
        animator = GetComponent<Animator>();
        if (!animator)
            Debug.LogError("PlayerAnimatorManager is Missing Animator Component"this);
    }
 
    // Update is called once per frame
    void Update()
    {
        if (!photonView.isMine && PhotonNetwork.connected)//connected를 넣는 이유는 개발 단계에서 프리팹을 테스트하기 위함.
            return;                                     //나중에는 후자는 지워도 되는 것으로 보임
        if (!animator)
            return;
        AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0); // 현재 수행중인 animator의 state를 가져옴.
        if (stateInfo.IsName("Base Layer.Run"))
            if (Input.GetButtonDown("Fire2"))
                animator.SetTrigger("Jump");
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        if (v < 0)
            v = 0;
        animator.SetFloat("Speed", h * h + v * v);
        animator.SetFloat("Direction", h, DirectionDampTime, Time.deltaTime);
    }
}
 
cs






카메라를 제어하자.

CameraWork 컴포넌트를 제어하기 위해 PlayerManager.cs를 변경한다.


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
//PlayerManager.cs
using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
public class PlayerManager : Photon.PunBehaviour
{
    public GameObject Beams;
    public float Health = 1f;
    bool IsFiring;
    private void Awake()
    {
        if (Beams == null)
            Debug.LogError("<Color=Red><a>Missing</a><Color> Beams Reference."this);
        else
            Beams.SetActive(false);
    }
    private void Start()
    {
        CameraWork _cameraWork = this.gameObject.GetComponent<CameraWork>();
        if (_cameraWork != null)
        {
            if (photonView.isMine)//이것이 내꺼냐?
                _cameraWork.OnStartFollowing();//그럼 얘만 따라다니자
        }
        else
            Debug.LogError("<Color=Red><a>Missing</a></Color> CameraWork Component on playerPrefab."this);
    }
    private void Update()
    {
        ProcessInputs();
        if (Health <= 0f)
            GameManager.instance.LeaveRoom(); // 체력이 0이 되면 게임 오버
        if (Beams != null && IsFiring != Beams.GetActive())
            Beams.SetActive(IsFiring);
    }
 
    void ProcessInputs()
    {
        if (Input.GetButtonDown("Fire1"))
            if (!IsFiring)
                IsFiring = true;
        if (Input.GetButtonUp("Fire1"))
            if (IsFiring)
                IsFiring = false;
    }
 
    private void OnTriggerEnter(Collider other)
    {
        if (!photonView.isMine)//자기 거인지 확인
            return;
        if (!other.CompareTag("Beam"))
            return;
        Health -= 0.1f;
    }
 
    private void OnTriggerStay(Collider other)
    {
        if (!photonView.isMine)
            return;
        if (!other.CompareTag("Beam"))
            return;
        Health -= 0.1f * Time.deltaTime;
    }
}
 
cs





여기에 광선 제어도 추가해보자.

또 다시 PlayerManager.cs를 수정한다.


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
//PlayerManager.cs
using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
public class PlayerManager : Photon.PunBehaviour, IPunObservable
{
    public GameObject Beams;
    public float Health = 1f;
    bool IsFiring;
    private void Awake()
    {
        if (Beams == null)
            Debug.LogError("<Color=Red><a>Missing</a><Color> Beams Reference."this);
        else
            Beams.SetActive(false);
    }
    private void Start()
    {
        CameraWork _cameraWork = this.gameObject.GetComponent<CameraWork>();
        if (_cameraWork != null)
        {
            if (photonView.isMine)//이것이 내꺼냐?
                _cameraWork.OnStartFollowing();//그럼 얘만 따라다니자
        }
        else
            Debug.LogError("<Color=Red><a>Missing</a></Color> CameraWork Component on playerPrefab."this);
    }
    private void Update()
    {
        if (photonView.isMine) // 얘도 플레이어 자기 캐릭만 동작해야하니까 랩핑함.
            ProcessInputs();
        if (Health <= 0f)
            GameManager.instance.LeaveRoom(); // 체력이 0이 되면 게임 오버
        if (Beams != null && IsFiring != Beams.GetActive())
            Beams.SetActive(IsFiring);
    }
 
    void ProcessInputs()
    {
        if (Input.GetButtonDown("Fire1"))
            if (!IsFiring)
                IsFiring = true;
        if (Input.GetButtonUp("Fire1"))
            if (IsFiring)
                IsFiring = false;
    }
 
    private void OnTriggerEnter(Collider other)
    {
        if (!photonView.isMine)//자기 거인지 확인
            return;
        if (!other.CompareTag("Beam"))
            return;
        Health -= 0.1f;
    }
 
    private void OnTriggerStay(Collider other)
    {
        if (!photonView.isMine)
            return;
        if (!other.CompareTag("Beam"))
            return;
        Health -= 0.1f * Time.deltaTime;
    }
 
    void IPunObservable.OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {   //메소드 안에서 stream 변수를 전달하였다. 네트워크를 타고 전송되며 이 호출로 데이터를 읽고 쓴다.
        //photonView.isMine이 true일 때 write, 아닐 때 read된다.
        if (stream.isWriting)//write일 때
            stream.SendNext(IsFiring);//data Stream에 추가
        else//read일 때
            this.IsFiring = (bool)stream.ReceiveNext();
    }
}
 
cs


OnPhotonSerializeView는 초당 여러번 호출되며 PhotonView의 동기화 데이터를 읽고 쓴다.


'BCA > 8. Photon' 카테고리의 다른 글

63. Photon Tutorial (9)  (0) 2018.08.07
62. Photon Tutorial (8)  (0) 2018.08.07
60. Photon Tutorial (6)  (0) 2018.08.06
59. Photon Tutorial (5)  (0) 2018.08.06
58. Photon Tutorial (4)  (0) 2018.08.06
Comments