[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閱讀 230,106評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,441評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,211評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,736評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,475評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,834評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,829評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,009評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,559評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,306評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,516評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,038評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,728評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,132評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,443評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,249評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,484評論 2 379

推薦閱讀更多精彩內容