游戏机制
场景是沿用巡逻兵的九块区域,在对角线分别创建一个玩家,只要两个玩家相遇就都会被摧毁,同时游戏结束,其中两个玩家有各自的摄像机,各自的动作都会显示。
游戏演示
具体实现
代码部分
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
其中GameObject
其中NetworkManager
其中Pos1和Pos2
player