Unity PUN插件多人在线同步角色坐标旋转角度和动作
用PUN插件的话,就在OnJoinedRoom()回调函数里,表示加入房间,可以实例化角色,GameObject go=PhotonNetwork.Instantiate(prefabPlayer.name, new Vector3(241,0.2f,253), Quaternion.identity, 0);这里的prefabPlayer需要放在Resources文件夹里。
prefabPlayer上加上一个PhotonView组件,
为了同步在角色坐标,这里需要一个回调函数, void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info);在调用这个函数之前,需要做一点准备工作,因为这个函数我是写在PlayerPesonNetWork这个脚本里,所以需要把这脚本拖在PhotonView的Observed Components下,这样你就能在PlayerPesonNetWork脚本里的 void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info);去写一些同步的信息。
这里我把PlayerPesonNetWork脚本粘出来:
using UnityEngine; using System.Collections; using Newtonsoft.Json; public class PlayerPesonNetWork : Photon.MonoBehaviour { GirlSniper girlSniper; public static PlayerPesonNetWork PPNW; void Awake() { girlSniper = GetComponent<GirlSniper>(); if (photonView.isMine) { girlSniper.isControl = true; GameObject.Find("GameObjectMainCamera").GetComponent<MouseRotation>().target = gameObject.transform; } else { girlSniper.isControl = false; } gameObject.name = gameObject.name + photonView.viewID; PPNW = this; } void Start() { } void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) { if (stream.isWriting) { //动作状态根据需求写的 //将自己的动作状态 坐标 旋转角度传出 stream.SendNext( JsonConvert.SerializeObject(girlSniper.animatorState_D)); stream.SendNext(transform.position); stream.SendNext(transform.rotation); } else { //获取动作状态 坐标 旋转角度 girlSniper.animatorState_D = JsonConvert.DeserializeObject <AnimatorState_D>((string)stream.ReceiveNext()); correctPlayerPos = (Vector3)stream.ReceiveNext(); correctPlayerRot = (Quaternion)stream.ReceiveNext(); } } private Vector3 correctPlayerPos = Vector3.zero; //We lerp towards this private Quaternion correctPlayerRot = Quaternion.identity; //We lerp towards this // Update is called once per frame void Update () { if (!photonView.isMine) { transform.position = Vector3.Lerp(transform.position, correctPlayerPos, Time.deltaTime * 5); transform.rotation = Quaternion.Lerp(transform.rotation, correctPlayerRot, Time.deltaTime * 5); } } }
同时我再把自己写的控制角色脚本也粘出来,这脚本也是绑在prefabPlayer上的:
using UnityEngine; using System.Collections; public class GirlSniper : MonoBehaviour { public Animator animator; private Camera cam; private UISprite spriteX; public bool isControl = true; public AnimatorState_D animatorState_D; private float playerSpeed = 2.0f; private GameObject goCameraParent; // public GameObject goShootAnimation;//开枪特效 // Use this for initialization void Start () { goCameraParent = GameObject.Find("GameObjectMainCamera").gameObject; animator = GetComponent<Animator>(); cam = Camera.main; spriteX = GameObject.Find("UI Root").transform.FindChild("Camera").FindChild("X").GetComponent<UISprite>(); animatorState_D = new AnimatorState_D(); } // Update is called once per frame void Update () { if (animator) { if (!isControl) { enumUpdate(); } else { isControlUpdate(); } } } //控制更新 void isControlUpdate() { float fVertical = Input.GetAxis("Vertical"); float fHorizontal = Input.GetAxis("Horizontal"); //当前的动画状态 参数0表示当前层级为0 AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0); if (stateInfo.IsName("Base Layer.moveForward")) { if (Input.GetKeyDown(KeyCode.Space)) { animator.SetBool("jump", true); animatorState_D.jump = true; transform.Translate(Vector3.forward * 2); } else if (Input.GetKeyUp(KeyCode.Space)) { animator.SetBool("jump", false); animatorState_D.jump = false; } } if (stateInfo.IsName("Base Layer.idle")) { animator.SetBool("jump", Input.GetKeyDown(KeyCode.Space)); animator.SetBool("happy", Input.GetKeyDown(KeyCode.H)); animator.SetBool("sad", Input.GetKeyDown(KeyCode.U)); animatorState_D.jump=Input.GetKeyDown(KeyCode.Space); animatorState_D.happy=Input.GetKeyDown(KeyCode.H); animatorState_D.sad = Input.GetKeyDown(KeyCode.U); } if (stateInfo.IsName("Base Layer.idle_look")) { animator.SetBool("jump", Input.GetKeyDown(KeyCode.Space)); animator.SetBool("happy", Input.GetKeyDown(KeyCode.H)); animator.SetBool("sad", Input.GetKeyDown(KeyCode.U)); animatorState_D.jump = Input.GetKeyDown(KeyCode.Space); animatorState_D.happy = Input.GetKeyDown(KeyCode.H); animatorState_D.sad = Input.GetKeyDown(KeyCode.U); } if (Input.GetMouseButtonDown(0)) { transform.localEulerAngles = new Vector3(transform.localEulerAngles.x, goCameraParent.transform.localEulerAngles.y, transform.localEulerAngles.z); animator.SetBool("shoot", true); Camera.main.GetComponent<Animator>().SetBool("shutDown",true); Ray ray01 = cam.ViewportPointToRay(new Vector3(0.45f, 0.65f, 0.0f)); RaycastHit hit; if (Physics.Raycast(ray01, out hit)) { if (hit.transform.tag == "Player") { spriteX.color = Color.yellow; PlayerPesonNetWork.PPNW.SendDieMessage(hit.transform.name, PhotonTargets.All); } else { spriteX.color = Color.white; } } } else if (Input.GetMouseButtonUp(0)) { animator.SetBool("shoot", false); spriteX.color = Color.white; Camera.main.GetComponent<Animator>().SetBool("shutDown", false); } if (Mathf.Abs(fHorizontal) > 0.1f || Mathf.Abs(fVertical) > 0.1f) { animator.SetBool("shiftForward", true); animatorState_D.shiftForward = true; } if (Mathf.Abs(fHorizontal) <= 0.1f && Mathf.Abs(fVertical) <= 0.1f) { animator.SetBool("shiftForward", false); animatorState_D.shiftForward = false; } if (Input.GetAxis("Vertical") > 0.1f && animator.GetBool("shoot") == false) { transform.localEulerAngles = new Vector3(transform.localEulerAngles.x, goCameraParent.transform.localEulerAngles.y, transform.localEulerAngles.z); transform.Translate(Vector3.forward * Time.deltaTime * playerSpeed); } if (Input.GetAxis("Vertical") < -0.1f && animator.GetBool("shoot") == false) { transform.localEulerAngles = new Vector3(transform.localEulerAngles.x, goCameraParent.transform.localEulerAngles.y + 180, transform.localEulerAngles.z); transform.Translate(Vector3.forward * Time.deltaTime * playerSpeed); } if (Input.GetAxis("Horizontal") > 0.1f && animator.GetBool("shoot") == false) { transform.localEulerAngles = new Vector3(transform.localEulerAngles.x, goCameraParent.transform.localEulerAngles.y + 90, transform.localEulerAngles.z); transform.Translate(Vector3.forward * Time.deltaTime * playerSpeed); } if (Input.GetAxis("Horizontal") < -0.1f && animator.GetBool("shoot") == false) { transform.localEulerAngles = new Vector3(transform.localEulerAngles.x, goCameraParent.transform.localEulerAngles.y + 270, transform.localEulerAngles.z); transform.Translate(Vector3.forward * Time.deltaTime * playerSpeed); } } //枚举更新 void enumUpdate() { animator.SetBool("jump",animatorState_D.jump); animator.SetBool("shiftForward", animatorState_D.shiftForward); animator.SetBool("happy", animatorState_D.happy); animator.SetBool("sad", animatorState_D.sad); animator.SetBool("shoot", animatorState_D.shoot); animator.SetBool("die",animatorState_D.die); } } public class AnimatorState_D { public bool jump = false; public bool shiftForward = false; public bool happy = false; public bool sad = false; public bool shoot = false; public bool die = false; }