Unity Ragdoll 心得+坑点总结

Ragdoll有什么用

煮个栗子:守望先锋的玩家死亡时,会突然全身乏力,尸体的动作十分有趣

而Unity可以用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组件

原文地址:https://www.cnblogs.com/zhxmdefj/p/10764043.html

时间: 2024-10-27 10:43:52

Unity Ragdoll 心得+坑点总结的相关文章

Google Firebase Unity接入的坑

就说跑demo碰到的坑吧 https://firebase.google.com/docs/unity/setup 这是Firebase Unity的setup指南 大概写写步骤: 1. Firebase Console(https://console.firebase.google.com/)里设置好你的api key, 创建好app 2. 下载好GoogleService-Info.plist(IOS),google-services.json(Android),扔进Unity工程目录, 这

Unity AssetBundle 爬坑!!!!!!!

AssetBundle是Unity推荐的资源管理方式,官方列举了诸如热更新,压缩,灵活等等优点,但AssetBundle的坑是非常深的,很多隐藏细节让你使用起来需要十分谨慎,一不小心就会掉入深坑,打包没规划好,20MB的资源"压缩"到了30MB,或者大量的包导致打包以及加载时的各种低效,或者莫名其妙地丢失关联,或者内存爆掉,以及各种加载失败,在网上研究了大量关于AssetBundle的文章,但每次看完之后,还是有不少疑问,所以只能通过实践来解答心中的疑问,为确保结果的准确性,下面的测试

(转)Unity AssetBundle爬坑手记

转自:http://www.cnblogs.com/ybgame/p/3973177.html 这篇文章从AssetBundle的打包,使用,管理以及内存占用各个方面进行了比较全面的分析,对AssetBundle使用过程中的一些坑进行填补指引以及喷! AssetBundle是Unity推荐的资源管理方式,官方列举了诸如热更新,压缩,灵活等等优点,但AssetBundle的坑是非常深的,很多隐藏细节让你使用起来需要十分谨慎,一不小心就会掉入深坑,打包没规划好,20MB的资源“压缩”到了30MB,或

Unity AssetBundle爬坑手记

这篇文章从AssetBundle的打包,使用,管理以及内存占用各个方面进行了比较全面的分析,对AssetBundle使用过程中的一些坑进行填补指引以及喷! AssetBundle是Unity推荐的资源管理方式,官方列举了诸如热更新,压缩,灵活等等优点,但AssetBundle的坑是非常深的,很多隐藏细节让你使用起来需要十分谨慎,一不小心就会掉入深坑,打包没规划好,20MB的资源“压缩”到了30MB,或者大量的包导致打包以及加载时的各种低效,或者莫名其妙地丢失关联,或者内存爆掉,以及各种加载失败,

Unity 开发心得(1)

C#与JS用于unity开发的区别: C#中定义函数必须声明函数类型(void等),但是JS中可以未知函数类型直接定义(function) 注意 C#脚本在Rect前有个new JS脚本没有. 例:在unity中创建GUI控件 在unity中使用脚本都需要绑定游戏对象.例如GUI需要绑定在camera对象中才能在Game界面中显示出来.具体的操作是,选中游戏对象(例如camera),点击右边Inspector中的"Add Component"并选择需要绑定的脚本. C#脚本: void

玲珑杯Unity开发心得——开始菜单GUI制作

///////////////2015/08/04////////////// //////////////by xbw///////////////////// /////////////环境  unity 4.6////////// 先看一下效果图 不错吧,,, 来代码 using UnityEngine; using System.Collections; [RequireComponent(typeof(AudioSource))] public class MainMenuGUI :

玲珑杯Unity开发心得——游戏中暂停及积分显示GUI

//////////////////2015/08/04////////////// /////////////////by xbw//////////////////// ////////////////环境  unity 4.6///////// 先看一下效果图, 来两段代码 using UnityEngine; using System.Collections; public class jifencontrol: MonoBehaviour { //This script handles

玲珑杯Unity开发心得——欢迎界面淡出并且转场景

 ///////////2015/08/04/////////// ///////////by xbw///////////////// ///////////环境 unity4.6/////// 直接贴代码了,挂在给主摄像机就好了,其中有个class类直接放在文件夹就好: DisplayTextureFullScreen.. var graphic = TextureGUI(); //(28,23); var GUIColor:Color; function OnGUI() { GUI.c

玲珑杯Unity开发心得——进度条界面(异步加载游戏场景)

/////////////2015/08/04////////////// ////////////by xbw//////////////////// ///////////环境 unity 4.6////////// 先上效果图 还可以吧,先贴一下代码, using UnityEngine; using System.Collections; public class Loading4 : MonoBehaviour { public Texture2D load_write; //进度条底