Пример #1
0
    /// <summary>
    /// Makes the character shoot.
    /// If the character is currently shooting (its cooldown is running), the action is cancelled.
    /// If the hit object has a Shootable component, triggers OnShot event on that component.
    /// </summary>
    public void DoShoot()
    {
        // If the character is already shooting (its cooldown is running) or the action is frozen, cancel update
        if (IsShooting || m_FreezeShoot)
        {
            return;
        }

        Vector3 aimVector = AimVector.normalized;

        // Start the cooldown coroutine
        m_ShootCooldownCoroutine = StartCoroutine(ApplyShootCooldown(m_ShootRange, m_ShootCooldown));
        // Call OnShoot event
        m_ShootEvents.OnShoot.Invoke(new ShootInfos
        {
            origin    = transform.position,
            direction = aimVector,
            range     = m_ShootRange,
            cooldown  = m_ShootCooldown,
            damages   = m_ShootDamages
        });

        // If the shot hit something
        if (Physics.Raycast(transform.position, aimVector, out RaycastHit rayHit, m_ShootRange, m_ShootableObjectsLayer))
        {
            HitInfos infos = new HitInfos
            {
                shooter  = gameObject,
                target   = rayHit.collider.gameObject,
                origin   = transform.position,
                impact   = rayHit.point,
                distance = rayHit.distance,
                damages  = m_ShootDamages
            };

            // Call OnHitTarget event
            m_ShootEvents.OnHitTarget.Invoke(infos);

            if (rayHit.collider.TryGetComponent(out Shootable shootable))
            {
                shootable.NotifyHit(infos);
                // If this character can gain score
                if (m_Scorer != null && shootable.ScoreByShot != 0)
                {
                    // Get score from the target if possible
                    m_Scorer.GainScore(shootable.ScoreByShot);
                }
            }

            #if UNITY_EDITOR
            if (m_EnableDebugLines)
            {
                Debug.DrawLine(transform.position, transform.position + aimVector * rayHit.distance, Color.red, m_DebugLineDuration);
            }
            #endif
        }
    ///<summary>
    /// Called when an object enters in this object's trigger.
    ///</summary>
    private void OnTriggerEnter(Collider _Other)
    {
        if (m_Collected)
        {
            return;
        }

        Scorer scorer = _Other.GetComponent <Scorer>();

        // If the entering entity can score
        if (scorer != null)
        {
            scorer.GainScore(m_Score);
        }

        m_Collected = true;
        m_OnCollect.Invoke(new CollectInfos()
        {
            score     = m_Score,
            position  = transform.position,
            collector = _Other.gameObject
        });
    }