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

关键词: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 ();
            // 获得法术的前进方向,用于实现碰撞效果;
            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 ().KillStatsUpdate ();
                }
                // 根据伤害值,造成相应伤害
                health.TakeDamage (HurtValue);
                // 产生撞击效果
                other.GetComponent ().AddForce (bounceDriection*m_BouncePower);
                
                //根据绑定的施法者netId,调用施法者的数据统计脚本更新伤害数据
                NetworkServer.objects [PlayerNetID].gameObject.GetComponent ().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 ();
        // 将施法者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的显示: "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] 多人游戏中法术伤害和击杀数据的实时显示)