unity官方内置网络unet的实例
一、添加网络管理组件
新创建一个网络管理器。该网络管理器将控制该项目的网络状态,包括游戏状态管理,生成点管理,场景管理,配对和允许访问相关信息。对于高级用户,可以从NetworkManager派生一个类来自定义组件的行为,扩展未涵盖的NetworkManager
二、创建角色预制体:
NetworkIdentity组件介绍:网络物体最基本的组件,客户端与服务器确认是否是一个物体(netID),也用来表示各个状态,如是否是服务器,是否是客户端,是否有权限,是否是本地玩家等。
三、控制角色移动
四、控制角色射击
子弹预制体的设置
子弹生成:
子弹销毁为什么不用同步,是因为服务端是母体,服务端的销毁掉,客户端自然就会被销毁
五、血量的减少
制作血条:
注意:血量减少,因为服务器是母体,为了防止母体子弹销毁时,客户端子弹还没有碰撞到角色,血量不能及时减少,造成数据不同步,因此血量的控制检测只能是在服务器进行计算并同步到客户端
子弹添加碰撞脚本
六、控制人物的重生
设置重生点:
七、控制敌人的生成
敌人在每个客户端都要产生,所以敌人产生在服务端来做,将产生的敌人同步到客户端上
RPC是远程调用(服务端与客户端互调用),调用服务器端的某个方法,使用Comond,想调用客户端的某个方法使用ClientRPC,
SyncVar是同步一个变量,比如同步主角的血量,
hook,指定一个字符串参数,这个参数指定方法的名字,变量的值发生改变时,调用Hook指定的方法。
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class PlayerController : NetworkBehaviour {
public GameObject bulletPrefab;
public Transform bulletSpawn;
// Update is called once per frame
void Update () {
if (isLocalPlayer == false)
{
return;
}
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
transform.Rotate(Vector3.up * h * 120 * Time.deltaTime);
transform.Translate(Vector3.forward * v * 3 * Time.deltaTime);
if (Input.GetKeyDown(KeyCode.Space))
{
CmdFire();
}
}
[Command]//这个命令, 各个客户端会调用这个方法,但是运行是在服务器端运行的
void CmdFire()//这个方法需要在server里面调用,必须以Cmd开头
{
// 子弹的生成 需要server完成,然后把子弹同步到各个client
GameObject bullet = Instantiate(bulletPrefab, bulletSpawn.position, bulletSpawn.rotation) as GameObject;
bullet.GetComponent<Rigidbody>().velocity = bullet.transform.forward * 10;//给初速度
Destroy(bullet, 2);
NetworkServer.Spawn(bullet);//网络生成子弹,同步到客户端,如果没有这句代码的的话,另外一个客户端是看不到子弹的生成的
//bullet 属于网络的一个东西,这句只是把子弹物体分发给了客户端,但是没有给客户端的子弹给与速度
}
public override void OnStartLocalPlayer()
{
//这个方法只会在本地角色那里调用 当角色被创建的时候
GetComponent<MeshRenderer>().material.color = Color.blue;
}
}
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.Networking;
public class Health : NetworkBehaviour {
public const int maxHealth = 100;
//下面SyncVar同步的功能会一直检测,检测到之后会调用这个方法,每个客户端都会调用的
[SyncVar(hook="OnChangeHealth") ]
public int currentHealth = maxHealth;
public Slider healthSlider;
public bool destroyOnDeath = false;//为true,表示是敌人,要销毁
public void TakeDamage(int damage) //下面是在服务端执行的方法
{
if (isServer == false) return;// 血量的处理只在服务器端执行
currentHealth -= damage;
if (currentHealth <= 0)
{
if (destroyOnDeath) //表示是敌人,要销毁
{
Destroy(this.gameObject); return;
}
currentHealth = maxHealth;//死亡之后,当前血量恢复到最大血量
RpcRespawn();//不是敌人的话,要重生
}
}
//上面定义同步变量,更新变化后的变量
void OnChangeHealth(int health)
{
healthSlider.value = health / (float)maxHealth;
}
//设置重生点
private NetworkStartPosition[] spawnPoints;
void Start()
{
if (isLocalPlayer)
{
spawnPoints = FindObjectsOfType<NetworkStartPosition>();
}
}
/// <summary>
/// 人物重生,这个方法应该在客户端调用
/// </summary>
[ClientRpc]
void RpcRespawn()
{
if (isLocalPlayer == false) return;
Vector3 spawnPosition = Vector3.zero;
if (spawnPoints != null && spawnPoints.Length > 0)
{
spawnPosition = spawnPoints[Random.Range(0, spawnPoints.Length)].transform.position;
}
transform.position = spawnPosition;
}
}
using UnityEngine;
using System.Collections;
public class Bullet : MonoBehaviour {
void OnCollisionEnter(Collision col)
{
GameObject hit = col.gameObject;
Health health = hit.GetComponent<Health>();
if (health != null)
{
health.TakeDamage(10);
}
Destroy(this.gameObject);
}
}
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class EnemySpawner : NetworkBehaviour {
public GameObject enemyPrefab;
public int numberOfEnemies;
public override void OnStartServer()
{
for (int i = 0; i < numberOfEnemies; i++)//敌人的数量
{
Vector3 position = new Vector3(Random.Range(-6f, 6f), 0, Random.Range(-6f, 6f));
Quaternion rotation = Quaternion.Euler(0, Random.Range(0, 360), 0);
GameObject enemy = Instantiate(enemyPrefab, position, rotation) as GameObject;
NetworkServer.Spawn(enemy);//同步到客户端,同步到网络上
}
}
}