关键词:NetworkServer.objects;NetworkInstanceId
基本原理:在释放法术时,将施法角色的NetworkInstanceId(netId)绑在法术上,如果法术击中目标(产生伤害/击杀目标),则根据已绑定的施法者的netId,更新该施法者的伤害和击杀数值,并在UI上显示;
Tips:
1、在多人游戏中,法术通常是作为Prefab,利用NetworkServer.Spawn()方法在释放时生成;
2、为了方便,可以将控制法术伤害的脚本添加在法术的Prefab上;
3、如果法术是基于粒子系统构建,那么伤害触发的控制需要写在OnParticleCollision()中;
示例:
该实现主要涉及到三个脚本:
-
伤害控制脚本:
a、法术被释放时,获得施法者netId;
b、击中目标后,调用角色数据统计脚本,更新并显示数据; -
法术释放脚本:
生成法术,并在生成时将施法者的netId赋给法术的伤害控制脚本保存; -
角色数据统计脚本:
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 ();
}
}
网友评论