Ejemplo n.º 1
0
        public GameObject[] MakeOne()
        {
            var transform            = _parrent.transform;
            SkinnedMeshRenderer rend = _parrent.AddComponent <SkinnedMeshRenderer>();

            if (_material != null)
            {
                rend.material = _material;
            }
            rend.updateWhenOffscreen = true;

            var mesh = _meshGenerator.Create(_radius, _length, _boneCount, _restrictFirstBone);

            // Create Bone Transforms and Bind poses
            // One bone at the bottom and one at the top
            GameObject[] bones     = new GameObject[_boneCount];
            Transform[]  bonesT    = new Transform[_boneCount];
            Matrix4x4[]  bindPoses = new Matrix4x4[_boneCount];


            for (int i = 0; i < _boneCount; i++)
            {
                bones[i] = new GameObject("Bone_" + (i + 1).ToString());
            }


            for (int i = 0; i < _boneCount; i++)
            {
                float r = (float)i / (_boneCount - 1);

                var boneT = bones[i].transform;
                bonesT[i]    = boneT;
                boneT.parent = transform;
                // Set the position relative to the parent
                boneT.localRotation = Quaternion.identity;
                boneT.localPosition = new Vector3(0, r * -_length, 0);

                // The bind pose is bone's inverse transformation matrix
                // In this case the matrix we also make this matrix relative to the root
                // So that we can move the root game object around freely
                bindPoses[i] = boneT.worldToLocalMatrix * transform.localToWorldMatrix;
            }



            for (int i = 0; i < _boneCount; i++)
            {
                var bone = bones[i];

                var rigid = bone.AddComponent <Rigidbody>();
                rigid.mass = _massOfBone;

                if (i == 0)
                {
                    rigid.isKinematic = true;
                }
                else
                {
                    float unitHeight = _length / (_boneCount - 1);

                    var collider = bone.AddComponent <CapsuleCollider>();
                    collider.radius = _radius;
                    collider.height = unitHeight;
                    collider.center = new Vector3(0, unitHeight / 2, 0);


                    var joint = bone.AddComponent <ConfigurableJoint>();
                    joint.connectedBody = bones[i - 1].GetComponent <Rigidbody>();

                    joint.projectionMode = JointProjectionMode.PositionAndRotation;

                    joint.xMotion = ConfigurableJointMotion.Locked;
                    joint.yMotion = ConfigurableJointMotion.Locked;
                    joint.zMotion = ConfigurableJointMotion.Locked;

                    if (i != 1 | _restrictFirstBone)
                    {
                        joint.angularXMotion = ConfigurableJointMotion.Limited;
                        joint.angularYMotion = ConfigurableJointMotion.Locked;
                        joint.angularZMotion = ConfigurableJointMotion.Limited;
                    }
                    else
                    {
                        joint.angularXMotion = ConfigurableJointMotion.Free;
                        joint.angularYMotion = ConfigurableJointMotion.Free;
                        joint.angularZMotion = ConfigurableJointMotion.Free;
                    }

                    joint.autoConfigureConnectedAnchor = false;
                    joint.connectedAnchor = new Vector3(0, 0, 0);
                    joint.anchor          = new Vector3(0, unitHeight, 0);

                    var xLowLimits = joint.lowAngularXLimit;
                    xLowLimits.limit       = -_jointAngleLimit;
                    joint.lowAngularXLimit = xLowLimits;

                    var xHighLimits = joint.highAngularXLimit;
                    xHighLimits.limit       = _jointAngleLimit;
                    joint.highAngularXLimit = xHighLimits;

                    var zLimits = joint.angularZLimit;
                    zLimits.limit       = _jointAngleLimit;
                    joint.angularZLimit = zLimits;
                }
            }



            // assign the bindPoses array to the bindposes array which is part of the mesh.
            mesh.bindposes = bindPoses;

            // Assign bones and bind poses
            rend.bones      = bonesT;
            rend.sharedMesh = mesh;

            return(bones);
        }
Ejemplo n.º 2
0
        public RopeGenerationResult MakeOne()
        {
            var transform            = _parrent.transform;
            SkinnedMeshRenderer rend = _parrent.AddComponent <SkinnedMeshRenderer>();

            rend.updateWhenOffscreen = true;

            MeshGenerationResult result = _meshGenerator.Create(_colliderRadius, _length, _boneCount, _restrictFirstBone);

            if (result.materials != null)
            {
                rend.materials = result.materials;
            }
            Mesh mesh = result.mesh;

            // Create Bone Transforms and Bind poses
            // One bone at the bottom and one at the top
            GameObject[] bones     = new GameObject[_boneCount];
            Transform[]  bonesT    = new Transform[_boneCount];
            Matrix4x4[]  bindPoses = new Matrix4x4[_boneCount];


            for (int i = 0; i < _boneCount; i++)
            {
                bones[i] = new GameObject("Bone_" + (i + 1).ToString());
            }


            for (int i = 0; i < _boneCount; i++)
            {
                float r = (float)i / (_boneCount - 1);

                var boneT = bones[i].transform;
                bonesT[i]    = boneT;
                boneT.parent = transform;
                // Set the position relative to the parent
                boneT.localRotation = Quaternion.identity;
                boneT.localPosition = new Vector3(r * _length, 0, 0);

                // The bind pose is bone's inverse transformation matrix
                // In this case the matrix we also make this matrix relative to the root
                // So that we can move the root game object around freely
                bindPoses[i] = boneT.worldToLocalMatrix * transform.localToWorldMatrix;
            }



            for (int i = 0; i < _boneCount; i++)
            {
                var bone = bones[i];

                var rigid = bone.AddComponent <Rigidbody>();
                rigid.mass = _massOfBone;

                if (i == 0)
                {
                    rigid.isKinematic = true;
                }
                else
                {
                    float unitHeight = _length / (_boneCount - 1);

                    var collider = bone.AddComponent <CapsuleCollider>();
                    collider.radius    = _colliderRadius;
                    collider.height    = unitHeight;
                    collider.center    = new Vector3(-unitHeight / 2, 0, 0);
                    collider.direction = 0;


                    var joint = bone.AddComponent <ConfigurableJoint>();
                    joint.connectedBody = bones[i - 1].GetComponent <Rigidbody>();

                    joint.projectionMode = JointProjectionMode.PositionAndRotation;

                    joint.xMotion = ConfigurableJointMotion.Locked;
                    joint.yMotion = ConfigurableJointMotion.Locked;
                    joint.zMotion = ConfigurableJointMotion.Locked;

                    bool firstBoneRistrict = i != 1 | _restrictFirstBone;
                    if (firstBoneRistrict & _jointAngleLimit > 0f)
                    {
                        joint.angularYMotion = ConfigurableJointMotion.Limited;
                        joint.angularZMotion = ConfigurableJointMotion.Limited;
                    }
                    else
                    {
                        joint.angularYMotion = ConfigurableJointMotion.Free;
                        joint.angularZMotion = ConfigurableJointMotion.Free;
                    }

                    if (firstBoneRistrict & _rotateAngleLimit > 0f)
                    {
                        joint.angularXMotion = ConfigurableJointMotion.Limited;
                    }
                    else
                    {
                        joint.angularXMotion = ConfigurableJointMotion.Free;
                    }

                    joint.angularXLimitSpring = new SoftJointLimitSpring
                    {
                        spring = 1000f,
                        damper = 100f,
                    };

                    joint.autoConfigureConnectedAnchor = false;
                    joint.connectedAnchor = new Vector3(0, 0, 0);
                    joint.anchor          = new Vector3(-unitHeight, 0, 0);

                    var xLowLimits = joint.lowAngularXLimit;
                    xLowLimits.limit       = -_rotateAngleLimit;
                    joint.lowAngularXLimit = xLowLimits;

                    var xHighLimits = joint.highAngularXLimit;
                    xHighLimits.limit       = _rotateAngleLimit;
                    joint.highAngularXLimit = xHighLimits;

                    var zLimits = joint.angularZLimit;
                    zLimits.limit       = _jointAngleLimit;
                    joint.angularZLimit = zLimits;

                    var yLimits = joint.angularYLimit;
                    yLimits.limit       = _jointAngleLimit;
                    joint.angularYLimit = yLimits;

                    var   angularDrive = new JointDrive();
                    float psr          = (float)(i - 1) / (_boneCount - 2);
                    angularDrive.positionSpring = Mathf.Lerp(_angularDriveSpringStart, _angularDriveSpringStop, psr);
                    angularDrive.maximumForce   = float.MaxValue;
                    joint.slerpDrive            = angularDrive;
                    joint.rotationDriveMode     = RotationDriveMode.Slerp;
                }
            }

            // assign the bindPoses array to the bindposes array which is part of the mesh.
            mesh.bindposes = bindPoses;

            // Assign bones and bind poses
            rend.bones      = bonesT;
            rend.sharedMesh = mesh;

            return(new RopeGenerationResult
            {
                Mesh = mesh,
                Bones = bones,
            });
        }