using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.EventSystems; public class CannonScript : MonoBehaviour { [SerializeField] private GameObject cannon; [SerializeField] private GameObject projectile; [SerializeField] private float lookDepth; [SerializeField] private float cannonForce; [SerializeField] private float fireRate = 0.5f; [SerializeField]private float fireTimer; private bool firing = false; [SerializeField]private float damage = 1f; private Vector3 lookDir; private Vector3[] offsets; [SerializeField]private int bullets; // Start is called before the first frame update void Start() { lookDir = Vector3.zero; offsets = new Vector3[] { new Vector3(-0.1f, 0), new Vector3(0.1f, 0), new Vector3(0, -0.1f), new Vector3(0, 0.1f) }; bullets = 1; } // Update is called once per frame void Update() { Debug.DrawRay(transform.position, lookDir * Mathf.Infinity, Color.red); if (firing && !EventSystem.current.IsPointerOverGameObject()){ fireTimer += Time.deltaTime; if(fireTimer >= fireRate){ Fire(); fireTimer = 0; } }else if(fireTimer < fireRate){ fireTimer += Time.deltaTime; } } void Fire(){ GameObject proj = Instantiate(projectile, cannon.transform.position, cannon.transform.rotation); proj.GetComponent().SetDamage(damage); proj.GetComponent().AddForce(cannonForce * lookDir, ForceMode.Impulse); proj.layer = GameManager.Instance.GetCurrentLayerID(); RaycastHit hit; if (Physics.Raycast(transform.position, lookDir, out hit, Mathf.Infinity, GameManager.Instance.GetCurrentDimensionLayerMask())) { Debug.DrawRay(transform.position, lookDir * hit.distance, Color.yellow, 0.5f); GameObject hitObject = hit.collider.gameObject; if (hitObject.CompareTag("Enemy")) { hitObject.GetComponent().IsShot(hit.distance, damage); } } if(bullets > 1){ //Pick random offset from lookDir for (int i = 0; i < bullets-1; i++) { proj = Instantiate(projectile, cannon.transform.position, cannon.transform.rotation); proj.GetComponent().SetDamage(damage); proj.GetComponent().AddForce(cannonForce * (lookDir+offsets[i]), ForceMode.Impulse); if (Physics.Raycast(transform.position, (lookDir+offsets[i]), out hit, Mathf.Infinity)) { Debug.DrawRay(transform.position, (lookDir+offsets[i]) * hit.distance, Color.yellow, 0.5f); GameObject hitObject = hit.collider.gameObject; if (hitObject.CompareTag("Enemy")) { hitObject.GetComponent().IsShot(hit.distance, damage); } } } } } private Vector3 GetMouseWorldPosition(){ Vector3 screenPos = Mouse.current.position.ReadValue(); Ray ray = Camera.main.ScreenPointToRay(screenPos); RaycastHit hit; Vector3 worldPoint = Vector3.zero; if (Physics.Raycast(ray, out hit)) { if(hit.transform.gameObject.CompareTag("Enemy")){ worldPoint = hit.point; }else{ screenPos.z = lookDepth; worldPoint = Camera.main.ScreenToWorldPoint(screenPos); } } if(worldPoint == Vector3.zero){ screenPos.z = lookDepth; worldPoint = Camera.main.ScreenToWorldPoint(screenPos); } return worldPoint; } public void OnLook(InputAction.CallbackContext ctx){ Vector3 bodyLookPos= GetMouseWorldPosition(), cannonLookPos = GetMouseWorldPosition(); bodyLookPos.y = 0; gameObject.transform.LookAt(bodyLookPos); cannon.transform.LookAt(cannonLookPos); lookDir = (cannonLookPos - transform.position).normalized; } public void OnFire(InputAction.CallbackContext ctx){ if(ctx.started){//btn pressed firing = true; }else if(ctx.canceled){//btn released firing = false; } } public void SetFireRate(float nFireRate){ this.fireRate = nFireRate; } public float GetFireRate(){ return fireRate; } public void SetDamage(float dmg){ this.damage = dmg; } public float GetDamage(){ return damage; } public void SetBullets(int nBullets){ this.bullets = nBullets; } public int GetBullets(){ return bullets; } }