游戏蛮牛学习群(纯技术交流,不闲聊):959392658
游戏蛮牛 手机端
开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

开发者专栏

关注:2370

当前位置:游戏蛮牛 技术专区 开发者专栏

__________________________________________________________________________________
开发者干货区版块规则:

  1、文章必须是图文形式。(至少2幅图)
      2、文章字数必须保持在1500字节以上。(编辑器右下角有字数检查)
      3、本版块只支持在游戏蛮牛原创首发,不支持转载。
      4、本版块回复不得无意义,如:顶、呵呵、不错......【真的会扣分的哦】
      5、......
__________________________________________________________________________________
查看: 851|回复: 4

[alayeshi] Unity5之Network人物被打掉血功能

[复制链接]  [移动端链接]
排名
2720
昨日变化

74

主题

326

帖子

1577

积分

Rank: 9Rank: 9Rank: 9

UID
54986
好友
11
蛮牛币
2743
威望
0
注册时间
2014-11-12
在线时间
479 小时
最后登录
2018-12-5

专栏作家

发表于 2018-6-27 14:40:25 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x

这一讲主要是讲人物如何掉血,是为了下一节掉血同步做铺垫的,这节先讲仅在服务器端的掉血,客户端不同步!重要的事情讲3遍:服务器端,服务器端,服务器端!!!

首先是用Slider制作血条,制作方法网上资料很多就不讲了。

几个注意的地方:血条是世界坐标,所以Canvas要改成world space,还有就是相机要永远看到血条的正面(不会变成一个片),因此加上了Lookatcamera的脚本,如下图:


脚本的具体代码如下:把这个脚本绑定到canvas上就可以了。

[csharp] view plain copy



  • using UnityEngine;  
  • using System.Collections;  
  •   
  • public class Lookatcamera : MonoBehaviour {  
  •   
  •     // Use this for initialization  
  •     void Start () {  
  •       
  •     }  
  •       
  •     // Update is called once per frame  
  •     void Update () {  
  •         if(Camera.main!=null)  
  •         this.gameObject.transform.LookAt(Camera.main.transform);  
  •     }  
  • }  

[csharp] view plain copy



  •   

然后就看人物了,人物既然要血条显示掉血,那必然有对应的代码来实现,代码如下:

[csharp] view plain copy



  • using UnityEngine;  
  • using System.Collections;  
  • using UnityEngine.UI;  
  • using UnityEngine.Networking;  
  •   
  • public class health : NetworkBehaviour {  
  •   
  •   
  •     public const int maxhealth = 100;  
  •     public int currenthealth = maxhealth;  
  •     public Slider healthslider;  
  •   
  •   
  •   
  •     public void Takedamage(int damage)  
  •     {  
  •         if (isServer == false)  
  •         {  
  •             return;  
  •         }  
  •   
  •         currenthealth -= damage;  
  •         if (currenthealth<=0)  
  •         {  
  •             currenthealth = 0;  
  •         }  
  •   
  •         healthslider.value = currenthealth / (float)maxhealth;  
  •     }  
  •   
  •     // Use this for initialization  
  •     void Start () {  
  •       
  •     }  
  •       
  •     // Update is called once per frame  
  •     void Update () {  
  •       
  •     }  
  •   
  •   
  • }  

只要将该代码绑定到主角身上,然后把对应的slider这个血条拖上去就OK。如图:


然后再看子弹,因为子弹要打到人物才会使人掉血,所以子弹上必须有一个检测撞击到人的脚本,如下:

[csharp] view plain copy



  • using UnityEngine;  
  • using System.Collections;  
  •   
  • public class knock : MonoBehaviour {  
  •   
  •     /// <summary>  
  •     /// 子弹碰撞人物时调用人物身上的掉血方法  
  •     /// </summary>  
  •     /// <param name="collision"></param>  
  •      void OnCollisionEnter(Collision collision)  
  •     {  
  •         Debug.Log("hit");  
  •         GameObject hit = collision.gameObject;  
  •         health healths= hit.GetComponent<health>();  
  •         if (healths != null)  
  •         {  
  •             healths.Takedamage(10);  
  •         }  
  •         Destroy(this.gameObject);  
  •     }  
  •   
  •   
  • }  

就这么简单,完成了!

然后就可以测试了,仅在服务器端有掉血效果,客户端不同步。效果如下:



接着上一讲的内容来讲,上一讲已经实现了服务器端的掉血功能,那么这一讲自然就要实现所有客户端同步掉血功能了。

其实主要就是同步的功能,一切都在代码里。思路很明显,只要将血量的值同步给客户端就可以了。

代码如图:



  • using UnityEngine;



  • using System.Collections;



  • using UnityEngine.UI;



  • using UnityEngine.Networking;







  • public class health : NetworkBehaviour {











  •     public const int maxhealth = 100;







  •     [SyncVar (hook ="changevalue")]//同步变量,改变currenthealth的值。一直会调用changevalue方法。



  •     public int currenthealth = maxhealth;







  •     public Slider healthslider;















  •     public void Takedamage(int damage)



  •     {



  •         if (isServer == false)



  •         {



  •             return;



  •         }







  •         currenthealth -= damage;



  •         if (currenthealth<=0)



  •         {



  •             currenthealth = 0;



  •         }











  •     }



  •     /// <summary>



  •     /// 该方法里需要定义一个参数,传入的参数就是上面定义的同步的currenthealth的值



  •     /// </summary>



  •     /// <param name="healthvalue"></param>



  •     void changevalue(int healthvalue)



  •     {



  •         healthslider.value = healthvalue / (float)maxhealth;



  •     }



  • }


这里来解读一下代码里的部分内容,其实整个health里的改动很少。只在血量变量上面添加了一个[syncvar],这个东西的意思是同步变量。它的功能就是可以将currenthealth的值同步到所有客户端。

而其后面的(hook ="changevalue")是为了能够在客户端看到血条在UI上的变化,如果没有(hook ="changevalue")血量一样会同步到所有客户端,但是客户端的UI是看不到变化的。

语法规定有了(hook ="changevalue"),就必须要有个名为changevalue的方法与之对应,而且会一直调用该方法,所有下面代码里有了对应的changevalue方法。

本案例里要求的这个方法,必须有一个参数,而这个参数的传入值就是上面定义的currenthealth。然后在这个方法里把UI变化的方法写进去,这样无论血量如何变化都会同步到所有客户端且对应的UI。

这样就实现了该功能了,效果如下:




回复

使用道具 举报

5熟悉之中
780/1000
排名
6052
昨日变化
3

9

主题

318

帖子

780

积分

Rank: 5Rank: 5

UID
285521
好友
0
蛮牛币
1258
威望
0
注册时间
2018-6-12
在线时间
227 小时
最后登录
2018-12-5
发表于 2018-6-30 15:59:28 | 显示全部楼层
谢大佬

回复

使用道具 举报

5熟悉之中
568/1000
排名
5371
昨日变化
3

2

主题

147

帖子

568

积分

Rank: 5Rank: 5

UID
252889
好友
2
蛮牛币
1838
威望
0
注册时间
2017-11-6
在线时间
164 小时
最后登录
2018-12-4
QQ
发表于 2018-7-2 11:55:46 | 显示全部楼层

回复

使用道具 举报

5熟悉之中
863/1000
排名
4571
昨日变化
16

3

主题

369

帖子

863

积分

Rank: 5Rank: 5

UID
269155
好友
2
蛮牛币
1403
威望
0
注册时间
2018-2-22
在线时间
183 小时
最后登录
2018-12-10
发表于 2018-7-16 10:45:25 | 显示全部楼层
network这不是unity自带的吗  好用吗

回复 支持 反对

使用道具 举报

7日久生情
2299/5000
排名
2570
昨日变化
5

1

主题

1464

帖子

2299

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
119154
好友
0
蛮牛币
2549
威望
0
注册时间
2015-8-21
在线时间
292 小时
最后登录
2018-12-9
发表于 2018-9-3 22:16:05 | 显示全部楼层
谢谢楼主大大。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

快速回复 返回顶部 返回列表