Unity3D UNET 模仿局域网游戏(二)
2016-05-04 09:52
417 查看
紧接着上一篇博客,上一篇博客中,我们已经能够分别移动角色,并且控制他射击了,而且还稍微区分了一下不同的角色。这篇博客中我们继续讲解后面的内容。
既然角色都已经可以射击了,那肯定还得需要一个血量对吧,所以现在我们就添加血量。给Player添加Health脚本并编辑:
然后需要给Player添加一个Tag 名字为”Player”,给子弹也就是Bullet 添加一个脚本Bullet,并编辑:
既然有了血量,我们是不是就应该给他添加一个血条,现在我们就添加血条。新建UI–>Slider,然后把slider下的Handle Slide Area删掉,把Fill 移动到Background的子物体,再把Fill Area删掉。
把 Fill 选择填充父背景,也就是Background,保证他们两个一样大。修改颜色成绿色,Bbackgroud修改颜色成红色。Fill 选择这个
然后这是效果图
最后,我们要把这个血条添加到角色身上去。选中Canvas,Render Mode改为World Space,让摄像机渲染这个UI。把Canvas拖到Player的子物体。做如下改变:
拖动Slider到角色头顶,然后效果图
血条就添加好了,现在我们让他能够随着生命值改变。修改Health类
这时我们发现当角色旋转时,血条也会旋转,看起来不美观,我们让他只”看着摄像机”。
给Canvas添加一个脚本LookAtCamera并编辑
这样血条就会一直对着摄像机了。现在运行游戏,是可以使用的,
但是!!细心的你会发现,他们的血条有可能不同步。这是因为,血量的判断在客户端和服务端都进行了判断,相当于各自计算各自的,但是!!当服务端的子弹碰撞到Player时,会计算生命值,然后销毁子弹,而当服务端的子弹销毁时,客户端的子弹也会跟着一起消失,而服务端已经计算了,而客户端没有计算(就像网络游戏有延迟一样),就会导致不同步。现在我们来让子弹同步。要解决这个问题,我们就要让血量的检测在服务端进行,然后同步到客户端就行了。修改Health类继承NetworkBehaviour,
这时候就同步了。。接下来我们设置当角色生命值为0时重生。修改Health类,这里修改的地方比较少,我就直接放修改的图片,大家对应着修改就行了。
这时候运行,你会发现,只有当客户端攻击时角色死亡位置才会重置,服务端攻击不会。这是因为一开始我们设置了,
这代表只有客户端才有权限,而服务端的攻击然后重置位置,这是没有权限的,所以现在我们要让它能够在服务端也重置位置,修改Health类
这时候就可以同步了。在下一篇博客中我们将对游戏增加一点小内容。
本博客用作新手学习讨论,如有不好或错误的地方也请指出来,谢谢。
既然角色都已经可以射击了,那肯定还得需要一个血量对吧,所以现在我们就添加血量。给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 } }
这时候就可以同步了。在下一篇博客中我们将对游戏增加一点小内容。
本博客用作新手学习讨论,如有不好或错误的地方也请指出来,谢谢。
相关文章推荐
- Kinect结合Unity3D引擎开发体感游戏(一)
- 我是运营,我没有假期
- [原创]java局域网聊天系统
- Shell 脚本编程陷阱
- 每个 Linux 游戏玩家都绝不想要的恼人体验
- 在 Fedora 上使用 Steam play 和 Proton 来玩 Windows 游戏
- 新注册
- Steam 让我们在 Linux 上玩 Windows 的游戏更加容易
- 如何使用 Steam Play 在 Linux 上玩仅限 Windows 的游戏
- 新一代iPad适配应用之游戏篇
- VBS脚本写的Windows硬件检测工具分享
- 一个注册表搞定“打开局域网机器文件提示”
- VB实现的《QQ美女找茬游戏》作弊器实例
- 用vbscript实现隐藏任务栏图标的脚本
- 用autoit编写第一个脚本(Hello World)
- VBS调用WMI快速关闭IE的脚本
- Oracle数据库执行脚本常用命令小结
- 收集的ROS防火墙脚本