星际之旅 2019-06-27
视频地址
GITHUB地址
第一步是在项目中创建 NetworkManager 对象:
将场记挂载到网络空对象上创建游戏场景:
public class FirstSceneController : MonoBehaviour { // Use this for initialization void Start () { Instantiate(Resources.Load<GameObject>("Prefabs/Plane"), new Vector3(0, -0.5f, 0), Quaternion.identity); } // Update is called once per frame void Update() { } }
设置玩家对象预制
联网玩家对象的运动
![注册玩家预制](https://pmlpml.github.io/unity3d-learning/images/ch13/UNetTut5.png) * 编写 PlayerMove 脚本,使玩家的移动被联网同步: ```cs using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Networking; public class PlayerMove : NetworkBehaviour { public GameObject bulletPrefab; private Camera myCamera; public override void OnStartLocalPlayer() { GetComponent<MeshRenderer>().material.color = Color.red; GetComponent<Rigidbody>().freezeRotation = true; myCamera = Camera.main; } void Update() { if (!isLocalPlayer) return; var x = Input.GetAxis("Horizontal"); var z = Input.GetAxis("Vertical") * 0.1f; //移动和旋转 transform.Translate(0, 0, z * 0.7f); transform.Rotate(0, x, 0); myCamera.transform.position = transform.position + transform.forward * -3 + new Vector3(0, 4, 0); myCamera.transform.forward = transform.forward + new Vector3(0, -0.5f, 0); if (Input.GetKeyDown(KeyCode.Space)) { CmdFire(); } //防止碰撞发生后的旋转 if (this.gameObject.transform.localEulerAngles.x != 0 || gameObject.transform.localEulerAngles.z != 0) { gameObject.transform.localEulerAngles = new Vector3(0, gameObject.transform.localEulerAngles.y, 0); } if (gameObject.transform.position.y != 0) { gameObject.transform.position = new Vector3(gameObject.transform.position.x, 0, gameObject.transform.position.z); } } [Command] void CmdFire() { // This [Command] code is run on the server! // create the bullet object locally var bullet = (GameObject)Instantiate( bulletPrefab, new Vector3((transform.position + transform.forward).x,0.2f,(transform.position + transform.forward).z), Quaternion.identity); bullet.GetComponent<Rigidbody>().velocity = transform.forward * 4; // spawn the bullet on the clients NetworkServer.Spawn(bullet); // when the bullet is destroyed on the server it will automaticaly be destroyed on clients Destroy(bullet, 3.0f); } } ```
联网子弹。创建一个球体的子弹元素,添加rigibody和球状碰撞组件添加进Spawn Info中的注册预制目录中:
public class Bullet : MonoBehaviour { void OnCollisionEnter(Collision collision) { var hit = collision.gameObject; var hitCombat = hit.GetComponent<Combat>(); if (hitCombat != null) { hitCombat.TakeDamage(10); Destroy(gameObject); } else { Destroy(gameObject); } } }
实现第三人称视角时,一开始想的办法是将摄像机绑定为游戏对象的子元素。但是在联机时,由于摄像机优先级相同优先渲染后加载的,所有视角会切换到后进入的人身上。所有只能采用移动摄像机,使摄像机永远在第三人称的固定位置跟随的方式解决。
//添加到PlayerMove脚本中的相应部分 public override void OnStartLocalPlayer(){ private Camera myCamera; public override void OnStartLocalPlayer() { myCamera = Camera.main; } void Update() { myCamera.transform.position = transform.position + transform.forward * -3 + new Vector3(0, 4, 0); myCamera.transform.forward = transform.forward + new Vector3(0, -0.5f, 0); } }