Beispiel #1
0
    void ApplyForce(Collider2D other)
    {
        IForceObject forceObj = other.GetComponent <IForceObject>();

        if (forceObj != null)
        {
            int id = other.gameObject.GetInstanceID();
            if (!isUsed.ContainsKey(id))
            {
                isUsed [id] = false;
            }
            if (!isUsed [id])
            {
                float yValue = transform.up.y;
                if ((yValue > -0.09f) && (yValue < 0.09f))
                {
                    yValue = 0;
                }
                float xValue = transform.up.x;
                if ((xValue > -0.09f) && (xValue < 0.09f))
                {
                    xValue = 0;
                }
                Vector2 dir = new Vector2(xValue, yValue);

                if (dir.x != 0 && dir.y == 0)
                {
                    isUsed [id] = forceObj.ApplyForce(dir.normalized, Force.x, ForceYWhenOnlyX, true, TimeNotInput);
                }
                else
                {
                    isUsed [id] = forceObj.ApplyForce(dir.normalized, Force.x, Force.y, true, TimeNotInput);
                }
                if (isUsed [id])
                {
                    anim.SetBool(animationName, true);
                    audio.Stop();
                    audio.Play();
                }
                if (ForceCallback != null)
                {
                    ForceCallback(dir.normalized);
                }
                //  isUsed [id] = true;
            }

            //Fix Loco
            else
            {
                isUsed [id] = false;
                anim.SetBool(animationName, false);
            }
        }
    }
Beispiel #2
0
        /// <summary>
        /// Initialize the default values.
        /// </summary>
        protected override void Awake()
        {
            base.Awake();

            m_GameObject       = gameObject;
            m_Transform        = transform;
            m_ForceObject      = m_GameObject.GetCachedComponent <IForceObject>();
            m_Rigidbody        = m_GameObject.GetCachedComponent <Rigidbody>();
            m_AttributeManager = GetComponent <AttributeManager>();
            if (!string.IsNullOrEmpty(m_HealthAttributeName))
            {
                m_HealthAttribute = m_AttributeManager.GetAttribute(m_HealthAttributeName);
            }
            if (!string.IsNullOrEmpty(m_ShieldAttributeName))
            {
                m_ShieldAttribute = m_AttributeManager.GetAttribute(m_ShieldAttributeName);
            }
            m_AliveLayer = m_GameObject.layer;
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
            m_NetworkInfo          = m_GameObject.GetCachedComponent <INetworkInfo>();
            m_NetworkHealthMonitor = m_GameObject.GetCachedComponent <INetworkHealthMonitor>();
            if (m_NetworkInfo != null && m_NetworkHealthMonitor == null)
            {
                Debug.LogError("Error: The object " + m_GameObject.name + " must have a NetworkHealthMonitor component.");
            }
#endif

            if (m_Hitboxes != null && m_Hitboxes.Length > 0)
            {
                m_ColliderHitboxMap = new Dictionary <Collider, Hitbox>();
                for (int i = 0; i < m_Hitboxes.Length; ++i)
                {
                    m_ColliderHitboxMap.Add(m_Hitboxes[i].Collider, m_Hitboxes[i]);
                }
                m_RaycastHits        = new RaycastHit[m_MaxHitboxCollisionCount];
                m_RaycastHitComparer = new Utility.UnityEngineUtility.RaycastHitComparer();
            }

            EventHandler.RegisterEvent(m_GameObject, "OnRespawn", OnRespawn);
        }
Beispiel #3
0
        /// <summary>
        /// Do the explosion.
        /// </summary>
        /// <param name="damageAmount">The amount of damage to apply to the hit objects.</param>
        /// <param name="impactForce">The amount of force to apply to the hit object.</param>
        /// <param name="impactForceFrames">The number of frames to add the force to.</param>
        /// <param name="originator">The originator of the object.</param>
        public void Explode(float damageAmount, float impactForce, int impactForceFrames, GameObject originator)
        {
            Health       health            = null;
            Rigidbody    colliderRigidbody = null;
            IForceObject forceObject       = null;
            var          hitCount          = Physics.OverlapSphereNonAlloc(m_Transform.position, m_Radius, m_CollidersHit, m_ImpactLayers, QueryTriggerInteraction.Ignore);

#if UNITY_EDITOR
            if (hitCount == m_MaxCollisionCount)
            {
                Debug.LogWarning("Warning: The maximum number of colliders have been hit by " + m_GameObject.name + ". Consider increasing the Max Collision Count value.");
            }
#endif
            for (int i = 0; i < hitCount; ++i)
            {
                // A GameObject can contain multiple colliders. Prevent the explosion from occurring on the same GameObject multiple times.
                if (m_ObjectExplosions.Contains(m_CollidersHit[i].gameObject))
                {
                    continue;
                }
                m_ObjectExplosions.Add(m_CollidersHit[i].gameObject);
                // The base character GameObject should only be checked once.
                if ((forceObject = m_CollidersHit[i].gameObject.GetCachedParentComponent <IForceObject>()) != null)
                {
                    if (m_ObjectExplosions.Contains(forceObject))
                    {
                        continue;
                    }
                    m_ObjectExplosions.Add(forceObject);
                }

                // OverlapSphere can return objects that are in a different room. Perform a cast to ensure the object is within the explosion range.
                if (m_LineOfSight)
                {
                    // Add a slight vertical offset to prevent a floor collider from getting in the way of the cast.
                    var position  = m_Transform.TransformPoint(0, 0.1f, 0);
                    var direction = m_CollidersHit[i].transform.position - position;
                    if (Physics.Raycast(position - direction.normalized * 0.1f, direction, out m_RaycastHit, direction.magnitude, m_ImpactLayers, QueryTriggerInteraction.Ignore) &&
                        !(m_RaycastHit.transform.IsChildOf(m_CollidersHit[i].transform)
#if FIRST_PERSON_CONTROLLER
                          // The cast should not hit any colliders who are a child of the camera.
                          || m_RaycastHit.transform.gameObject.GetCachedParentComponent <FirstPersonController.Character.FirstPersonObjects>() != null
#endif
                          ))
                    {
                        // If the collider is part of a character then ensure the head can't be hit.
                        var parentAnimator = m_CollidersHit[i].transform.gameObject.GetCachedParentComponent <Animator>();
                        if (parentAnimator != null && parentAnimator.isHuman)
                        {
                            var head = parentAnimator.GetBoneTransform(HumanBodyBones.Head);
                            direction = head.position - position;
                            if (Physics.Raycast(position, direction, out m_RaycastHit, direction.magnitude, m_ImpactLayers, QueryTriggerInteraction.Ignore) &&
                                !m_RaycastHit.transform.IsChildOf(m_CollidersHit[i].transform) && !m_CollidersHit[i].transform.IsChildOf(m_RaycastHit.transform) &&
                                m_RaycastHit.transform.IsChildOf(m_Transform)
#if FIRST_PERSON_CONTROLLER
                                // The cast should not hit any colliders who are a child of the camera.
                                && m_RaycastHit.transform.gameObject.GetCachedParentComponent <FirstPersonController.Character.FirstPersonObjects>() == null
#endif
                                )
                            {
                                continue;
                            }
                        }
                        else
                        {
                            continue;
                        }
                    }
                }

                // The shield can absorb some (or none) of the damage from the explosion.
                var hitDamageAmount = damageAmount;
#if ULTIMATE_CHARACTER_CONTROLLER_MELEE
                ShieldCollider shieldCollider;
                if ((shieldCollider = m_CollidersHit[i].transform.gameObject.GetCachedComponent <ShieldCollider>()) != null)
                {
                    hitDamageAmount = shieldCollider.Shield.Damage(this, hitDamageAmount);
                }
#endif

                // ClosestPoint only works with a subset of collider types.
                Vector3 closestPoint;
                if (m_CollidersHit[i] is BoxCollider || m_CollidersHit[i] is SphereCollider || m_CollidersHit[i] is CapsuleCollider || (m_CollidersHit[i] is MeshCollider && (m_CollidersHit[i] as MeshCollider).convex))
                {
                    closestPoint = m_CollidersHit[i].ClosestPoint(m_Transform.position);
                }
                else
                {
                    closestPoint = m_CollidersHit[i].ClosestPointOnBounds(m_Transform.position);
                }
                var hitDirection = closestPoint - m_Transform.position;

                // Allow a custom event to be received.
                EventHandler.ExecuteEvent <float, Vector3, Vector3, GameObject, object, Collider>(m_CollidersHit[i].transform.gameObject, "OnObjectImpact", hitDamageAmount, closestPoint, hitDirection * m_ImpactForce, originator, this, m_CollidersHit[i]);
                if (m_OnImpactEvent != null)
                {
                    m_OnImpactEvent.Invoke(hitDamageAmount, closestPoint, hitDirection * m_ImpactForce, originator);
                }

                // If the shield didn't absorb all of the damage then it should be applied to the character.
                if (hitDamageAmount > 0)
                {
                    // If the Health component exists it will apply an explosive force to the character/character in addition to deducting the health.
                    // Otherwise just apply the force to the character/rigidbody.
                    if ((health = m_CollidersHit[i].gameObject.GetCachedParentComponent <Health>()) != null)
                    {
                        // The further out the collider is, the less it is damaged.
                        var damageModifier = Mathf.Max(1 - (hitDirection.magnitude / m_Radius), 0.01f);
                        health.Damage(hitDamageAmount * damageModifier, m_Transform.position, hitDirection.normalized, impactForce * damageModifier, impactForceFrames, m_Radius, originator, this, null);
                    }
                    else if (forceObject != null)
                    {
                        var damageModifier = Mathf.Max(1 - (hitDirection.magnitude / m_Radius), 0.01f);
                        forceObject.AddForce(hitDirection.normalized * impactForce * damageModifier);
                    }
                    else if ((colliderRigidbody = m_CollidersHit[i].gameObject.GetCachedComponent <Rigidbody>()) != null)
                    {
                        colliderRigidbody.AddExplosionForce(impactForce * MathUtility.RigidbodyForceMultiplier, m_Transform.position, m_Radius);
                    }
                }
            }
            m_ObjectExplosions.Clear();

            // An audio clip can play when the object explodes.
            m_ExplosionAudioClipSet.PlayAudioClip(m_GameObject);

            Scheduler.Schedule(m_Lifespan, Destroy);
        }