美文网首页unity征服Unity3dunity3D技术分享
[Unity3D] 多人游戏中以角色为中心释放冲击波

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

作者: 薯條 | 来源:发表于2017-11-10 16:26 被阅读112次

    关键词: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!

    相关文章

      网友评论

        本文标题:[Unity3D] 多人游戏中以角色为中心释放冲击波

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