using System.Collections; using System.Collections.Generic; using UnityEngine; namespace TBTK{ public class ShootObject : MonoBehaviour { #if UNITY_EDITOR public static bool inspector=false; #endif public enum _Type{ Projectile, Beam, Effect, Missile, } public _Type type; public delegate void HitCallback(); public HitCallback hitCallback; [Header("Projectile & Missile")] public float speed=10; public float elevation=2; //how elevated the shoot trajectory is (x-axis) public float swerve=2; //how elevated the shoot trajectory is (y-axis) public float falloffRange=1; //below this range, the elevation will gradually decrease, try set to match the max range of the tower private float eta=1; //estimated time to hit target, used to adjust offsetPos during runtime private float effElevation=1; //actual elevation used in runtime, recalculated based on falloffRange private float effSwerve=0; //actual elevation used in runtime, recalculated based on falloffRange //offset to the targetPos for the SO to aim for, adjust in runtime to create a trajectory //it's always (0, value, 0), and value is consistently droping as the SO approach the target, making the SO aim above the target and drops overtime private Vector3 offsetPos=Vector3.zero; [Space(5)] public List trailList=new List(); private Vector3 shootDir; private Vector3 shootDirP; [Header("Beam")] public List lines=new List(); public float beamDuration=0.5f; public float startWidth=0.25f; private List linePos=new List{ Vector3.zero, Vector3.zero }; private Vector3 tgtPos; [Header("Effect")] public float effectDuration=0.5f; public bool attachToShootPoint=false; [Header("Visual and Audio")] public VisualObject effectShoot=new VisualObject(); public VisualObject effectHit=new VisualObject(); public AudioClip shootSound; public AudioClip hitSound; [Header("Runtime Attribute (For Debugging)")] public Unit tgtUnit; public float tgtRadius=0; public Vector3 targetPos; //public AttackInfo attackInfo; public float shootTime; public Transform shootPoint; private bool shot=false; private bool hit=false; protected GameObject thisObj; //public GameObject GetObj(){ return thisObj; } protected Transform thisT; //public Transform GetT(){ return thisT; } public Vector3 GetPos(){ return thisT!=null ? thisT.position : transform.position ; } public Quaternion GetRot(){ return thisT!=null ? thisT.rotation : transform.rotation ; } public void Awake(){ thisT=transform; thisObj=gameObject; if(type==_Type.Beam){ for(int i=0; itgtRadius) thisT.Translate(dir*Mathf.Min(Time.deltaTime*speed, dist), Space.World); else Hit(GetPos()); } else if(type==_Type.Beam){ float durRemain=Mathf.Clamp(beamDuration-(Time.time-shootTime), 0, beamDuration); if(durRemain<=0) Hit(ModifyTargetPosWithTgtRadius()); else{ for(int i=0; ieffectDuration){ Hit(ModifyTargetPosWithTgtRadius()); } } } void Hit(Vector3 hitPos){ if(hit) return; hit=true; effectHit.Spawn(hitPos, Quaternion.identity); AudioManager.PlaySound(hitSound); //if(attackInfo!=null && tgtUnit!=null) tgtUnit.ApplyAttack(attackInfo); if(hitCallback!=null) hitCallback(); ObjectPoolManager.Unspawn(thisObj); } Vector3 ModifyTargetPosWithTgtRadius(){ Vector3 dir=(GetPos()-targetPos).normalized; return targetPos+dir*tgtRadius; } public float GetElevationAngle(Vector3 sPos, Vector3 tPos){ if(type!=_Type.Projectile) return 0; float dist=Vector3.Distance(sPos, tPos); float elev=elevation*Mathf.Clamp((dist-(falloffRange*.5f))/falloffRange, 0, 1); return -Mathf.Atan(elev/dist)*Mathf.Rad2Deg; } void OnDrawGizmos(){ Gizmos.DrawLine(GetPos(), targetPos); } } }