美文网首页unity进阶教程合集征服Unity3dunity3D技术分享
[Unity3D] 多人游戏中法术伤害和击杀数据的实时显示

[Unity3D] 多人游戏中法术伤害和击杀数据的实时显示

作者: 薯條 | 来源:发表于2017-10-24 17:43 被阅读101次

    关键词:NetworkServer.objects;NetworkInstanceId

    基本原理:在释放法术时,将施法角色的NetworkInstanceId(netId)绑在法术上,如果法术击中目标(产生伤害/击杀目标),则根据已绑定的施法者的netId,更新该施法者的伤害和击杀数值,并在UI上显示;

    Tips:

    1、在多人游戏中,法术通常是作为Prefab,利用NetworkServer.Spawn()方法在释放时生成;

    2、为了方便,可以将控制法术伤害的脚本添加在法术的Prefab上;

    3、如果法术是基于粒子系统构建,那么伤害触发的控制需要写在OnParticleCollision()中;

    示例:

    该实现主要涉及到三个脚本:

    1. 伤害控制脚本:
      a、法术被释放时,获得施法者netId;
      b、击中目标后,调用角色数据统计脚本,更新并显示数据;

    2. 法术释放脚本:
      生成法术,并在生成时将施法者的netId赋给法术的伤害控制脚本保存;

    3. 角色数据统计脚本:
      a、记录并更新造成的伤害和击杀数据;
      b、更新数据在相应的UI上;


    1、伤害控制脚本 - Hurt.cs,添加在“法术”的Prefab上。
    public class Hurt : NetworkBehaviour {
        ...
        // 法术所造成的伤害值;
        public int HurtValue = 10;
        // 用于获取施法者的netId;
        public NetworkInstanceId PlayerNetID;
        ...
        // 粒子系统的碰撞事件;
        void OnParticleCollision(GameObject other){
            
            if (other.gameObject.CompareTag("Player")){
                // 获得碰撞对象的Health实例,这是绑在角色上的血量控制脚本;
                var health = other.GetComponent<Health> ();
                // 获得法术的前进方向,用于实现碰撞效果;
                var bounceDriection = this.transform.forward;
    
                if (!health) {
                    Debug.Log ("Health Component not Found!");
                } else {
                    // 目标对象的当前血量减去伤害值后,小于等于0,则被击杀
                    if(health.currentHealth-HurtValue <=0){
                        //根据绑定的施法者netId,调用施法者的数据统计脚本更新击杀数据
                        NetworkServer.objects [PlayerNetID].gameObject.GetComponent<PlayerStats> ().KillStatsUpdate ();
                    }
                    // 根据伤害值,造成相应伤害
                    health.TakeDamage (HurtValue);
                    // 产生撞击效果
                    other.GetComponent<Rigidbody> ().AddForce (bounceDriection*m_BouncePower);
                    
                    //根据绑定的施法者netId,调用施法者的数据统计脚本更新伤害数据
                    NetworkServer.objects [PlayerNetID].gameObject.GetComponent<PlayerStats> ().DamageStatsUpdate(HurtValue);
                }
            }
            // 击中2s后,销毁该法术
            Destroy (this.gameObject,2f);
        }
        ...
    }
    
    2、法术释放脚本 - Spells.cs,添加在“角色”Prefab上,
    public class Spells : NetworkBehaviour {
        ...
        //存放所有法术,作为法术索引
        public GameObject[] SpellGroup;
        ...
        [Command]
        public void CmdSpell(int index, float time, Vector3 position, Quaternion rotation,
            int groupindex){
    
            // 判断法术类型,与本文无关
            if (groupindex < 0 || groupindex > 2)
                groupindex = 0;
            
            // 根据index获得对应法术实例
            var m_Spell = SpellGroup [index];
            // 实例化法术
            GameObject spell = (GameObject)Instantiate (m_Spell, position, rotation);
    
            // 获得实例后,获得法术上的Hurt脚本
            var hurt = spell.GetComponent<Hurt> ();
            // 将施法者netId,赋值给Hurt.PlayerNetID,由此释放出的法术便记住了它的主人。
            if(hurt){
                hurt.PlayerNetID = this.netId;
            }
            // 生成法术
            NetworkServer.Spawn (spell);
            // 如果为击中,则在一定时间后,销毁该法术;
            Destroy (spell,time);
    
        }
        ...
    }
    
    3、角色数据统计脚本 - PlayerStats.cs,添加在“角色”的Prefab上,
    public class PlayerStats : MonoBehaviour {
        // 记录角色造成的伤害和击杀数值
        private int m_Kill = 0;
        private int m_Damage = 0;
        
        // 用于获得UI Text的实例;
        private Text m_StatsText;
    
        void Start () {
            // 获得名为“Stats”的UI Text实例,名字不重要,找到对应的Text就行;
            m_StatsText = GameObject.Find ("Stats").GetComponent<Text>();
            // 初始化该Text的显示: "KILL: 0     DAMAGE: 0"
            m_StatsText.text = string.Format ("KILL:  {0}\tDAMAGE:  {1}",0,0);
        }
        // 更新UI上的数据显示
        void StatsUpdate(){
            m_StatsText.text = string.Format ("KILL:  {0}\tDAMAGE:  {1}",m_Kill,m_Damage);
        }
        // 更新伤害数值,在Hurt.cs中被调用
        public void DamageStatsUpdate(int hurtValue){
            m_Damage += hurtValue;
            StatsUpdate ();
        }
        // 更新击杀数值,在Hurt.cs中被调用
        public void KillStatsUpdate(){
            m_Kill++;
            StatsUpdate ();
        }
    
    
    }
    

    Enjoy it

    相关文章

      网友评论

        本文标题:[Unity3D] 多人游戏中法术伤害和击杀数据的实时显示

        本文链接:https://www.haomeiwen.com/subject/sajxpxtx.html