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; } }