zoukankan      html  css  js  c++  java
  • Unity Ragdoll 实现死亡效果 心得+坑点总结

    效果展示

    正如其名,Ragdoll可以让人物模型实现像布娃娃一样物理效果

    创建Ragdoll

    在场景中新建 3D Object → Ragdoll...

    接下来是一个初见复杂的绑定界面,这里我做了简单翻译

    我们需要将模型对应的关节部位一一拉进这个表

    创建完成后,可以发现模型中的每个所选部位中多了一个Rigibody,一个Collider和一个Character Joint组件,在Joint面板里可以调节转动限制等

    这里要注意的一个坑点是,root节点是没有Character Joint的,当你找不到root节点时,没有Character Joint但是添加了Box Collider和Rigibody的就是root节点

    root节点应在这个位置,不熟悉朋友有可能将盆骨附近Pelvis 与 胸部附近Middle Spine的两个Collider互换位置,或者重叠,这将导致整个人物的抽搐,蒙皮拉伸

    调整四肢Collider大小位置,如下:

    通过代码控制

    如果我需要的效果是:

    1. 让角色存活(isDead = false)时:每个部位的Rigibody的isKinematic一直为true,每个部位的Collider的isTrigger也为true
    2. 角色死亡(isDead = true)时:每个部位的Rigibody的isKinematic变为false,每个部位的Collider的isTrigger也变为false,同时,必须将角色的Animation组件去除

    代码

    我的做法是使用GetComponentsInChildren函数获得所有刚体,再通过每个刚体获取这个部位上的Collider,用两个List将他们存储起来。就可以方便的设置isKinematic和isTrigger

    同时在死亡的下一帧用协程关闭动画组件,(如果想让角色复活,Anmiaton组件的enable属性设置为true即可)

    完整代码如下:

    	public List<Rigidbody> ragdollRigidbodys = new List<Rigidbody>();
        public List<Collider> ragdollColliders = new List<Collider>();
    
    	void InitRagdoll() {
    
            Rigidbody[] _rigidbodys = GetComponentsInChildren<Rigidbody>();
    
            for (int i = 0; i < _rigidbodys.Length; i++) {
                if (_rigidbodys[i] == rigidbody)
                    continue;
                ragdollRigidbodys.Add(_rigidbodys[i]);
                _rigidbodys[i].isKinematic = true;
    
                Collider _collider = _rigidbodys[i].gameObject.GetComponent<Collider>();
                _collider.isTrigger = true;
                ragdollColliders.Add(_collider);
    
            }
        }
    
        void EnableRagdoll() {
            for (int i = 0; i < ragdollRigidbodys.Count; i++) {
                ragdollRigidbodys[i].isKinematic = false;
                ragdollColliders[i].isTrigger = false;
            }
    
            Collider collidercontroller = rigidbody.gameObject.GetComponent<Collider>();
            collidercontroller.enabled = false;
            rigidbody.isKinematic = true;
    
            StartCoroutine(CloseAnimator());
        }
    
        IEnumerator CloseAnimator() {
            yield return new WaitForEndOfFrame();
            animator.enabled = false;
            this.enabled = false;
        }
    

    最终效果就是这样了,死亡之后的布娃娃状态真的很有意思

    坑点总结

    第一帧蒙皮拉伸,撕裂

    Play之后的第一帧(先点暂停再Play可查看第一帧)可能出现角色关节撕裂,Play之后角色乱动

    解决方案:

    • 检查pelvis和middle spine是否混淆,root节点设置错误(root节点是有刚体,有碰撞器没有Character Joint

    • 检查两个部位的collider是否产生重叠

    死亡后蒙皮拉伸,撕裂

    解决方案:

    可以尝试勾选Character Joint组建的Enable Projection选项

    死亡后布娃娃不生效

    解决方案

    检查是否有关Animator组件

  • 相关阅读:
    团队作业---软件制作8
    团队作业---软件制作7
    团队绩效考核表
    团队报告
    团队作业---软件制作6
    团队作业---软件制作5
    团队作业---软件制作4
    团队作业---软件制作3
    团队作业---软件制作2
    第十周学习进度条
  • 原文地址:https://www.cnblogs.com/zhxmdefj/p/10764043.html
Copyright © 2011-2022 走看看