[Unity3D] 多人游戏中以角色为中心释放冲击波

关键词:SphereCollider,ClientRpc,Command

基本思路:为角色添加Sphere Collider,通过脚本其体积和碰撞事件,实现冲击效果。


Tips:

官网有很好的关于多人游戏的入门教程,非常值得一看:https://unity3d.com/learn/tutorials/s/multiplayer-networking


1 为角色添加额外的碰撞器,Sphere Collider, 勾选isTrigger,center可根据实际模型调整至中心位置。
2 重写OnStartLocalPlayer(),
public class PlayerControl : NetworkBehaviour {
    
    // 启用生成本地角色时,可以修改一些属性值
    public override void OnStartLocalPlayer()
    {
        // 将本地角色改为蓝色,便于区分,默认为白色
        GetComponent<MeshRenderer>().material.color = Color.blue;
        
        // 重设SphereCollider的半径,将其缩小至角色体内
        GetComponent<SphereCollider>().radius = 0.4f;

    }
}
3 冲击波碰撞和特效的实现
public class Spells : NetworkBehaviour {
    
    // [SerializeField] 可以让私有变量在editor中可见,便于测试;
    [SerializeField] private bool m_BombStart = false;
    private SphereCollider m_SphCollider;
    private float maxRadius;
    
    void Start () {
        m_SphCollider = GetComponent<SphereCollider>();
        // maxRadius 用来设置冲击波的最大半径
        maxRadius = m_SphCollider.radius * 10f;
    }
    
    // 法术释放后,控制SphereCollider随时间扩大半径
    // 放在FixedUpdate()中,可以使半径增加的速度,在不同性能的机器上保持一致。
    void FixedUpdate(){
        if(!isLocalPlayer){
            return;
        }
        
        // m_BombStart 用来控制开始和结束
        if(m_BombStart){
            
            if (m_SphCollider.radius < maxRadius) {
                m_SphCollider.radius += 0.2f;
            } else {
                // 半径达到最大后,重置半径,并停止半径继续增加。
                m_SphCollider.radius = 0.4f;
                m_BombStart = false;
            }
            
        }
    }
    
    // 冲击波,在PlayerControl.cs中,通过按钮调用
    public void Bomb(int groupindex){
        // groupindex 区分法术类型,不同类法术设置不同CD,
        if (!CD_Trigger[groupindex]) {
            
            // 下个FixedUpdate Frame开始增加SphereCollider的半径;
            m_BombStart = true;
            // 开启冷却计时;
            CDTrigger(groupindex);
            // 在角色位置,调用施法效果;
            CmdBombEffect(transform.position);
        }
    }
    
    // 冲击波碰撞效果实现
    void OnTriggerEnter(Collider other){
        // if条件确保只有非本地角色,才会受到由本地角色所释放的冲击波法术的影响
        if (other.CompareTag ("Player") && 
            !other.GetComponent<NetworkIdentity> ().isLocalPlayer) {
            // 计算冲击方向
            var bounceDir = other.transform.position - transform.position;
            
            // 直接调用下面这条语句,在多人游戏中不能实现预期效果,
            // 因为本地虽然更改了角色的位置,但服务器端却没有,
            // 因此只会看到角色受力后,被服务器迅速重置到之前的位置,最终只会有一个微小的抖动。
            // other.attachedRigidbody.AddForce (bounceDir * 500f);
            
            // 正确的做法是让服务器,通知所有客户端来执行这个动作
            CmdBomb (bounceDir,other.gameObject);

        }
    }
    // 简单理解,就是向服务器发出一条指令,由服务器来执行 (具体可参考API和开头给出的教程)
    [Command]
    void CmdBomb(Vector3 dir,GameObject other){
        RpcBomb(dir,other);
    }
    
    // 简单理解,就是从服务器发出一条指令,在所有客户端上执行
    [ClientRpc]
    void RpcBomb(Vector3 dir,GameObject other){     
        // 实现角色受到冲击的效果
        other.GetComponent<Rigidbody>().AddForce (dir * 500f);
    }
    
    // 同理,这个是用来触发冲击波特效的,如果不通过服务器给所有客户端发指令,那么只能在本机看到,其他客户端则看不到。
    [Command]
    void CmdBombEffect(Vector3 bombcenter){
        RpcBombEffect(bombcenter);
    }
    
    [ClientRpc]
    void RpcBombEffect(Vector3 bombcenter){     
        // 保存在EffectsManager.Instance.hitEffects中的一个本地粒子效果
        var clone = (GameObject)Instantiate (EffectsManager.Instance.hitEffects[1], bombcenter, Quaternion.identity);
        Destroy (clone,2f);
    }

}
4 实现效果

(蓝色是本机,白色是另一个玩家。画面有点渣,各位看官见谅,不懂美术的程序员,目前只能这样了。。。)


冲击波.gif
Enjoy It!
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容