Example #1
0
    private bool CheckDamage(Collider target, AttackPoint point)
    {
        DamageAble victim = target.GetComponent <DamageAble>();

        if (victim == null)
        {
            return(false);
        }

        if (victim.gameObject == wielder)
        {
            return(true);
        }

        DamageAble.DamageData data = new DamageAble.DamageData
        {
            damageAmount = damage,
            damager      = this,
            damageOwner  = wielder,
            direction    = direction,
            damageSource = wielder.transform.position
        };

        victim.ApplyDamage(data);


        if (hit_effect != null)
        {
            hit_effect.transform.position = point.attackRoot.position;
            hit_effect.time = 0;
            hit_effect.Play();
        }

        return(true);
    }
Example #2
0
        private void FixedUpdate()
        {
            if (isInAttack)
            {
                for (int i = 0; i < attackPointArray.Length; i++)
                {
                    AttackPoint ap = attackPointArray[i];

                    Vector3 worldPos  = GetAttackPointWorldPos(ap);
                    Vector3 attackVec = worldPos - previousAttackPos[i];


                    if (attackVec.magnitude < 0.001f)
                    {
                        attackVec = Vector3.forward * 0.0001f;
                    }

                    Ray r        = new Ray(worldPos, attackVec.normalized);
                    int contacts = Physics.SphereCastNonAlloc(r, ap.radius, raycastHitCache, attackVec.magnitude, targetLayers,
                                                              QueryTriggerInteraction.Ignore);

                    for (int j = 0; j < contacts; j++)
                    {
                        Collider col = raycastHitCache[j].collider;
                        if (col != null)
                        {
                            CheckDamage(col, attackVec, worldPos);
                        }
                    }

                    //update new postion
                    previousAttackPos[i] = worldPos;
                }
            }
        }
Example #3
0
 private Vector3 GetAttackPointWorldPos(AttackPoint ap)
 {
     if (ap.attackRoot == null)
     {
         return(Vector3.zero);
     }
     return(ap.attackRoot.position + ap.attackRoot.transform.TransformVector(ap.offset));
 }
Example #4
0
        private bool CheckDamage(Collider other, AttackPoint pts)
        {
            Damageable damageable = other.GetComponent <Damageable>();

            if (damageable == null)
            {
                return(false);
            }

            if (damageable.gameObject == m_Owner)
            {
                return(true); //ignore self harm, but do not end the attack (we don't "bounce" off ourselves)
            }
            if ((targetLayers.value & (1 << other.gameObject.layer)) == 0)
            {
                //hit an object that is not in our layer, this end the attack. we "bounce" off it
                return(false);
            }

            if (hitAudio != null)
            {
                var renderer = other.GetComponent <Renderer>();
                if (!renderer)
                {
                    renderer = other.GetComponentInChildren <Renderer> ();
                }
                if (renderer)
                {
                    hitAudio.PlayRandomClip(renderer.sharedMaterial);
                }
                else
                {
                    hitAudio.PlayRandomClip();
                }
            }

            Damageable.DamageMessage data = new Damageable.DamageMessage
            {
                amount       = damage,
                damager      = this,
                direction    = m_Direction.normalized,
                damageSource = m_Owner.transform.position,
                throwing     = m_IsThrowingHit,
                stopCamera   = false
            };

            damageable.ApplyDamage(data);

            if (hitParticlePrefab != null)
            {
                m_ParticlesPool[m_CurrentParticle].transform.position = pts.attackRoot.transform.position;
                m_ParticlesPool[m_CurrentParticle].time = 0;
                m_ParticlesPool[m_CurrentParticle].Play();
                m_CurrentParticle = (m_CurrentParticle + 1) % PARTICLE_COUNT;
            }

            return(true);
        }
Example #5
0
    private new void Start()
    {
        base.Start();

        //Debug.Log("Enemy.Start");

        // reset nextTile, latched and attackPoint, for cloned (replicated) units
        latched     = false;
        attackPoint = null;

        Transform rotatingPart = transform.Find(Constants.RotatingPart);

        if (rotatingPart == null)
        {
            Debug.Log("RotatingPart is NULL!");
        }
        else
        {
            Transform head = rotatingPart.Find("Head");
            if (head == null)
            {
                Debug.Log("Head is NULL!");
            }
            else
            {
                anim = head.GetComponent <Animator>();
                if (anim == null)
                {
                    Debug.Log("Animator is NULL!");
                }
            }
        }

        moveable = GetComponent <Moveable>();
        if (moveable == null)
        {
            moveable = gameObject.AddComponent <Moveable>();
        }

        //rotatingPart = transform.Find(Constants.RotatingPart);

        if (!Shop.instance.IsCoughing())
        {
            moveable.SetSpeed(regularSpeed);
        }
        // todo: if coughing when this enemy is spawned, slow it down too
        //else
        //    speed =

        replicationCoundtown = random.Next(minReplicationTime, maxReplicationTime);

        meleeAttackers = new List <Transform>();
        towerAttackers = new List <Transform>();
    }
Example #6
0
    private void crash(Collider collider, AttackPoint attackPoint)
    {
        //if (damagedObjectsList.Contains(collider.gameObject)) return;
        //damagedObjectsList.Add(collider.gameObject);

        if (audioSource)
        {
            audioSource.Play();
        }

        StartCoroutine(owner.GetComponent <Damageable>().
                       locateCrashParticle(attackPoint.attackRoot.position, owner.transform.position));
    }
Example #7
0
        private void OnDrawGizmosSelected()
        {
            for (int i = 0; i < attackPointArray.Length; i++)
            {
                AttackPoint ap = attackPointArray[i];

                if (ap.attackRoot != null)
                {
                    Vector3 worldPos = ap.attackRoot.TransformVector(ap.offset);
                    Color   green    = Color.green;
                    green.a      = 0.7f;
                    Gizmos.color = green;
                    Gizmos.DrawWireSphere(worldPos + ap.attackRoot.position, ap.radius);
                }
            }
        }
Example #8
0
        private void FixedUpdate()
        {
            if (m_InAttack)
            {
                for (int i = 0; i < attackPoints.Length; ++i)
                {
                    AttackPoint pts = attackPoints[i];

                    Vector3 worldPos     = pts.attackRoot.position + pts.attackRoot.TransformVector(pts.offset);
                    Vector3 attackVector = worldPos - m_PreviousPos[i];

                    if (attackVector.magnitude < 0.001f)
                    {
                        // A zero vector for the sphere cast don't yield any result, even if a collider overlap the "sphere" created by radius.
                        // so we set a very tiny microscopic forward cast to be sure it will catch anything overlaping that "stationary" sphere cast
                        attackVector = Vector3.forward * 0.0001f;
                    }


                    Ray r = new Ray(worldPos, attackVector.normalized);

                    int contacts = Physics.SphereCastNonAlloc(r, pts.radius, s_RaycastHitCache, attackVector.magnitude,
                                                              targetLayers.value,//~0,
                                                              QueryTriggerInteraction.Ignore);

                    for (int k = 0; k < contacts; ++k)
                    {
#if UNITY_EDITOR
                        // helper to visualise the ground check ray in the scene view
                        Debug.DrawLine(r.origin, r.origin + r.direction, Color.cyan);
#endif
                        Collider col = s_RaycastHitCache[k].collider;

                        if (col != null)
                        {
                            CheckDamage(col, pts);
                        }
                    }

                    m_PreviousPos[i] = worldPos;

#if UNITY_EDITOR
                    pts.previousPositions.Add(m_PreviousPos[i]);
#endif
                }
            }
        }
        private void OnDrawGizmosSelected()
        {
            for (int i = 0; i < attackPoints.Length; ++i)
            {
                AttackPoint pts = attackPoints[i];

                if (pts.attackRoot != null)
                {
                    Vector3 worldPos = pts.attackRoot.TransformVector(pts.offset);
                    Gizmos.color = new Color(1.0f, 1.0f, 1.0f, 0.4f);
                    Gizmos.DrawSphere(pts.attackRoot.position + worldPos, pts.radius);
                }

                if (pts.previousPositions.Count > 1)
                {
                    UnityEditor.Handles.DrawAAPolyLine(10, pts.previousPositions.ToArray());
                }
            }
        }
Example #10
0
    private void checkDamage(Collider collider, AttackPoint attackPoint)
    {
        Damageable damageableScript = collider.GetComponent <Damageable>();
        GameObject gameObject       = collider.gameObject;

        if (damageableScript != null && !damagedObjectsList.Contains(gameObject))
        {
            if (collider.gameObject != owner && collider.gameObject.tag != owner.tag)
            {
                damageMessage.damageSource = attackPoint.attackRoot.transform.position;

                damagedObjectsList.Add(gameObject);

                damageableScript.applyDamage(damageMessage);

                burnTarget();
            }
        }
    }
        private bool CheckDamage(Collider other, AttackPoint pts)
        {
            Damageable d = other.GetComponent <Damageable>();

            if (d == null)
            {
                return(false);
            }

            if (d.gameObject == m_Owner)
            {
                return(true);
            }

            if ((targetLayers.value & (1 << other.gameObject.layer)) == 0)
            {
                return(false);
            }



            Damageable.DamageMessage data;

            data.amount       = damage;
            data.damager      = this;
            data.direction    = m_Direction.normalized;
            data.damageSource = m_Owner.transform.position;
            data.throwing     = m_IsThrowingHit;
            data.stopCamera   = false;

            d.ApplyDamage(data);

            if (hitParticlePrefab != null)
            {
                m_ParticlesPool[m_CurrentParticle].transform.position = pts.attackRoot.transform.position;
                m_ParticlesPool[m_CurrentParticle].time = 0;
                m_ParticlesPool[m_CurrentParticle].Play();
                m_CurrentParticle = (m_CurrentParticle + 1) % PARTICLE_COUNT;
            }

            return(true);
        }
Example #12
0
    private void checkDamage(Collider collider, AttackPoint attackPoint)
    {
        Damageable damageableScript = collider.GetComponent <Damageable>();
        GameObject gameObject       = collider.gameObject;

        if (damageableScript != null && !damagedObjectsList.Contains(gameObject))
        {
            if (damageableScript.Invincibility || collider.gameObject == owner ||
                collider.gameObject.tag == owner.tag)
            {
                return;
            }

            damageMessage.damageSource = attackPoint.attackRoot.position;
            damageMessage.radius       = attackPoint.radius;

            damagedObjectsList.Add(gameObject);
            damageableScript.applyDamage(damageMessage);
        }
    }
Example #13
0
    protected GameObject LookForLatchedEnemies()
    {
        GameObject chosenEnemy      = null;
        float      shortestDistance = Mathf.Infinity;

        GameObject[] attackPoints = GameObject.FindGameObjectsWithTag(Constants.AttackPointTag);
        foreach (GameObject ap in attackPoints)
        {
            AttackPoint attackPoint = ap.GetComponent <AttackPoint>();
            if (attackPoint != null && !attackPoint.IsVacant())
            {
                float distanceToAP = Vector2.Distance(transform.position, ap.transform.position);
                if (distanceToAP <= range && distanceToAP < shortestDistance)
                {
                    shortestDistance = distanceToAP;
                    chosenEnemy      = attackPoint.GetOccupant().gameObject;
                }
            }
        }
        return(chosenEnemy);
    }
Example #14
0
    private void FixedUpdate()
    {
        if (inAttack)
        {
            for (int i = 0; i < attackPoints.Length; ++i)
            {
                AttackPoint point = attackPoints[i];

                Vector3 worldPos     = point.attackRoot.position + point.attackRoot.TransformVector(point.offset);
                Vector3 attackVector = worldPos - previousPoints[i];

                if (attackVector.magnitude < 0.001f)
                {
                    attackVector = Vector3.forward * 0.0001f;
                }

                Ray ray = new Ray(worldPos, attackVector.normalized);

                int contacts = Physics.SphereCastNonAlloc(ray, point.radius, RaycastCache, attackVector.magnitude, ~0, QueryTriggerInteraction.Ignore);

                for (int k = 0; k < contacts; ++k)
                {
                    Collider col = RaycastCache[k].collider;

                    if (col != null)
                    {
                        CheckDamage(col, point);
                    }
                }

                previousPoints[i] = worldPos;

#if UNITY_EDITOR
                point.previousPoints.Add(previousPoints[i]);
#endif
            }
        }
    }
        private void FixedUpdate()
        {
            if (m_InAttack)
            {
                for (int i = 0; i < attackPoints.Length; ++i)
                {
                    AttackPoint pts = attackPoints[i];

                    Vector3 worldPos     = pts.attackRoot.position + pts.attackRoot.TransformVector(pts.offset);
                    Vector3 attackVector = worldPos - m_PreviousPos[i];

                    if (attackVector.magnitude < 0.001f)
                    {
                        attackVector = Vector3.forward * 0.0001f;
                    }


                    Ray r = new Ray(worldPos, attackVector.normalized);

                    int contacts = Physics.SphereCastNonAlloc(r, pts.radius, s_RaycastHitCache, attackVector.magnitude,
                                                              ~0,
                                                              QueryTriggerInteraction.Ignore);

                    for (int k = 0; k < contacts; ++k)
                    {
                        Collider col = s_RaycastHitCache[k].collider;

                        if (col != null)
                        {
                            CheckDamage(col, pts);
                        }
                    }

                    m_PreviousPos[i] = worldPos;
                }
            }
        }
Example #16
0
    /// <summary> Called with Invoke(). </summary>
    private void UpdateTarget()
    {
        // if it already has a target, see if it's dead or too far away, or if there's another one without an attacker
        if (target != null)
        {
            Enemy targetEnemy = target.GetComponent <Enemy>();

            float distanceToTarget = Vector2.Distance(transform.position, target.transform.position);
            if (distanceToTarget > spotRange)
            {
                //Debug.Log("LOST TARGET");
                DismissTarget();
                return;
            }

            // todo: if this target has another attacker, look for nearby enemies without an attacker
            if (targetEnemy != null && targetEnemy.HasAnotherMeleeAttacker(transform))
            {
                // this target has another attacker; look for other targets without an attacker
                GameObject[] enemies2          = GameObject.FindGameObjectsWithTag(Constants.EnemyTag);
                float        shortestDistance2 = Mathf.Infinity;
                GameObject   nearestEnemy2     = null;
                foreach (GameObject enemy in enemies2)
                {
                    // if the enemy is beyond this unit's spot range, ignore target
                    float distanceToEnemy = Vector2.Distance(transform.position, enemy.transform.position);
                    if (distanceToEnemy <= spotRange)
                    {
                        // if the enemy has another attacker, ignore it
                        Enemy enemyEnemy = enemy.GetComponent <Enemy>();
                        if (enemyEnemy != null)
                        {
                            if (!enemyEnemy.HasAnotherMeleeAttacker(transform))
                            {
                                float distanceFromUnitToEnemy = Vector2.Distance(transform.position, enemy.transform.position);
                                if (distanceFromUnitToEnemy < shortestDistance2)
                                {
                                    shortestDistance2 = distanceFromUnitToEnemy;
                                    nearestEnemy2     = enemy;
                                }
                            }
                        }
                    }
                }

                if (nearestEnemy2 != null)
                {
                    AcquireTarget(nearestEnemy2.transform);
                }
            }

            return;
        }


        // if there's no current target, first look for living enemies latched to attack points within range
        float      shortestDistance = Mathf.Infinity;
        GameObject chosenEnemy      = null;

        GameObject[] attackPoints = GameObject.FindGameObjectsWithTag(Constants.AttackPointTag);
        foreach (GameObject ap in attackPoints)
        {
            AttackPoint attackPoint = ap.GetComponent <AttackPoint>();
            if (attackPoint != null && !attackPoint.IsVacant())
            {
                float distanceToAP = Vector2.Distance(transform.position, ap.transform.position);
                if (distanceToAP <= spotRange && distanceToAP < shortestDistance)
                {
                    shortestDistance = distanceToAP;
                    chosenEnemy      = attackPoint.GetOccupant().gameObject;
                }
            }
        }

        // otherwise, find the nearest enemy
        if (chosenEnemy == null || (chosenEnemy.GetComponent <Enemy>() != null))
        {
            GameObject[] enemies = GameObject.FindGameObjectsWithTag(Constants.EnemyTag);
            /*float */
            shortestDistance = Mathf.Infinity;
            //GameObject nearestEnemy = null;
            foreach (GameObject enemy in enemies)
            {
                // if this enemy is not dead
                if (enemy.GetComponent <Enemy>() != null)
                {
                    // if the enemy is beyond this unit's spot range, ignore target
                    float distanceToEnemy = Vector2.Distance(transform.position, enemy.transform.position);
                    if (distanceToEnemy <= spotRange && distanceToEnemy < shortestDistance)
                    {
                        shortestDistance = distanceToEnemy;
                        chosenEnemy      = enemy;
                    }
                }
            }
        }

        if (chosenEnemy != null)
        {
            //Debug.Log("FOUND TARGET");
            AcquireTarget(chosenEnemy.transform);
        }
        else
        {
            DismissTarget();
        }
    }
Example #17
0
    private void Update()
    {
        if (!started)
        {
            return;
        }

        if (coughing)
        {
            CoughEffect();
        }

        // update the hit countdown and the replication countdown each frame
        if (hitCountdown > 0f)
        {
            hitCountdown -= Time.deltaTime;
        }

        if (replicationCoundtown > 0f && !IsBeingAttacked() && !coughing)
        {
            replicationCoundtown -= Time.deltaTime;
        }
        if (replicationCoundtown <= 0f && !IsBeingAttacked() && !coughing)
        {
            Replicate();
        }

        // if there's a melee unit attacking,
        // start attacking it (face it, move towards it, and if in range, hit)
        if (meleeAttackers.Count > 0)
        {
            //Debug.Log("attacking melee attacker");

            // if it's latched, stop the latched animation
            if (latched)
            {
                attackPoint.SetOccupantActive(false);
                anim.SetBool("isAttackedWhileLatched", true);
                anim.SetBool("isMoving", true);
                anim.SetBool("isAtAP", false);

                if (!attackedWhileLatched)
                {
                    attackedWhileLatched = true;
                }

                //Debug.Log("stopping latched animation");
                //if (anim != null)
                //{
                //anim.SetBool("isLatched", false);
                //anim.SetTrigger("isAttackedWhileLatched");
                //}
            }

            AttackMeleeAttacker();
        }
        else // if there's no melee attacker, continue towards the next tile
        {
            if (nextTile != null)
            {
                //Debug.Log("nextTile != null");
                // if already latched, don't move
                if (latched)
                {
                    anim.SetBool("isAttackedWhileLatched", false);

                    // unless it's too far away from the attack point; in that case, move towards it
                    if (attackPoint != null && Vector2.Distance(transform.position, attackPoint.transform.position) > 0.15f)
                    {
                        //Debug.Log("move closer to attack point");
                        attackPoint.SetOccupantActive(false);
                        moveable.MoveDirectlyTowardsPosition(attackPoint.transform.position);

                        anim.SetBool("isAtAP", false);
                    }
                    else
                    {
                        //Debug.Log("starting latched animation");
                        if (anim != null)
                        {
                            anim.SetBool("isStunned", Shop.instance.IsCoughing());
                        }

                        if (attackedWhileLatched)
                        {
                            attackedWhileLatched = false;
                            attackPoint.SetOccupantActive(!attackedWhileLatched);
                        }

                        anim.SetBool("isAtAP", true);
                        anim.SetBool("isMoving", false);
                    }
                }
                else
                {
                    //Debug.Log("MoveDirectlyTowardsPosition");
                    moveable.MoveDirectlyTowardsPosition(nextTile.transform.position);

                    if (Vector2.Distance(transform.position, nextTile.transform.position) <= 0.3f)
                    {
                        // it's reached the tile; go to the next tile, unless the current tile is an attack point
                        AttackPoint ap = nextTile.GetComponent <AttackPoint>();
                        if (ap != null)
                        {
                            if (ap.IsVacant())
                            {
                                //Debug.Log("ap != null && ap.IsVacant");
                                // if it's an attack point and it's still vacant, occupy it
                                ap.SetOccupant(this);
                                attackPoint = ap;
                                latched     = true;
                                //anim.SetTrigger("isLatched");
                                anim.SetBool("isLatched", true);
                                anim.SetBool("isMoving", false);
                            }
                            else // if nextTile is an AP that is occupied, clear visited list and get next tile
                            {
                                //Debug.Log("NEXTTILE IS OCCUPIED AP!!!!!!!! clearing visitedTiles and getting next tile!");
                                visitedTiles.Clear();
                                GetNextTile();
                            }
                        }
                        else // otherwise, continue on the path
                        {
                            VisitTile(nextTile);
                            GetNextTile();
                        }
                    }
                }
            }
            else
            {
                //Debug.Log("nextTile == null; calling GetNextTile()");
                GetNextTile();
            }
        }
    }