Unity官方内置网络NetWork官方实例教程(一)Unity官方内置网络NetWork官方教程——拓展(三)
0X00 制作子弹
- 首先制作导弹预制体,随便选择一个sphere或者capsule调整合适大小(自己喜欢的颜色)自定义命名即可(例子为:Bullet)
- 第二步在新建一个玩家的子物体里(空物体即可),并调整合适的位置(作为导弹的起始位置)自定义命名即可(例子为:BulletSpawn)
- 第三步将子弹拖制为预制体,并将预制体拖制NetworkManager中的Spawn Info 的 Registered Spawnble Prefabs:中
- 子玩家控制的脚本中添加发射子弹的代码如下:
#region 字段定义
[SerializeField]
private GameObject bulletPrefab; // 子弹
[SerializeField]
private Transform bulletSpawn; // 子弹父物体
#endregion
void Update()
{
if (!isLocalPlayer)
{
return;
}
PlayerMove();
if (Input.GetKeyDown(KeyCode.Space))
{
//Fire();
CmdFire();
}
}
/// <summary>
/// 这个命令代码在客户机上被调用。
/// ……但是它是在服务器上运行的!
///
/// 多人开火
/// </summary>
[Command]
private void CmdFire()
{
// 克隆子弹
var bullet = (GameObject)Instantiate(bulletPrefab, bulletSpawn.position, bulletSpawn.rotation);
// 为子弹添加速度
bullet.GetComponent<Rigidbody>().velocity = bullet.transform.forward * 60;
// 同时在客户端生成子弹
NetworkServer.Spawn(bullet);
//2秒后摧毁子弹
Destroy(bullet, 0.5f);
}
0X02 杀伤效果
- 首先我们先简单的区分一下玩家(会在拓展中详细写):我们在玩家控制脚本中加一段代码如下:
/// <summary>
/// 更改本地玩家的颜色为红色
/// </summary>
public override void OnStartLocalPlayer()
{
GetComponent<MeshRenderer>().material.color = Color.red;
}
效果如下(所有截图都为其他例子,暂时仅供参考):
- 制作血条,如图所示(不具体说了):
- 显示血量代码如下:
/// <summary>
/// 挂载对象:player
/// 功能:显示现在血量
/// </summary>
public class Health : NetworkBehaviour
{
#region 字段
public const int _maxHealth = 100; // 最大血量
[SyncVar(hook = "OnChangeHealth")] // 同步变量
private int _curHealth = _maxHealth; // 当前血量默认为最大
public RectTransform _haemalStrand; // 血条
#endregion
#region 系统方法
void Update()
{
// 画布一直朝着照相机
_haemalStrand.parent.transform.LookAt(Camera.main.transform);
}
#endregion
#region 公共方法
/// <summary>
/// 攻击方法
/// </summary>
/// <param name="amount">伤害值</param>
public void Attack(int damageValue)
{
if (!isServer)
{
return;
}
_curHealth -= damageValue; // 减少生命值
if (_curHealth<=0)
{
Debug.Log("牺牲了。。。。。。");
_curHealth = _maxHealth;
RpcRespawm();
}
}
/// <summary>
/// 改变血量方法
/// 如果你用的图片代表血条,则用这个
/// 上面你的同步变量会同步到这个对勾函数中
/// 如果使用的是滑动条的话则不需要这个方法
/// </summary>
/// <param name="health"></param>
void OnChangeHealth(int health)
{
_haemalStrand.sizeDelta = new Vector2(health, _haemalStrand.sizeDelta.y);
}
[ClientRpc]
private void RpcRespawm()
{
if (!isLocalPlayer)
{
transform.position = Vector3.zero;
}
}
#endregion
}
- 编写子弹脚本,该脚本需要挂载到子弹身上。如下:
/// <summary>
/// 挂载对象:Bullet
/// 功能:碰到其他对象销毁子弹,调用受伤方法传一个伤害值
/// </summary>
public class Bullet : MonoBehaviour {
/// <summary>
/// 碰撞检测
/// </summary>
/// <param name="collision">碰到的碰撞盒</param>
private void OnCollisionEnter(Collision collision)
{
var _hit = collision.gameObject;
var _health = _hit.GetComponent<Health>(); // 获取脚本
if (_health!=null)
{
_health.Attack(10);
}
Destroy(gameObject);
}
}