Unity3D UNET 模仿局域网游戏(二)

紧接着上一篇博客,上一篇博客中,我们已经能够分别移动角色,并且控制他射击了,而且还稍微区分了一下不同的角色。这篇博客中我们继续讲解后面的内容。

既然角色都已经可以射击了,那肯定还得需要一个血量对吧,所以现在我们就添加血量。给Player添加Health脚本并编辑:

using UnityEngine;
using System.Collections;

public class Health : MonoBehaviour {
    public const int maxHealth = 100;   //最大血量
    public int currentHealth = maxHealth;   //当前血量

    //当玩家和子弹碰撞时调用的方法
    public void TakeDamage(int damage)
    {
        currentHealth -= damage;
        if (currentHealth <= 0)   //如果当前血量小于等于0
        {
            currentHealth = maxHealth;    //就让他回复满血状态,方便后面我们让他重生时需要
        }
    }
}

然后需要给Player添加一个Tag 名字为”Player”,给子弹也就是Bullet 添加一个脚本Bullet,并编辑:

using UnityEngine;
using System.Collections;

public class Bullet : MonoBehaviour {

    //当子弹与物体碰撞时
    void OnCollisionEnter(Collision other)
    {
        //如果碰撞的物体的Tag 是Player
        if (other.collider.tag == "Player")
        {
            //调用碰撞物体的TakeDamage,传递一个参数是10
                        other.collider.SendMessage("TakeDamage", 10);
            Destroy(gameObject);  //销毁子弹
        }
    }
}

既然有了血量,我们是不是就应该给他添加一个血条,现在我们就添加血条。新建UI–>Slider,然后把slider下的Handle Slide Area删掉,把Fill 移动到Background的子物体,再把Fill Area删掉。

把 Fill 选择填充父背景,也就是Background,保证他们两个一样大。修改颜色成绿色,Bbackgroud修改颜色成红色。Fill 选择这个

然后这是效果图

最后,我们要把这个血条添加到角色身上去。选中Canvas,Render Mode改为World Space,让摄像机渲染这个UI。把Canvas拖到Player的子物体。做如下改变:

拖动Slider到角色头顶,然后效果图

血条就添加好了,现在我们让他能够随着生命值改变。修改Health类

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class Health : MonoBehaviour {
    public const int maxHealth = 100;   //最大血量
    public int currentHealth = maxHealth;   //当前血量
    public Slider healthSlider;

    //当玩家和子弹碰撞时调用的方法
    public void TakeDamage(int damage)
    {
        currentHealth -= damage;
        if (currentHealth <= 0)   //如果当前血量小于等于0
        {
            currentHealth = maxHealth;    //就让他回复满血状态,方便后面我们让他重生时需要
        }
        healthSlider.value = (float)currentHealth / maxHealth;    //修改Slider的比例
    }
}

这时我们发现当角色旋转时,血条也会旋转,看起来不美观,我们让他只”看着摄像机”。

给Canvas添加一个脚本LookAtCamera并编辑

using UnityEngine;
using System.Collections;

public class LookAtCamera : MonoBehaviour {

    // Update is called once per frame
    void Update () {
        transform.LookAt(Camera.main.transform);
    }
}

这样血条就会一直对着摄像机了。现在运行游戏,是可以使用的,

但是!!细心的你会发现,他们的血条有可能不同步。这是因为,血量的判断在客户端和服务端都进行了判断,相当于各自计算各自的,但是!!当服务端的子弹碰撞到Player时,会计算生命值,然后销毁子弹,而当服务端的子弹销毁时,客户端的子弹也会跟着一起消失,而服务端已经计算了,而客户端没有计算(就像网络游戏有延迟一样),就会导致不同步。现在我们来让子弹同步。要解决这个问题,我们就要让血量的检测在服务端进行,然后同步到客户端就行了。修改Health类继承NetworkBehaviour,

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.Networking;

public class Health : NetworkBehaviour {
    public const int maxHealth = 100;   //最大血量
    //检测一个属性,当服务端改变值时,会同步到客户端
    //当值改变时,会调用一个方法 如:OnChangeHealth
    [SyncVar(hook = "OnChangeHealth")]
    public int currentHealth = maxHealth;   //当前血量
    public Slider healthSlider;

    //当玩家和子弹碰撞时调用的方法
    public void TakeDamage(int damage)
    {
        if (!isServer)   //如果不是服务端
        {
            return;
        }
        currentHealth -= damage;
        if (currentHealth <= 0)   //如果当前血量小于等于0
        {
            currentHealth = maxHealth;    //就让他回复满血状态,方便后面我们让他重生时需要
        }

    }

    //当服务端检测的属性值改变时调用的方法
    //health:改变后的值
    void OnChangeHealth (int health)
    {
        healthSlider.value = (float)health / maxHealth;    //修改Slider的比例
    }
}

这时候就同步了。。接下来我们设置当角色生命值为0时重生。修改Health类,这里修改的地方比较少,我就直接放修改的图片,大家对应着修改就行了。

这时候运行,你会发现,只有当客户端攻击时角色死亡位置才会重置,服务端攻击不会。这是因为一开始我们设置了,

这代表只有客户端才有权限,而服务端的攻击然后重置位置,这是没有权限的,所以现在我们要让它能够在服务端也重置位置,修改Health类

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.Networking;

public class Health : NetworkBehaviour {
    public const int maxHealth = 100;   //最大血量
    //检测一个属性,当服务端改变值时,会同步到客户端
    //当值改变时,会调用一个方法 如:OnChangeHealth
    [SyncVar(hook = "OnChangeHealth")]
    public int currentHealth = maxHealth;   //当前血量
    public Slider healthSlider;

    //当玩家和子弹碰撞时调用的方法
    public void TakeDamage(int damage)
    {
        if (!isServer)   //如果不是服务端
        {
            return;
        }
        currentHealth -= damage;
        if (currentHealth <= 0)   //如果当前血量小于等于0
        {
            currentHealth = maxHealth;    //就让他回复满血状态,方便后面我们让他重生时需要
            RpcRespawn();     //调用一个方法,设置重生的位置
        }

    }

    //当服务端检测的属性值改变时调用的方法
    //health:改变后的值
    void OnChangeHealth (int health)
    {
        healthSlider.value = (float)health / maxHealth;    //修改Slider的比例
    }

    //远程调用,表示调用这个方法时就会在客户端调用,方法名必须以Rpc开头
    [ClientRpc]
    void RpcRespawn()
    {
        if (!isLocalPlayer)
        {
            return;
        }
        transform.position = Vector3.zero;   //把位置设置到0,0,0
    }
}

这时候就可以同步了。在下一篇博客中我们将对游戏增加一点小内容。

本博客用作新手学习讨论,如有不好或错误的地方也请指出来,谢谢。

时间: 2024-10-05 23:26:37

Unity3D UNET 模仿局域网游戏(二)的相关文章

Unity3D UNET 模仿局域网游戏

这两天在学习的过程中,发现一个讲Unity的unet组件的好教程,在这里分享给大家. 新建一个 UnetProject. 新建一个GameObject重命名为Network Manager,给它添加Network Manager组件,这是Unet提供的一个核心管理组件,可以在脚本里访问Network Manager进行网络开发. 还需要添加一个 Network Manager HUD 组件,这个用来显示UI,UI上的按钮会跟Network Manager交互.这时候运行屏幕上会出现如下: LAN

转 猫都能学会的Unity3D Shader入门指南(二)

猫都能学会的Unity3D Shader入门指南(二) 关于本系列 这是Unity3D Shader入门指南系列的第二篇,本系列面向的对象是新接触Shader开发的Unity3D使用者,因为我本身自己也是Shader初学者,因此可能会存在错误或者疏漏,如果您在Shader开发上有所心得,很欢迎并恳请您指出文中纰漏,我会尽快改正.在之前的开篇中介绍了一些Shader的基本知识,包括ShaderLab的基本结构和语法,以及简单逐句地讲解了一个基本的shader.在具有这些基础知识后,阅读简单的sha

计蒜客 跳跃游戏二(动态规划)

给定一个非负整数数组,假定你的初始位置为数组第一个下标. 数组中的每个元素代表你在那个位置能够跳跃的最大长度. 你的目标是到达最后一个下标,并且使用最少的跳跃次数. 例如: A = [2,3,1,1,4], 到达最后一个下标的最少跳跃次数为2.(先跳跃1步,从下标0到1,然后跳跃3步,到达最后一个下标.一共两次) 格式: 第一行输入一个正整数n,接下来的一行,输入数组A[n]. 最后输出最少的跳跃次数. 样例1 输入: 5 3 1 1 1 1 输出: 2 #include <stdio.h>

hiho一下 第四十五周 博弈游戏&#183;Nim游戏&#183;二 [ 博弈 ]

传送门 题目1 : 博弈游戏·Nim游戏·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Alice和Bob这一次准备玩一个关于硬币的游戏:N枚硬币排成一列,有的正面朝上,有的背面朝上,从左到右依次编号为1..N.现在两人轮流翻硬币,每次只能将一枚正面朝上的硬币翻过来,并且可以随自己的意愿,在一枚硬币翻转后决定要不要将该硬币左边的任意一枚硬币也翻一次(正面翻到背面或背面翻到正面).翻最后一枚正面向上的硬币的人获胜.同样的,这次游戏里面Alice仍然先手,两人均采

Unity3D射击游戏-UNITY3D软件开发、游戏开发、UNITY3D游戏开发

Unity3D射击游戏-UNITY3D软件开发.游戏开发.UNITY3D游戏开发 上海诸君信息科技有限公司是以Oculus.Unity.虚拟现实作为核心业务的民营高科技企业,坚持精益研发与技术创新,拥有丰富Oculus.Unity.虚拟现实的软件与游戏开发经验,能提供优质的技术解决方案. 公司拥有全面强大的团队,拥有优秀的设计师与美术人员,有大量的游戏项目制作管理经验,能优质控制游戏产品质量和制作时间,成功服务于海内外多家公司,拥有丰富的客户案例. 诸君信息科技已服务的客户包括,普华永道.交大.

Unity3D热更新全书-脚本(二) 两级分化

上篇明确了我们探讨的脚本是什么:是写在文本文件里面的代码,可以作为资源加载,取得字符串再执行. 可是为什么世界上会有那么多的脚本?而其使用方法完全看起来不一样呢?这是因为每种脚本都有自己的定位,在不同的复杂度脚本将表现出完全不同的样貌,我们来看一下. 复杂度一:计算 执行字符串的核心函数应该是这样的 int i = Eval("1+2"); 我们有一套例子,本文最后有如何取得例子的说明. 程序里就可以通过执行字符串来执行逻辑,字符串的变更就可以得到逻辑的变更. 试想如果要做公式计算,他

博弈游戏&#183;Nim游戏&#183;二

题目1 : 博弈游戏·Nim游戏·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Alice和Bob这一次准备玩一个关于硬币的游戏: N枚硬币排成一列,有的正面朝上,有的背面朝上,从左到右依次编号为1..N.现在两人轮流翻硬币,每次只能将一枚正面朝上的硬币翻过来,并且可以随自己的意愿,在一枚硬币翻转后决定要不要将该硬币左边的任意一枚硬币也翻一次(正面翻到背面或背面翻到正面).翻最后一枚正面向上的硬币的人获胜.同样的,这次游戏里面Alice仍然先手,两人均采取最优

计蒜客-跳跃游戏二 (简单dp)

题目链接:https://nanti.jisuanke.com/t/20                                                            跳跃游戏二 给定一个非负整数数组,假定你的初始位置为数组第一个下标.数组中的每个元素代表你在那个位置能够跳跃的最大长度.你的目标是到达最后一个下标,并且使用最少的跳跃次数. 例如: A = [2,3,1,1,4],到达最后一个下标的最少跳跃次数为 2.(先跳跃 1 步,从下标 0 到 1,然后跳跃 3 步,

[Unity3D]Unity3D圣骑士模仿游戏开发传仙灵达到当局岛

大家好,我是秦培.欢迎关注我的博客.我的博客地址blog.csdn.net/qinyuanpei. 在前面的文章中.我们分别实现了一个自己定义的角色控制器<[Unity3D]Unity3D游戏开发之仿仙剑奇侠传角色控制效果>和角色死亡的效果<[Unity3D]Unity3D游戏开发之仿仙剑奇侠传角色死亡效果实现>.今天我们继续来做点和仙剑相关的东西,首先我们来看一副图: 这幅图呢,是仙剑奇侠传的第一个迷宫场景--仙灵岛的莲花池. 男主角李逍遥为替婶婶求药独闯仙灵岛,在经历了前面的小