//--------------------------------------------------------------------------------------------------------------------- protected void UpdateRagdoll() { if (!ragdoll) { ragdoll = GetComponent <RootMotion.FinalIK.RagdollUtility>(); } if (ragdoll) { ragdoll.UpdateRigidBones(); } }
//------------------------------------------------------------------------------------------------------------------------- private IEnumerator TempRagdoll(Damageable damageable, RootMotion.FinalIK.RagdollUtility ragdoll, float duration) { ragdoll.EnableRagdoll(); yield return(new WaitForSeconds(duration)); if (damageable.Alive) { ragdoll.DisableRagdoll(); //FENG_TODO: will remove this if we would like to add crawling animations. Let's kill it for the time-being damageable.OnDie.Invoke(); } }
void Awake() { animator = GetComponent<Animator>(); hitReaction = GetComponent<HitReaction>(); rigidbody = GetComponent<Rigidbody>(); if (targetPlayer == null) { targetPlayer = GameObject.FindGameObjectWithTag("Player"); } if (wayPoints.Length == 0) { wayPoints = GameObject.FindGameObjectsWithTag("WayPoint"); } if(blackBoard == null) blackBoard = gameObject.GetComponent<Blackboard>(); if (behaviourTree == null) behaviourTree = gameObject.GetComponent<BehaviourTreeOwner>(); if (blackBoard != null) blackBoard.SetValue("target", targetPlayer); if (behaviourTree != null) { List<GameObject> wps = new List<GameObject>(wayPoints); blackBoard.SetValue("PatrolWayPoints", wps); } currentHP = HP; ragdollUtility = GetComponent<RagdollUtility>(); }
//------------------------------------------------------------------------------------------------------------------------- // TODO: integrate damage filters into explosive effect attributes public virtual void Detonate() { OnDetonate.Invoke(); if (shrapnelPrefab) { foreach (var collider in m_effectOrigin.GetComponentsInChildren <Collider>()) { collider.isTrigger = true; } var shrapnel = GameObject.Instantiate(shrapnelPrefab, m_effectOrigin.position, m_effectOrigin.rotation); shrapnel.SetActive(true); GameObject.Destroy(shrapnel, shrapnelDuration); } //TODO: implement shielding of blast effects Collider[] hitColliders = Physics.OverlapSphere(m_effectOrigin.position + EffectPositionOffset, EffectRadius, AffectedLayers, QueryTriggerInteraction.UseGlobal); var hitDamageables = new List <Damageable>(); //var bodies = new List<Rigidbody>(); //Debug.Log("[BOOM HIT]"); RootMotion.FinalIK.RagdollUtility ragdoll = null; foreach (var hitCollider in hitColliders) { //Debug.Log("[BOOM HIT] " + hit.name); var damageable = hitCollider.GetComponentInParent <Damageable>(); if (damageable) { if (damageable.isServer) { bool firstHit = !hitDamageables.Contains(damageable); if (firstHit) { hitDamageables.Add(damageable); } if (!LimitDamageablesToOneHit || firstHit) { // TODO: more intelligently select the root collider to apply damage effect to var effectRange = Vector3.Distance(hitCollider.transform.position, m_effectOrigin.position) / EffectRadius; int damage = Mathf.RoundToInt(BaseDamage * Falloff.Evaluate(effectRange)); if (damage > 0) { damageable.TakeDamage(damage, hitCollider); } } } // FENG_TODO: not using ragdoll for now based on design; will see if we will enable it in the future bool using_Ragdoll = false; if (using_Ragdoll) { if (!ragdoll) { ragdoll = damageable.GetComponent <RootMotion.FinalIK.RagdollUtility>(); } if (ragdoll && !ragdoll.isRagdoll) { if (m_profile.ragdollDuration > 0) { damageable.StartCoroutine(TempRagdoll(damageable, ragdoll, m_profile.ragdollDuration)); } else if (m_profile.ragdollDuration < 0) { ragdoll.EnableRagdoll(); } } } } // TODO: figure out best way optionally limit force to apply just to root body. Rigidbody rb = hitCollider.GetComponentInParent <Rigidbody>(); if (rb != null) { rb.AddExplosionForce(EffectForce, m_effectOrigin.position + EffectPositionOffset + Random.onUnitSphere, 2 * EffectRadius, 3.0f); //rb.AddForce(EffectForce,, m_effectOrigin.position + EffectPositionOffset, 2 * EffectRadius, 1.0f); } } }