UnityGameProjectsCode / RelianceGame / Player Control / PlayerShoot.cs
PlayerShoot.cs
Raw
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class PlayerShoot : MonoBehaviour
{
    private LineRenderer laserLine;
    public List<Material> lasers = new List<Material>();
    private RaycastHit hit;
    private Ray ray;
    GraphicRaycaster canvasCaster;
    EventSystem eventSys;
    PointerEventData pointData;
    private GameManager gameManager;
    private SoundManager soundMgr;
    private BotStats botStats;
    private DisplayLog displayLog;
    private AudioSource audioS;
    private bool hitCanvas;
    public GameObject marker;
    private Animator animator;
    private MouseReload mReload;
    public ParticleSystem laserParticles;
    private Light barrelLight;
    public GameObject impactObject;
    private PlayerCallForHelp pCall;

    public Transform barrelEnd; //manually added object to determine end of barrel
    public Transform turretPos; //manually added object to determine turret rotation
    public Transform barrelPos; //manually added object to determine barrel rotation

    public bool shooting = false;
    private float fireRate = 2f;
    private float timeBetweenShots = 0f;
    public float physicsImpactForce;
    public float turretRotateSpeed;
    public float barrelMoveSpeed;
    public int critChance;
    public int heavyHitChance;
    public int heavyHitModifier;

    void Start()
    {
        laserLine = GetComponent<LineRenderer>();
        laserLine.enabled = false;
        gameManager = GameObject.Find("Persistent Object").GetComponent<GameManager>();
        soundMgr = GameObject.Find("Persistent Object").GetComponent<SoundManager>();
        botStats = GetComponent<BotStats>();
        canvasCaster = GameObject.Find("RunningUI").GetComponent<GraphicRaycaster>();
        eventSys = GameObject.Find("EventSystem").GetComponent<EventSystem>();
        displayLog = GameObject.Find("RunningUI/Text Log/Log Panel/Content").GetComponent<DisplayLog>();
        pCall = GetComponent<PlayerCallForHelp>();
        animator = GetComponent<Animator>();
        audioS = GetComponent<AudioSource>();
        mReload = GameObject.Find("RunningUI/Mouse Base").GetComponent<MouseReload>();
        barrelLight = barrelEnd.gameObject.GetComponent<Light>();
        hitCanvas = false;
        barrelLight.enabled = false;
    }

    void Update()
    {
        FollowMouse();

        if (shooting == true)
        {
            timeBetweenShots += Time.deltaTime;

            if (!animator.GetCurrentAnimatorStateInfo(2).IsName("BarrelLightFlash"))
            {
                laserLine.enabled = false;
                barrelLight.enabled = false;
            }

            if (timeBetweenShots >= fireRate)
            {
                timeBetweenShots = 0.0f;
                shooting = false;

                mReload.PlayReloadSound();
                mReload.ResetAnim();
            }
        }


        if (Input.GetButtonDown("Fire Cannon")) //use a canvas raycast to detect if the item being clicked is a button, if not, shoot
        {
            pointData = new PointerEventData(eventSys);
            pointData.position = Input.mousePosition;

            List<RaycastResult> results = new List<RaycastResult>();

            canvasCaster.Raycast(pointData, results);

            foreach (RaycastResult result in results)
            {
                if (result.gameObject.GetComponent<Button>())
                {
                    hitCanvas = true;
                    break;
                }
            }

            if (!hitCanvas)
            {
                Shoot();
            }

            hitCanvas = false;
        }
    }

    void Shoot() //draw a ray out from the player and damage the enemy
    {
        RaycastHit hit;

        if (Physics.Raycast(barrelEnd.position, barrelEnd.forward, out hit) && !shooting)
        {
            laserLine.SetPosition(0, barrelEnd.position);
            laserLine.SetPosition(1, hit.point);
            int randomLaserMat = Random.Range(0, 5);
            laserLine.material = lasers[randomLaserMat];
            shooting = true;
            timeBetweenShots = 0.0f;
            Instantiate(impactObject, hit.point, Quaternion.identity, gameObject.transform.parent);
            laserLine.enabled = true;
            barrelLight.enabled = true;

            float adjustedAnimSpeed = 1.0f;

            for (float i = 2f; i >= fireRate; i -= 0.1f)
            {
                adjustedAnimSpeed += 0.01f;
            }

            animator.SetFloat("fireSpeed", adjustedAnimSpeed);

            mReload.SetAnimSpeed(adjustedAnimSpeed);
            mReload.PlayReload();

            animator.Play("PlayerShoot", 0);
            animator.Play("LaserMove", 1);
            animator.Play("BarrelLightFlash", 2);
            laserParticles.Play();

            float pitchVariance = Random.Range(0.80f, 1.20f);

            audioS.pitch = pitchVariance;
            audioS.PlayOneShot(GetComponent<MultipleAudioClips>().clips[1]);
            ApplyForce(hit);
            DealDamage(hit);
        }
    }

    private void ApplyForce(RaycastHit hit)
    {
        if ((hit.collider.gameObject.name.Contains("Box") || hit.collider.gameObject.name.Contains("Barrel") || hit.collider.gameObject.name.Contains("BotModelDestroyed")) && hit.collider.gameObject.tag == "Prop")
        {
            hit.collider.gameObject.GetComponent<Rigidbody>().AddExplosionForce(physicsImpactForce, hit.point, 10);
        }
    }

    private void DealDamage(RaycastHit hit)
    {
        GameObject hitObject = hit.collider.gameObject;

        if (hitObject.CompareTag("Enemy"))
        {
            pCall.OnShotGetEnemy(hitObject);
            soundMgr.StartMusicCouroutine();

            EnemyAIMachine enemyHit = hitObject.GetComponent<EnemyAIMachine>();
            Health enemyHP = hitObject.GetComponent<Health>();

            int randCritChance = Random.Range(0, 100);
            int randHeavyHitChance = Random.Range(0, 100);

            if (randCritChance <= critChance)
            {
                int hitDamage = 2;

                if (randHeavyHitChance <= heavyHitChance)
                    hitDamage += heavyHitModifier;

                enemyHP.HealthReduce(hitDamage);
            }
            else
            {
                int hitDamage = 1;

                if (randHeavyHitChance <= heavyHitChance)
                    hitDamage += heavyHitModifier;

                enemyHP.HealthReduce(hitDamage);
            }

            hitObject.GetComponent<AudioSource>().PlayOneShot(hitObject.GetComponent<MultipleAudioClips>().clips[0]);

            enemyHit.enemyObject = gameObject;
            enemyHit.canSeeEnemy = true;

            if (enemyHP.health <= 0)
            {
                if (enemyHit.turretBot)
                    gameManager.OnTurretKill(enemyHit.gameObject);
                else
                    gameManager.OnKill(enemyHit.gameObject);

                displayLog.RecieveLog(enemyHit.displayName + " was destroyed", Color.red);
                pCall.SetEnemyNull();
                botStats.KillExpIncrease(hitObject);

                hitObject.SetActive(false);
            }
        }
        else if (hitObject.CompareTag("EnemyStructure"))
        {
            soundMgr.StartMusicCouroutine();

            StructureInfo enemyHit = hitObject.GetComponent<StructureInfo>();
            Health enemyHP = hitObject.GetComponent<Health>();

            int randCritChance = Random.Range(0, 100);
            int randHeavyHitChance = Random.Range(0, 100);

            if (randCritChance <= critChance)
            {
                int hitDamage = 2;

                if (randHeavyHitChance <= heavyHitChance)
                    hitDamage += heavyHitModifier;

                enemyHP.HealthReduce(hitDamage);
            }
            else
            {
                int hitDamage = 1;

                if (randHeavyHitChance <= heavyHitChance)
                    hitDamage += heavyHitModifier;

                enemyHP.HealthReduce(hitDamage);
            }

            hitObject.GetComponent<AudioSource>().PlayOneShot(hitObject.GetComponent<MultipleAudioClips>().clips[0]);

            if (enemyHP.health <= 0)
            {
                gameManager.OnStructureDestroy(enemyHit.gameObject);
                displayLog.RecieveLog(enemyHit.displayName + " was destroyed", Color.red);
                pCall.SetEnemyNull();
                botStats.KillExpIncrease(hitObject);

                hitObject.SetActive(false);
            }
        }
    }

    private void FollowMouse() //called from update to have the turret and barrel of the bot follow the mouse
    {
        //create a var to hold the raycast hit data
        RaycastHit hit;

        //create a ray from the screen to the mouse position
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

        int layer = 1 << 9;

        layer = ~layer;
        float distance = float.MaxValue;
        //if the ray hits something, do this
        if (Physics.Raycast(ray, out hit, distance, layer, QueryTriggerInteraction.Ignore))
        {
            //create a vector3 var to hold the location of the hit
            Vector3 hitPos = hit.point;

            //create a quaternion to store the rotation for the bot to the mouse pos
            Quaternion hitRot = Quaternion.LookRotation(hitPos - transform.position);

            //create a quaternion to store the rotation for the turret to the mouse pos
            Quaternion turretRot = Quaternion.LookRotation(hitPos - turretPos.transform.position);

            //Have the turret rotate towards the hit point using the hitRot var, use delta time to smooth travel
            turretPos.transform.rotation = Quaternion.RotateTowards(turretPos.transform.rotation, hitRot, Time.deltaTime * turretRotateSpeed);

            //set the euler angles of the turret so that the turret will only move on the y axis
            turretPos.transform.localEulerAngles = new Vector3(0, turretPos.transform.localEulerAngles.y, 0);

            //Have the barrel rotate move up or down to point at the hit point, smoothed, using the turrets transform as the height of the barrel from the hit point
            barrelPos.transform.rotation = Quaternion.RotateTowards(barrelPos.transform.rotation, turretRot, Time.deltaTime * barrelMoveSpeed);

            //set the euler angles of the barrel so that it will only rotate on the y axis
            barrelPos.transform.localEulerAngles = new Vector3(0, barrelPos.transform.localEulerAngles.y, 0);
        }
    }

    public float GetFireRate()
    {
        return fireRate;
    }

    public void SetFireRate(float newRate)
    {
        fireRate = newRate;
    }
}