3D游戏编程10--多人游戏与网络

游戏机制

场景是沿用巡逻兵的九块区域,在对角线分别创建一个玩家,只要两个玩家相遇就都会被摧毁,同时游戏结束,其中两个玩家有各自的摄像机,各自的动作都会显示。

游戏演示

网络游戏1
网络游戏2

具体实现

代码部分

CameraFlow.cs

实现摄像机跟随玩家,并且随着玩家移动的功能,和单机版的一样

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraFlow : MonoBehaviour
{
    public Transform follow;            //跟随的物体
    void Start()
    {

    }

    void FixedUpdate()
    {
        if (follow)
        {
            Vector3 nextpos = follow.forward * -1 * 4 + follow.up * 3 + follow.position;
            this.transform.position = nextpos;
            this.transform.LookAt(new Vector3(follow.position.x, follow.position.y + 2, follow.position.z));
        }
    }
}

NewMove.cs

主要是将以前的移动的代码,单独拿出来,放在玩家上,做成一个预制体
分别是鼠标左键,第一种攻击方式,鼠标右键,第二种攻击方式,空格键,跳跃。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class NewMove : NetworkBehaviour
{
    public float moveSpeed;
    public float rotateSpeed;
    public void Start()
    {
        //这句可以实现摄像机在两个玩家之间显示的不一样
        if (isLocalPlayer)
        {
            GameObject.Find("Main Camera").GetComponent<CameraFlow>().follow = gameObject.transform;
        }
    }
    public void Update()
    {
        if (!isLocalPlayer)
        {
            return;
        }
        float translationX = Input.GetAxis("Horizontal");
        float translationZ = Input.GetAxis("Vertical");
        MovePlayer(translationX, translationZ);
        Attack();
    }
    public void Attack()
    {
        //Fire1对应鼠标左键
        if (Input.GetButtonDown("Fire1"))
        {
            CmdAttack1();
        }
        //Fire2对应鼠标右键
        if (Input.GetButtonDown("Fire2"))
        {
            CmdAttack2();
        }
        //Jump对应空格键space
        if (Input.GetButtonDown("Jump"))
        {
            CmdJump();
        }
    }
    //要实现Animator的动态,首先要在组件中加入Newwork Animator,然后将要加入的动作勾选
    //并且用Trigger触发的动作,需要用下面这种方式实现,就是攻击有客户端发出,由服务端调回
    //这样就可以看见动作,用bool触发的不需要
    [Command]
    public void CmdAttack1()
    {
        RpcAttack1();
    }
    [ClientRpc]
    public void RpcAttack1()
    {
        this.GetComponent<Animator>().SetTrigger("attack1");
    }

    [Command]
    public void CmdAttack2()
    {
        RpcAttack2();
    }
    [ClientRpc]
    public void RpcAttack2()
    {
        this.GetComponent<Animator>().SetTrigger("attack2");
    }

    [Command]
    public void CmdJump()
    {
        RpcJump();
    }
    [ClientRpc]
    public void RpcJump()
    {
        this.GetComponent<Animator>().SetTrigger("jump");
    }

    public void MovePlayer(float translationX, float translationZ)
    {
        if (translationX != 0 || translationZ != 0)
        {
            this.GetComponent<Animator>().SetBool("run", true);
        }
        else
        {
            this.GetComponent<Animator>().SetBool("run", false);
        }

        this.transform.Translate(0, 0, translationZ * moveSpeed * Time.deltaTime);
        this.transform.Rotate(0, translationX * rotateSpeed * Time.deltaTime, 0);

        if (this.transform.localEulerAngles.x != 0 || this.transform.localEulerAngles.z != 0)
        {
            this.transform.localEulerAngles = new Vector3(0, this.transform.localEulerAngles.y, 0);
        }
        if (this.transform.position.y != 0)
        {
            this.transform.position = new Vector3(this.transform.position.x, 0, this.transform.position.z);
        }
    }

    public void OnCollisionEnter(Collision collision)
    {
        var hit = collision.gameObject;
        var hitPlayer = hit.GetComponent<NewMove>();

        if(hitPlayer != null)
        {
            Destroy(gameObject);
            Destroy(hit);
            //将UserGUI中的isEnd置为true表示游戏结束
            GameObject.Find("GameObject").GetComponent<UserGUI>().isEnd = true;
        }
    }
}

UserGUI.cs

主要判断游戏结束,以及显示游戏结束的信息


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UserGUI : MonoBehaviour {

    public bool isEnd;

    void Start () {
        isEnd = false;
    }

    public void OnGUI()
    {
        if (isEnd)
        {
            GUI.Label(new Rect(300,200, 200, 50), "游戏结束");
        }
    }
}

其他设置部分

组件
其中MainCamera
MainCamera
其中GameObject
GamejObject
其中NetworkManager
NetworkManager
其中Pos1和Pos2
Pos1
player
player1
player2

代码以及视频

代码以及视频

猜你喜欢

转载自blog.csdn.net/yaoxh6/article/details/80794021