using UnityEngine;

using System.Collections;

using UnityStandardAssets.Utility; 


public class PlayerCtrl : MonoBehaviour {

private Transform tr;

private NetworkView _networkView;


private Vector3 currPos=Vector3.zero;

private Quaternion currRot=Quaternion.identity;


public GameObject bullet;

public Transform firePos;

public enum AnimState{

idle=0,

runFoward,

runBackward,

runRight,

runLeft

}

public AnimState animState=AnimState.idle;

public AnimationClip[] animClips;


private CharacterController _controller;

private Animation _animation;


void Awake(){

tr = GetComponent<Transform> ();

_networkView = GetComponent<NetworkView> ();

_controller = GetComponent<CharacterController> ();

_animation = GetComponentInChildren<Animation> ();


if (_networkView.isMine) {

Camera.main.GetComponent<SmoothFollow>().target=tr;

}

}

// Use this for initialization

void Start () {

}

// Update is called once per frame

void Update () {

if (_networkView.isMine) {

if (Input.GetMouseButtonDown (0)) {

Fire ();

_networkView.RPC ("Fire", RPCMode.Others);

}


Vector3 localVelocity = tr.InverseTransformDirection (_controller.velocity);

Vector3 forwardDir = new Vector3 (0f, 0f, localVelocity.z);

Vector3 rightDir = new Vector3 (localVelocity.x, 0f, 0f);


if (forwardDir.z >= 0.1f) {

animState = AnimState.runFoward;

} else if (forwardDir.z <= -1.0f) {

animState = AnimState.runBackward;

} else if (rightDir.x >= 0.1f) {

animState = AnimState.runRight;

} else if (rightDir.x <= -0.1f) {

animState = AnimState.runLeft;

} else {

animState = AnimState.idle;

}

_animation.CrossFade (animClips [(int)animState].name, 0.2f);


} else {

tr.position = Vector3.Lerp (tr.position, currPos, Time.deltaTime * 10.0f);

tr.rotation = Quaternion.Slerp (tr.rotation, currRot, Time.deltaTime * 10.0f);

}

}

[RPC]

void Fire(){

StartCoroutine (this.CreateBullet ());

}

IEnumerator CreateBullet(){

GameObject.Instantiate (bullet, firePos.position, firePos.rotation);

yield return null;

}


void OnSerializeNetworkView(BitStream stream,NetworkMessageInfo info){

if (stream.isWriting) {

Vector3 pos = tr.position;

Quaternion rot = tr.rotation;

int _animState=(int)animState;


stream.Serialize (ref pos);

stream.Serialize (ref rot);

stream.Serialize (ref _animState);

} else {

Vector3 revPos = Vector3.zero;

Quaternion revRot = Quaternion.identity;

int _animState=0;


stream.Serialize (ref revPos);

stream.Serialize (ref revRot);

stream.Serialize (ref _animState);


currPos = revPos;

currRot = revRot;

animState=(AnimState)_animState;

}

}

}


케릭터가 A,B가 있으면 서로 데이터를 송수신해서 움직이는걸 볼수있는 소스인데요
OnSerializeNetworkView 이 함수는 케릭터가 얼마나 움직였는지 송수신하는 부분이고 그 값을 currPos, currRot에 저장합니다 
currPos는 위치값  currRot는 각도입니다.

그리고나서
update문에서 

if (_networkView.isMine) {


} else {

tr.position = Vector3.Lerp (tr.position, currPos, Time.deltaTime * 10.0f);

tr.rotation = Quaternion.Slerp (tr.rotation, currRot, Time.deltaTime * 10.0f);

}


여기서 else문이 원격플레이어일때 실행됩니다. 즉 내가 A라고 가정하면 B일때 실행되는 부분이죠

그리고 tr.positon과 tr.rotation에 움직임과 각도의 값을 넣어주는데

여기서 이해가안갑니다


왜 tr.positon과 tr.rotation에 값을 넣어주는지


플레이어가 A와 B가 있다고 치면

A가 보는 화면에는 자신과 B가 있고
B가 보는 화면에는 자신과 A가 있습니다.
A가 움직였을때 A의 Transform 값을 B에게 보내고
B는 그 값을 수신합니다.
그럼 B 화면에서는 수신한 값만큼 자신이 아니라 A를 움직여 줘야하는데
그걸 update함수안에있는 else에서 수행을 합니다.
else 문에서 이동한 값과 각도를 tr.position, tr.rotation에 넣어줍니다.
그럼 움직이게되는데
이부분을 모르겠네요
왜 tr.position과 tr.rotation에 A가 움직인 값을 넣어주는지..
tr.position과 tr.rotation은 B를 움직이게 하는 것인데

제 생각엔 저렇게 tr.position과 tr.rotation에 A가 움직인 값을 넣어주면
B화면상에서 A가 움직이는게 아니라 B가 수신한 값만큼 움직여야된다고 생각하는데
도대체 왜 A가 움직이는거죠?



답변좀 부탁드립니다 ㅜ