예제 #1
0
 /// <summary>
 /// Ragdoll character
 /// </summary>
 private void RagdollIn()
 {
     ActivateRagdollParts(true);
     animator.enabled = false;
     ragdollState     = RagdollState.Ragdolled;
     ApplyVelocity(controller.GetVelocity());
 }
예제 #2
0
 /// <summary>
 /// Smoothly translate to animator's bone positions when character stops falling
 /// </summary>
 private void RagdollOut()
 {
     if (_state == RagdollState.Ragdolled)
     {
         _state = RagdollState.WaitStablePosition;
     }
 }
    // Unity method for physics update.
    void FixedUpdate()
    {
        // Apply animation following
        animFollow.FollowAnimation();

        // print(currentNumberOfCollisions);
        // print(animFollow.forceCoefficient);

        state = GetRagdollState();
        switch (state)
        {
        case RagdollState.DEAD:
            currentDeadStep += Time.fixedDeltaTime;
            if (currentDeadStep >= deadTime)
            {
                ComeAlive();
            }
            break;

        case RagdollState.LOOSING_STRENGTH:
            LooseStrength();
            break;

        case RagdollState.GAINING_STRENGTH:
            GainStrength();
            break;

        case RagdollState.FOLLOWING_ANIMATION:
            break;

        default:
            break;
        }
    }
예제 #4
0
        public void StartMecanim()
        {   // if we're not in a ragdoll state
            if (state != RagdollState.ragdolled)
            {   // no need to transition to mecanim
                return;
            }
            //Transition from ragdolled to animated through the blendToAnim state
            setKinematic(true); //disable gravity etc.
            ragdollingEndTime = Time.time; //store the state change time
            animator.enabled = true; //enable animation
            state = RagdollState.blendToAnim;  

            //Store the ragdolled position for blending
            foreach (BodyPart b in bodyParts)
            {
                b.storedRotation = b.transform.rotation;
                b.storedPosition = b.transform.position;
            }

            //Remember some key positions
            ragdolledFeetPosition = 0.5f * (animator.GetBoneTransform(HumanBodyBones.LeftToes).position + animator.GetBoneTransform(HumanBodyBones.RightToes).position);
            ragdolledHeadPosition = animator.GetBoneTransform(HumanBodyBones.Head).position;
            ragdolledHipPosition = animator.GetBoneTransform(HumanBodyBones.Hips).position;

        }
예제 #5
0
        public void StartRagdoll()
        {   
            // if we're not in an animation state
            if (state != RagdollState.animated)
            {   // no need to transition to ragdoll
                return;
            }
            //Transition from animated to ragdolled
            setKinematic(false); //allow the ragdoll RigidBodies to react to the environment

            animator.enabled = false; //disable animation

            // turn off NavMeshAgent if it exists
            if (GetComponent<NavMeshAgent>() != null) {
                GetComponent<NavMeshAgent>().enabled = false; // disable navigation agent
            }

            // turn off CapsuleCollider if it exists
            if (GetComponent<CapsuleCollider>() != null && GetComponent<CapsuleCollider>().enabled)
            {
                GetComponent<CapsuleCollider>().enabled = false;
            }

            // turn off CapsuleCollider if it exists
            if (GetComponent<Rigidbody>() != null)
            {
                GetComponent<Rigidbody>().isKinematic = true;
            }

            state = RagdollState.ragdolled;

        }
예제 #6
0
        private void GetUp()
        {
            ragdollingEndTime           = Time.time;
            animator.enabled            = true;
            ragdollState                = RagdollState.BlendToAnim;
            storedHipsPositionPrivAnim  = Vector3.zero;
            storedHipsPositionPrivBlend = Vector3.zero;

            storedHipsPosition = hipsTransform.position;

            Vector3 shiftPos = hipsTransform.position - transform.position;

            shiftPos.y = GetDistanceToFloor(shiftPos.y);

            MoveNodeWithoutChildren(shiftPos);

            for (int i = 0; i < transformComponents.Count; i++)
            {
                TransformComponent tc = transformComponents[i];
                tc.SetStoredRotation(tc.GetTransform().localRotation);
                tc.SetRotation(tc.GetTransform().localRotation);

                tc.SetStoredPosition(tc.GetTransform().localPosition);
                tc.SetPosition(tc.GetTransform().localPosition);
            }

            string getUpAnim = CheckIfLieOnBack() ? animationGetUpFromBack : animationGetUpFromBelly;

            animator.Play(getUpAnim, 0, 0);
            ActivateRagdollParts(false);
        }
    void LateUpdate()
    {
        if (_state == RagdollState.Blending)
        {
            if (Time.time <= _ragdollEndTime + _toGetUpTransitionTime)
            {
                //If we are waiting for Mecanim to start playing the get up animations, update the root of the mecanim
                //character to the best match with the ragdoll
                Vector3 animatedToRagdolled = _ragdolledHipPosition - _animController.GetBoneTransform(HumanBodyBones.Hips).position;
                Vector3 newRootPosition     = transform.position + animatedToRagdolled;

                //Now cast a ray from the computed position downwards and find the highest hit that does not belong to the character
                RaycastHit[] hits = Physics.RaycastAll(new Ray(newRootPosition, Vector3.down));
                newRootPosition.y = 0;
                foreach (RaycastHit hit in hits)
                {
                    if (!hit.transform.IsChildOf(transform))
                    {
                        newRootPosition.y = Mathf.Max(newRootPosition.y, hit.point.y);
                    }
                }
                transform.position = newRootPosition;

                //Get body orientation in ground plane for both the ragdolled pose and the animated get up pose
                Vector3 ragdolledDirection = _ragdolledHeadPosition - _ragdolledFeetPosition;
                ragdolledDirection.y = 0;

                Vector3 meanFeetPosition  = 0.5f * (_animController.GetBoneTransform(HumanBodyBones.LeftFoot).position + _animController.GetBoneTransform(HumanBodyBones.RightFoot).position);
                Vector3 animatedDirection = _animController.GetBoneTransform(HumanBodyBones.Head).position - meanFeetPosition;
                animatedDirection.y = 0;

                //Try to match the rotations. Note that we can only rotate around Y axis, as the animated characted must stay upright,
                //hence setting the y components of the vectors to zero.
                transform.rotation *= Quaternion.FromToRotation(animatedDirection.normalized, ragdolledDirection.normalized);
            }


            float blend = Mathf.Clamp01(1.0f - (Time.time - _ragdollEndTime - _toGetUpTransitionTime) / BlendTime);
            foreach (var l in _limbs)
            {
                if (l.Transform != transform)   //this if is to prevent us from modifying the root of the character, only the actual body parts
                //position is only interpolated for the hips
                {
                    if (l.Transform == _animController.GetBoneTransform(HumanBodyBones.Hips))
                    {
                        l.Transform.position = Vector3.Lerp(l.Transform.position, l.Position, blend);
                    }
                    //rotation is interpolated for all body parts
                    l.Transform.rotation = Quaternion.Slerp(l.Transform.rotation, l.Rotation, blend);
                }
            }

            //if the ragdoll blend amount has decreased to zero, move to animated state
            if (blend == 0)
            {
                _state = RagdollState.Animated;
                return;
            }
        }
    }
예제 #8
0
        void TransitionToAnimator()
        {

            if (Time.time <= ragdollingEndTime + mecanimToGetUpTransitionTime)
            {
                //If we are waiting for Mecanim to start playing the get up animations, update the root of the mecanim
                //character to the best match with the ragdoll
                Vector3 animatedToRagdolled = ragdolledHipPosition - animator.GetBoneTransform(HumanBodyBones.Hips).position;
                Vector3 newRootPosition = transform.position + animatedToRagdolled;

                //Now cast a ray from the computed position downwards and find the highest hit that does not belong to the character 
                RaycastHit[] hits = Physics.RaycastAll(new Ray(newRootPosition, Vector3.down)); 
                newRootPosition.y = 0;
                foreach (RaycastHit hit in hits)
                {
                    if (!hit.transform.IsChildOf(transform))
                    {
                        newRootPosition.y = Mathf.Max(newRootPosition.y, hit.point.y);
                    }
                }
                transform.position = newRootPosition;

                //Get body orientation in ground plane for both the ragdolled pose and the animated get up pose
                Vector3 ragdolledDirection = ragdolledHeadPosition - ragdolledFeetPosition;
                ragdolledDirection.y = 0;

                Vector3 meanFeetPosition = 0.5f * (animator.GetBoneTransform(HumanBodyBones.LeftFoot).position + animator.GetBoneTransform(HumanBodyBones.RightFoot).position);
                Vector3 animatedDirection = animator.GetBoneTransform(HumanBodyBones.Head).position - meanFeetPosition;
                animatedDirection.y = 0;

                //Try to match the rotations. Note that we can only rotate around Y axis, as the animated characted must stay upright,
                //hence setting the y components of the vectors to zero. 
                transform.rotation *= Quaternion.FromToRotation(animatedDirection.normalized, ragdolledDirection.normalized);
            }
            //compute the ragdoll blend amount in the range 0...1
            float ragdollBlendAmount = 1.0f - (Time.time - ragdollingEndTime - mecanimToGetUpTransitionTime) / ragdollToMecanimBlendTime;
            ragdollBlendAmount = Mathf.Clamp01(ragdollBlendAmount);

            //In LateUpdate(), Mecanim has already updated the body pose according to the animations. 
            //To enable smooth transitioning from a ragdoll to animation, we lerp the position of the hips 
            //and slerp all the rotations towards the ones stored when ending the ragdolling
            foreach (BodyPart b in bodyParts)
            {
                if (b.transform != transform)
                { //this if is to prevent us from modifying the root of the character, only the actual body parts
                    //position is only interpolated for the hips
                    if (b.transform == animator.GetBoneTransform(HumanBodyBones.Hips))
                        b.transform.position = Vector3.Lerp(b.transform.position, b.storedPosition, ragdollBlendAmount);
                    //rotation is interpolated for all body parts
                    b.transform.rotation = Quaternion.Slerp(b.transform.rotation, b.storedRotation, ragdollBlendAmount);
                }
            }

            //if the ragdoll blend amount has decreased to zero, move to animated state
            if (ragdollBlendAmount == 0)
            {
                state = RagdollState.animated;
            }
        }
예제 #9
0
        /// <summary>
        /// Ragdoll character
        /// </summary>
        private void RagdollIn()
        {
            //Transition from animated to ragdolled

            ActivateRagdollParts(true);             // allow the ragdoll RigidBodies to react to the environment
            _anim.enabled = false;                  // disable animation
            _state        = RagdollState.Ragdolled;
            ApplyVelocity(_bzRagdollCharacter.CharacterVelocity);
        }
예제 #10
0
 public void changeState(RagdollState newState)
 {
     lock (stateLock)
     {
         if (rState != newState)
         {
             rState = newState;
         }
     }
 }
예제 #11
0
        void LateUpdate()
        {
            anim.SetBool("GetUpFromBelly", false);
            anim.SetBool("GetUpFromBack", false);

            if (state == RagdollState.blendToAnim)
            {
                if (Time.time <= ragdollingEndTime + mecanimToGetUpTransitionTime)
                {
                    Vector3 animatedToRagdolled = ragdolledHipPosition - anim.GetBoneTransform(HumanBodyBones.Hips).position;
                    Vector3 newRootPosition     = transform.position + animatedToRagdolled;

                    RaycastHit[] hits = Physics.RaycastAll(new Ray(newRootPosition, Vector3.down));
                    newRootPosition.y = 0;
                    foreach (RaycastHit hit in hits)
                    {
                        if (!hit.transform.IsChildOf(transform))
                        {
                            newRootPosition.y = Mathf.Max(newRootPosition.y, hit.point.y);
                        }
                    }
                    transform.position = newRootPosition;

                    Vector3 ragdolledDirection = ragdolledHeadPosition - ragdolledFeetPosition;
                    ragdolledDirection.y = 0;

                    Vector3 meanFeetPosition  = 0.5f * (anim.GetBoneTransform(HumanBodyBones.LeftFoot).position + anim.GetBoneTransform(HumanBodyBones.RightFoot).position);
                    Vector3 animatedDirection = anim.GetBoneTransform(HumanBodyBones.Head).position - meanFeetPosition;
                    animatedDirection.y = 0;

                    transform.rotation *= Quaternion.FromToRotation(animatedDirection.normalized, ragdolledDirection.normalized);
                }
                float ragdollBlendAmount = 1.0f - (Time.time - ragdollingEndTime - mecanimToGetUpTransitionTime) / ragdollToMecanimBlendTime;
                ragdollBlendAmount = Mathf.Clamp01(ragdollBlendAmount);

                foreach (BodyPart b in bodyParts)
                {
                    if (b.transform != transform)
                    {
                        if (b.transform == anim.GetBoneTransform(HumanBodyBones.Hips))
                        {
                            b.transform.position = Vector3.Lerp(b.transform.position, b.storedPosition, ragdollBlendAmount);
                        }
                        b.transform.rotation = Quaternion.Slerp(b.transform.rotation, b.storedRotation, ragdollBlendAmount);
                    }
                }

                if (ragdollBlendAmount == 0)
                {
                    state = RagdollState.animated;
                    return;
                }
            }
        }
예제 #12
0
    public void FullRagdoll()
    {
        rState = RagdollState.Ragdoll;

        animationRate  = animationRange.min;       //animationRange.min;
        maxJointSpring = jointSpringRange.min;

        follow = false;
        force  = false;
        torque = false;
    }
예제 #13
0
    public void FullAnimated()
    {
        rState = RagdollState.Animated;

        animationRate  = animationRange.max;
        maxJointSpring = jointSpringRange.max;

        follow = true;
        force  = true;
        torque = true;
    }
예제 #14
0
        void LateUpdate()
        {
            if (_state != RagdollState.BlendToAnim)
            {
                return;
            }

            float ragdollBlendAmount = 1f - Mathf.InverseLerp(
                _ragdollingEndTime,
                _ragdollingEndTime + RagdollToMecanimBlendTime,
                Time.time);

            // In LateUpdate(), Mecanim has already updated the body pose according to the animations.
            // To enable smooth transitioning from a ragdoll to animation, we lerp the position of the hips
            // and slerp all the rotations towards the ones stored when ending the ragdolling

            if (_storedHipsPositionPrivBlend != _hipsTransform.position)
            {
                _storedHipsPositionPrivAnim = _hipsTransform.position;
            }

            _storedHipsPositionPrivBlend =
                Vector3.Lerp(_storedHipsPositionPrivAnim, _storedHipsPosition, ragdollBlendAmount);
            _hipsTransform.position = _storedHipsPositionPrivBlend;

            foreach (TransformComponent trComp in _transforms)
            {
                //rotation is interpolated for all body parts
                if (trComp.PrivRotation != trComp.Transform.localRotation)
                {
                    trComp.PrivRotation = Quaternion.Slerp(trComp.Transform.localRotation, trComp.StoredRotation,
                                                           ragdollBlendAmount);
                    trComp.Transform.localRotation = trComp.PrivRotation;
                }

                //position is interpolated for all body parts
                if (trComp.PrivPosition != trComp.Transform.localPosition)
                {
                    trComp.PrivPosition = Vector3.Slerp(trComp.Transform.localPosition, trComp.StoredPosition,
                                                        ragdollBlendAmount);
                    trComp.Transform.localPosition = trComp.PrivPosition;
                }
            }

            //if the ragdoll blend amount has decreased to zero, move to animated state
            if (Mathf.Abs(ragdollBlendAmount) < Mathf.Epsilon)
            {
                _state = RagdollState.Animated;
            }
        }
예제 #15
0
        /// <summary>
        /// LateUpdate is called after all Update functions have been called.
        /// </summary>
        private void LateUpdate()
        {
            if (ragdollState != RagdollState.BlendToAnim)
            {
                return;
            }

            float ragdollBlendAmount = 1f - Mathf.InverseLerp(
                ragdollingEndTime,
                ragdollingEndTime + RAGDOLL_TO_MECANIM_BLEND_TIME,
                Time.time);

            if (storedHipsPositionPrivBlend != hipsTransform.position)
            {
                storedHipsPositionPrivAnim = hipsTransform.position;
            }
            storedHipsPositionPrivBlend = Vector3.Lerp(storedHipsPositionPrivAnim, storedHipsPosition, ragdollBlendAmount);
            hipsTransform.position      = storedHipsPositionPrivBlend;

            for (int i = 0; i < transformComponents.Count; i++)
            {
                TransformComponent tc = transformComponents[i];
                if (tc.GetRotation() != tc.GetTransform().localRotation)
                {
                    tc.SetRotation(Quaternion.Slerp(tc.GetTransform().localRotation, tc.GetStoredRotation(), ragdollBlendAmount));
                    tc.GetTransform().localRotation = tc.GetRotation();
                }

                if (tc.GetPosition() != tc.GetTransform().localPosition)
                {
                    tc.SetPosition(Vector3.Slerp(tc.GetTransform().localPosition, tc.GetStoredPosition(), ragdollBlendAmount));
                    tc.GetTransform().localPosition = tc.GetPosition();
                }
            }

            if (Mathf.Abs(ragdollBlendAmount) < Mathf.Epsilon)
            {
                ragdollState = RagdollState.Animated;
            }
        }
예제 #16
0
        private void GetUp()
        {
            //Transition from ragdolled to animated through the blendToAnim state
            _ragdollingEndTime = Time.time; //store the state change time
            //_anim.SetFloat(_animatorForward, 0f);
            //_anim.SetFloat(_animatorTurn, 0f);
            _anim.enabled = true; //enable animation
            _state        = RagdollState.BlendToAnim;
            _storedHipsPositionPrivAnim  = Vector3.zero;
            _storedHipsPositionPrivBlend = Vector3.zero;

            _storedHipsPosition = _hipsTransform.position;

            // get distanse to floor
            Vector3 shiftPos = _hipsTransform.position - transform.position;

            shiftPos.y = GetDistanceToFloor(shiftPos.y);

            // shift and rotate character node without children
            MoveNodeWithoutChildren(shiftPos);

            //Store the ragdolled position for blending
            foreach (TransformComponent trComp in _transforms)
            {
                trComp.StoredRotation = trComp.Transform.localRotation;
                trComp.PrivRotation   = trComp.Transform.localRotation;

                trComp.StoredPosition = trComp.Transform.localPosition;
                trComp.PrivPosition   = trComp.Transform.localPosition;
            }

            //Initiate the get up animation
            string getUpAnim = CheckIfLieOnBack() ? _animationGetUpFromBack : _animationGetUpFromBelly;

            _anim.Play(getUpAnim, 0,
                       0);               // you have to set time to 0, or if your animation will interrupt, next time animation starts from previous position
            ActivateRagdollParts(false); // disable gravity on ragdollParts.
        }
예제 #17
0
	void LateUpdate()
	{
		//check for errors in state
		if(anim == null)
		{
			state = RagdollState.ragdolled;
			
			
		}
		
		
		//check if we're currently in the state that we should be
		if(state == RagdollState.ragdolled && GetComponent<RagdollTransitions>().boneParent.collider.enabled == false)
		{
			//set to ragdoll again
			GetComponent<RagdollTransitions>().boneParent.SetActive(true);
			setKinematic(false); //allow the ragdoll RigidBodies to react to the environment
		}
		
		//get back to our parents position and rotation
		transform.position = Vector3.Lerp( transform.position, transform.parent.position, 0.5f );
		transform.rotation = Quaternion.Lerp( transform.rotation, transform.parent.rotation, 0.1f);
		
		
		if(anim == null)
		{
			return;
		}
		
		
		//Clear the get up animation controls so that we don't end up repeating the animations indefinitely
		anim.SetBool("GetUpFromBelly",false);
		anim.SetBool("GetUpFromBack",false);

		//Blending from ragdoll back to animated
		if (state==RagdollState.blendToAnim)
		{
			if (Time.time<=ragdollingEndTime+mecanimToGetUpTransitionTime)
			{
				//If we are waiting for Mecanim to start playing the get up animations, update the root of the mecanim
				//character to the best match with the ragdoll
				Vector3 animatedToRagdolled=ragdolledHipPosition-anim.GetBoneTransform(HumanBodyBones.Hips).position;
				Vector3 newRootPosition=transform.position + animatedToRagdolled;
					
				//Now cast a ray from the computed position downwards and find the highest hit that does not belong to the character 
				RaycastHit[] hits=Physics.RaycastAll(new Ray(newRootPosition,Vector3.down)); 
				newRootPosition.y=0;
				foreach(RaycastHit hit in hits)
				{
					if (!hit.transform.IsChildOf(transform))
					{
						newRootPosition.y=Mathf.Max(newRootPosition.y, hit.point.y);
					}
				}
				transform.position=newRootPosition;
				
				//Get body orientation in ground plane for both the ragdolled pose and the animated get up pose
				Vector3 ragdolledDirection=ragdolledHeadPosition-ragdolledFeetPosition;
				ragdolledDirection.y=0;

				Vector3 meanFeetPosition=0.5f*(anim.GetBoneTransform(HumanBodyBones.LeftFoot).position + anim.GetBoneTransform(HumanBodyBones.RightFoot).position);
				Vector3 animatedDirection=anim.GetBoneTransform(HumanBodyBones.Head).position - meanFeetPosition;
				animatedDirection.y=0;
										
				//Try to match the rotations. Note that we can only rotate around Y axis, as the animated characted must stay upright,
				//hence setting the y components of the vectors to zero. 
				transform.rotation*=Quaternion.FromToRotation(animatedDirection.normalized,ragdolledDirection.normalized);
			}
			//compute the ragdoll blend amount in the range 0...1
			float ragdollBlendAmount=1.0f-(Time.time-ragdollingEndTime-mecanimToGetUpTransitionTime)/ragdollToMecanimBlendTime;
			ragdollBlendAmount=Mathf.Clamp01(ragdollBlendAmount);
			
			//In LateUpdate(), Mecanim has already updated the body pose according to the animations. 
			//To enable smooth transitioning from a ragdoll to animation, we lerp the position of the hips 
			//and slerp all the rotations towards the ones stored when ending the ragdolling
			foreach (BodyPart b in bodyParts)
			{
				if (b.transform!=transform){ //this if is to prevent us from modifying the root of the character, only the actual body parts
					//position is only interpolated for the hips
					if (b.transform==anim.GetBoneTransform(HumanBodyBones.Hips))
						b.transform.position=Vector3.Lerp(b.transform.position, b.storedPosition, ragdollBlendAmount);
					//rotation is interpolated for all body parts
					b.transform.rotation=Quaternion.Slerp(b.transform.rotation, b.storedRotation, ragdollBlendAmount);
				}
			}
			
			
			
			
			
			//if the ragdoll blend amount has decreased to zero, move to animated state
			if (ragdollBlendAmount==0)
			{
				state=RagdollState.animated;
				return;
			}
		}
	}
예제 #18
0
    void LateUpdate()
    {
        if (animator.GetCurrentAnimatorStateInfo (2).IsName ("StandUp@FromBack"))
        {
            if (animator.GetCurrentAnimatorStateInfo (2).normalizedTime > 0.1f)
            {
                tpController._rigidbody.useGravity = true;
                tpController._rigidbody.isKinematic = false;
                tpController.capsuleCollider.enabled = true;
            }
            if (animator.GetCurrentAnimatorStateInfo (2).normalizedTime > 0.9f)
                animator.SetBool("GetUpFromBack",false);
        }
        if (animator.GetCurrentAnimatorStateInfo (2).IsName ("StandUp@FromBelly"))
        {
            if (animator.GetCurrentAnimatorStateInfo (2).normalizedTime > 0.1f)
            {
                tpController._rigidbody.useGravity = true;
                tpController._rigidbody.isKinematic = false;
                tpController.capsuleCollider.enabled = true;
            }
            if (animator.GetCurrentAnimatorStateInfo (2).normalizedTime > 0.9f)
                animator.SetBool("GetUpFromBelly",false);
        }

        //Blending from ragdoll back to animated
        if (state == RagdollState.blendToAnim)
        {
            if (Time.time <= ragdollingEndTime + mecanimToGetUpTransitionTime)
            {
                //If we are waiting for Mecanim to start playing the get up animations, update the root of the mecanim
                //character to the best match with the ragdoll
                Vector3 animatedToRagdolled = ragdolledHipPosition - animator.GetBoneTransform(HumanBodyBones.Hips).position;
                Vector3 newRootPosition = transform.position + animatedToRagdolled;

                //Now cast a ray from the computed position downwards and find the highest hit that does not belong to the character
                RaycastHit[] hits = Physics.RaycastAll(new Ray(newRootPosition + Vector3.up,Vector3.down));
                newRootPosition.y = 0;
                foreach(RaycastHit hit in hits)
                {
                    if (!hit.transform.IsChildOf(transform))
                    {
                        newRootPosition.y = Mathf.Max(newRootPosition.y, hit.point.y);
                    }
                }
                transform.position = newRootPosition;

                //Get body orientation in ground plane for both the ragdolled pose and the animated get up pose
                Vector3 ragdolledDirection = ragdolledHeadPosition - ragdolledFeetPosition;
                ragdolledDirection.y = 0;

                Vector3 meanFeetPosition = 0.5f * (animator.GetBoneTransform(HumanBodyBones.LeftFoot).position + animator.GetBoneTransform(HumanBodyBones.RightFoot).position);
                Vector3 animatedDirection = animator.GetBoneTransform(HumanBodyBones.Head).position - meanFeetPosition;
                animatedDirection.y = 0;

                //Try to match the rotations. Note that we can only rotate around Y axis, as the animated characted must stay upright,
                //hence setting the y components of the vectors to zero.
                transform.rotation *= Quaternion.FromToRotation(animatedDirection.normalized,ragdolledDirection.normalized);
            }
            //compute the ragdoll blend amount in the range 0...1
            float ragdollBlendAmount = 1.0f - (Time.time - ragdollingEndTime - mecanimToGetUpTransitionTime)/ragdollToMecanimBlendTime;
            ragdollBlendAmount = Mathf.Clamp01(ragdollBlendAmount);

            //In LateUpdate(), Mecanim has already updated the body pose according to the animations.
            //To enable smooth transitioning from a ragdoll to animation, we lerp the position of the hips
            //and slerp all the rotations towards the ones stored when ending the ragdolling
            foreach (BodyPart b in bodyParts)
            {
                if (b.transform!=transform)
                { //this if is to prevent us from modifying the root of the character, only the actual body parts
                    //position is only interpolated for the hips
                    if (b.transform == animator.GetBoneTransform(HumanBodyBones.Hips))
                        b.transform.position = Vector3.Lerp(b.transform.position, b.storedPosition, ragdollBlendAmount);
                    //rotation is interpolated for all body parts
                    b.transform.rotation = Quaternion.Slerp(b.transform.rotation, b.storedRotation, ragdollBlendAmount);
                }
            }

            //if the ragdoll blend amount has decreased to zero, move to animated state
            if (ragdollBlendAmount == 0)
            {
                state=RagdollState.animated;
                return;
            }
        }
    }
예제 #19
0
    readonly float fallThreshold = 120f; //When this threshold is reached by impact force character will lose all control

    void ControllRagdoll()
    {
        //Check whether ragdoll or animated
        switch (rState)
        {
        case RagdollState.Animated:

            //1.Check if character is colliding with something. If not colliding break case
            //2.Check forces applied to character. - total collision force - main limbs total collision force - arms legs collision per limb etc.
            //3.If total collision force is bigger than thershold set state as ragdoll (character false) || if there is too much force on one limb (something collided with high speed) set state as ragdoll (character false)
            //4.If character did not fall and main limbs total collision bigger than threshold go to set state as goingRagdoll

            //if checks condition character will fall.After fall character will not retain full force until conditions satisfied (check case RagdollState.Ragdoll:)
            if (collisionCount > 0)
            {
                /*if((totalCollisionSpeed > 100f || (totalCollisionSpeed / collisionCount > 15f)))
                 * {
                 * //	Debug.LogWarning(totalCollisionSpeed / collisionCount);
                 * //	Debug.LogWarning(collisionCount + "\n");
                 *
                 *      rState = RagdollState.Ragdoll;
                 *      FullRagdoll();
                 * }
                 * else */
                bool totalForceExceeds    = ((totalCollisionSpeed > 100f || (totalCollisionSpeed / collisionCount > 15f)));
                bool mainLimbForceExceeds = (mainLimbsCollisionCount > 0 && (mainLimbsCollisionSpd / mainLimbsCollisionCount > 5f));

                if (totalForceExceeds || mainLimbForceExceeds)
                {
                    rState = RagdollState.GoingRagdoll;

                    maximumImpact = totalCollisionSpeed;
                    impactForce   = totalCollisionSpeed;
                }
            }

            break;

        case RagdollState.GoingRagdoll:

            //Check if the character is still colliding. If not colliding set state as goingAnimated and break
            //if colliding ease up the ragdoll smoothly according to speed of collision
            //if characters animationRate is reached 0 set state as ragdoll

            //When main limbs collided with some force ease up the character. Smoothly decrease applied force, torque and decrease animationRate
            if (mainLimbsCollisionCount > 0)
            {
                //if GoingRagdoll returns true character is ragdoll
                if (GoingRagdoll(maximumImpact) && maximumImpact > fallThreshold)                         //if not ragdoll yet continue setting impactforce and easing up
                {
                    FullRagdoll();
                    rState = RagdollState.Ragdoll;
                }

                impactForce = totalCollisionSpeed;

                //update maximum applied impact force each frame
                maximumImpact = (impactForce > maximumImpact) ? impactForce : maximumImpact;
            }
            else                     //character stopped colliding when going to ragdoll. Set state as going animated and break case
            {
                rState = RagdollState.GoingAnimated;
            }

            break;

        case RagdollState.Ragdoll:
            //Character will retain full force if this conditions satisfies

            //if maximumImpact is bigger than threshold character will use control untill collided to ground
            if (maximumImpact > fallThreshold && (collisionCount > 2 && rootBone.velocity.magnitude < 1f))
            {
                maximumImpact = 0f;
                rState        = RagdollState.Animated;
                FullAnimated();
            }

            break;

        case RagdollState.GoingAnimated:

            if (GoingAnimated(maximumImpact))
            {
                rState = RagdollState.Animated;
                FullAnimated();
            }

            break;

        default:
            break;
        }

        //Reset total collision in each fixedUpdate
        totalCollisionSpeed   = 0f;
        mainLimbsCollisionSpd = 0f;
    }
예제 #20
0
    void ControllRagdoll()
    {
        //Debug.Log(groundCollidingFoot);
        //Check whether ragdoll or animated
        switch (rState)
        {
        case RagdollState.Animated:

            //1.Check if character is colliding with something. If not colliding break case
            //2.Check forces applied to character. - total collision force - main limbs total collision force - arms legs collision per limb etc.
            //3.If total collision force is bigger than thershold set state as ragdoll (character false) || if there is too much force on one limb (something collided with high speed) set state as ragdoll (character false)
            //4.If character did not fall and main limbs total collision bigger than threshold go to set state as goingRagdoll

            //if checks condition character will fall.After fall character will not retain full force until conditions satisfied (check case RagdollState.Ragdoll:)
            if (collisionCount > 0)
            {
                rState = RagdollState.Ragdoll;
                //FullRagdoll();
            }


            break;

        case RagdollState.Ragdoll:
            //Character will retain full force if this conditions satisfies

            if (collisionCount > 0)
            {
                if (animationRate > 0.1f)
                {
                    animationRate  = Mathf.Lerp(animationRate, animationRange.min, totalCollisionSpeed / 1000f);
                    maxJointSpring = Mathf.Lerp(maxJointSpring, jointSpringRange.min, totalCollisionSpeed / 1000f);
                }
                else
                {
                    FullRagdoll();
                }
            }
            else
            {
                if (animationRate < animationRange.max - 0.1f)
                {
                    animationRate  = Mathf.Lerp(animationRate, animationRange.max, 0.05f);
                    maxJointSpring = Mathf.Lerp(maxJointSpring, jointSpringRange.max, 0.05f);
                }
                else
                {
                    FullAnimated();
                }
            }

            //if maximumImpact is bigger than threshold character will use control untill collided to ground
            //Debug.Log(collisionCount);
            if (rootBone.velocity.magnitude < 0.5f)
            {
                rState = RagdollState.Animated;
                FullAnimated();
            }


            break;

        default:
            break;
        }

        //Reset total collision in each fixedUpdate
        totalCollisionSpeed = 0f;
    }
예제 #21
0
    void LateUpdate()
    {
        if (_state == RagdollState.Blending) {
            if (Time.time <= _ragdollEndTime + _toGetUpTransitionTime) {
                //If we are waiting for Mecanim to start playing the get up animations, update the root of the mecanim
                //character to the best match with the ragdoll
                Vector3 animatedToRagdolled = _ragdolledHipPosition - _animController.GetBoneTransform(HumanBodyBones.Hips).position;
                Vector3 newRootPosition = transform.position + animatedToRagdolled;

                //Now cast a ray from the computed position downwards and find the highest hit that does not belong to the character
                RaycastHit[] hits = Physics.RaycastAll(new Ray(newRootPosition, Vector3.down));
                newRootPosition.y = 0;
                foreach (RaycastHit hit in hits) {
                    if (!hit.transform.IsChildOf(transform)) {
                        newRootPosition.y = Mathf.Max(newRootPosition.y, hit.point.y);
                    }
                }
                transform.position = newRootPosition;

                //Get body orientation in ground plane for both the ragdolled pose and the animated get up pose
                Vector3 ragdolledDirection = _ragdolledHeadPosition - _ragdolledFeetPosition;
                ragdolledDirection.y = 0;

                Vector3 meanFeetPosition = 0.5f * (_animController.GetBoneTransform(HumanBodyBones.LeftFoot).position + _animController.GetBoneTransform(HumanBodyBones.RightFoot).position);
                Vector3 animatedDirection = _animController.GetBoneTransform(HumanBodyBones.Head).position - meanFeetPosition;
                animatedDirection.y = 0;

                //Try to match the rotations. Note that we can only rotate around Y axis, as the animated characted must stay upright,
                //hence setting the y components of the vectors to zero.
                transform.rotation *= Quaternion.FromToRotation(animatedDirection.normalized, ragdolledDirection.normalized);
            }

            float blend = Mathf.Clamp01(1.0f - (Time.time - _ragdollEndTime - _toGetUpTransitionTime) / BlendTime);
            foreach (var l in _limbs) {

                if (l.Transform != transform) { //this if is to prevent us from modifying the root of the character, only the actual body parts
                    //position is only interpolated for the hips
                    if (l.Transform == _animController.GetBoneTransform(HumanBodyBones.Hips))
                        l.Transform.position = Vector3.Lerp(l.Transform.position, l.Position, blend);
                    //rotation is interpolated for all body parts
                    l.Transform.rotation = Quaternion.Slerp(l.Transform.rotation, l.Rotation, blend);
                }
            }

            //if the ragdoll blend amount has decreased to zero, move to animated state
            if (blend == 0) {
                _state = RagdollState.Animated;
                return;
            }
        }
    }
예제 #22
0
    void LateUpdate()
    {
        //check for errors in state
        if (anim == null)
        {
            state = RagdollState.ragdolled;
        }


        //check if we're currently in the state that we should be
        if (state == RagdollState.ragdolled && GetComponent <RagdollTransitions>().boneParent.collider.enabled == false)
        {
            //set to ragdoll again
            GetComponent <RagdollTransitions>().boneParent.SetActive(true);
            setKinematic(false);             //allow the ragdoll RigidBodies to react to the environment
        }

        //get back to our parents position and rotation
        transform.position = Vector3.Lerp(transform.position, transform.parent.position, 0.5f);
        transform.rotation = Quaternion.Lerp(transform.rotation, transform.parent.rotation, 0.1f);


        if (anim == null)
        {
            return;
        }


        //Clear the get up animation controls so that we don't end up repeating the animations indefinitely
        anim.SetBool("GetUpFromBelly", false);
        anim.SetBool("GetUpFromBack", false);

        //Blending from ragdoll back to animated
        if (state == RagdollState.blendToAnim)
        {
            if (Time.time <= ragdollingEndTime + mecanimToGetUpTransitionTime)
            {
                //If we are waiting for Mecanim to start playing the get up animations, update the root of the mecanim
                //character to the best match with the ragdoll
                Vector3 animatedToRagdolled = ragdolledHipPosition - anim.GetBoneTransform(HumanBodyBones.Hips).position;
                Vector3 newRootPosition     = transform.position + animatedToRagdolled;

                //Now cast a ray from the computed position downwards and find the highest hit that does not belong to the character
                RaycastHit[] hits = Physics.RaycastAll(new Ray(newRootPosition, Vector3.down));
                newRootPosition.y = 0;
                foreach (RaycastHit hit in hits)
                {
                    if (!hit.transform.IsChildOf(transform))
                    {
                        newRootPosition.y = Mathf.Max(newRootPosition.y, hit.point.y);
                    }
                }
                transform.position = newRootPosition;

                //Get body orientation in ground plane for both the ragdolled pose and the animated get up pose
                Vector3 ragdolledDirection = ragdolledHeadPosition - ragdolledFeetPosition;
                ragdolledDirection.y = 0;

                Vector3 meanFeetPosition  = 0.5f * (anim.GetBoneTransform(HumanBodyBones.LeftFoot).position + anim.GetBoneTransform(HumanBodyBones.RightFoot).position);
                Vector3 animatedDirection = anim.GetBoneTransform(HumanBodyBones.Head).position - meanFeetPosition;
                animatedDirection.y = 0;

                //Try to match the rotations. Note that we can only rotate around Y axis, as the animated characted must stay upright,
                //hence setting the y components of the vectors to zero.
                transform.rotation *= Quaternion.FromToRotation(animatedDirection.normalized, ragdolledDirection.normalized);
            }
            //compute the ragdoll blend amount in the range 0...1
            float ragdollBlendAmount = 1.0f - (Time.time - ragdollingEndTime - mecanimToGetUpTransitionTime) / ragdollToMecanimBlendTime;
            ragdollBlendAmount = Mathf.Clamp01(ragdollBlendAmount);

            //In LateUpdate(), Mecanim has already updated the body pose according to the animations.
            //To enable smooth transitioning from a ragdoll to animation, we lerp the position of the hips
            //and slerp all the rotations towards the ones stored when ending the ragdolling
            foreach (BodyPart b in bodyParts)
            {
                if (b.transform != transform)                //this if is to prevent us from modifying the root of the character, only the actual body parts
                //position is only interpolated for the hips
                {
                    if (b.transform == anim.GetBoneTransform(HumanBodyBones.Hips))
                    {
                        b.transform.position = Vector3.Lerp(b.transform.position, b.storedPosition, ragdollBlendAmount);
                    }
                    //rotation is interpolated for all body parts
                    b.transform.rotation = Quaternion.Slerp(b.transform.rotation, b.storedRotation, ragdollBlendAmount);
                }
            }



            //if the ragdoll blend amount has decreased to zero, move to animated state
            if (ragdollBlendAmount == 0)
            {
                state = RagdollState.animated;
                return;
            }
        }
    }