//called from GameControl when a unit is destroyed public void UnitDestroyed(Unit unit) { if(unit==null) return; //remove the destroyed unit from unitList unitList.Remove(unit); //if the unit's prefab is in prefabList, increase the corresponding kill count for(int i=0; i<prefabList.Count; i++){ if(unit.prefabID==prefabList[i].prefabID){ prefabKillCountList[i]+=1; break; } } //if unitList is cleared, check if objective is complete if(unitList.Count==0) CheckObjectiveComplete(); }
public AimInfo(Unit tgt) { //for a specific target (used by AI unit) unit=tgt; hitPoint=unit.thisT.position; targetT=unit.thisT; collider=unit.GetCollider(); }
public AimInfo(RaycastHit hit) { //from the raycast from the cursor used to aim at the target hitPoint=hit.point; targetT=hit.transform; collider=hit.collider; unit=targetT!=null ? hit.transform.GetComponent<Unit>() : null; }
//function call to fire the object public void Shoot(int srcL, float srcR, Transform shootPoint, AttackInstance aInstance=null, AimInfo aimInfo=null) { Init(); thisObj.SetActive(true); //cached all the passed information lcoally attInstance=aInstance; srcLayer=srcL; //the layer of the shooting unit (so we know it's from player or AI) srcRange=srcR; //the range of the shooting unit (so we know when to stop) state=_State.Shot; shootTime=Time.time; //to track how long the shoot object is has been travelledDistance=0; //to track how far the shoot object is has been fired //if there's any hideObject, set it to true (it's probably set to false when the shoot-object last hit something) if(hideObject!=null) hideObject.SetActive(true); //instantiate the shoot effect ShootEffect(thisT.position, thisT.rotation); if(type==_SOType.Simple || type==_SOType.Homing){ //if(aInstance!=null && thisCollider.enabled){ //~ Physics.IgnoreCollision(aInstance.srcUnit.GetCollider(), thisObj.GetComponent<Collider>(), true); //Debug.Log("collision avoidance with shooter unresolved"); //Physics.IgnoreCollision(srcCollider, thisCollider, true); //} // for homing shootobject, the shootobject needs to be aiming at some position, or a specific unit if(type==_SOType.Homing){ if(aimInfo.targetT!=null) targetUnit=aimInfo.unit; targetPos=aimInfo.hitPoint+new Vector3(Random.value-0.5f, 0, Random.value-0.5f)*2*spread; initialPos=shootPoint.position; initialDist=Vector3.Distance(targetPos, initialPos); curveMod=Random.Range(0, 2f); dummyPos=thisT.TransformPoint(Vector3.forward*speed*5); dummyPos=(targetPos+dummyPos)/2; } } else if(type==_SOType.Beam){ //if(attachedToShootPoint) transform.parent=shootPoint; thisT.parent=shootPoint; ObjectPoolManager.Unspawn(thisObj, beamDuration-.01f); } else if(type==_SOType.Point){ StartCoroutine(PointRoutine(aimInfo)); } //update the layermask used to do the hit detection in accordance to rules set in GameControl UpdateSphereCastMask(!GameControl.SOHitFriendly(), !GameControl.SOHitShootObject(), !GameControl.SOHitCollectible()); }
// Update is called once per frame void Update() { //if the shootobject is not in the shot state, dont continue if(type!=_SOType.Beam && state!=_State.Shot) return; float travelDistance=GetRangePerFrame(); //get the distance the shootobject travelled in this frame //do a sphere-cast to limit the travel distance in this frame so we dont over-shoot anything the shootobject might hit RaycastHit hit; if(Physics.SphereCast(thisT.position, hitRadius, thisT.forward, out hit, travelDistance, mask)){ travelDistance=Vector3.Distance(thisT.position, hit.point); } if(type==_SOType.Simple){ travelledDistance+=travelDistance; thisT.Translate(Vector3.forward * travelDistance); if(Time.time-shootTime>destroyTime) Hit(); if(travelledDistance>srcRange) OnTriggerEnter(null); } if(type==_SOType.Homing){ if(targetUnit!=null){ targetPos=targetUnit.thisT.position; Vector3 thisTempPos=thisT.position; thisTempPos.y=targetPos.y; Quaternion tgtRot=Quaternion.LookRotation(targetPos-thisTempPos); //if the target is too far off angle if(Mathf.Abs(thisT.rotation.eulerAngles.y-tgtRot.eulerAngles.y)>65){ targetPos=thisT.TransformPoint(0, 0, speed); targetPos.y=targetUnit.thisT.position.y; targetUnit=null; } else if(Time.time-shootTime>trackingDuration){ targetUnit=null; targetPos+=new Vector3(Random.value-0.5f, 0, Random.value-0.5f)*2*spread/2; } } float currentDist=Vector3.Distance(thisT.position, targetPos); float timeMultipler=(speed/initialDist)*0.125f; curveMod+=Time.deltaTime*timeMultipler; timeSinceFire+=Time.deltaTime*timeMultipler; dummyPos=Vector3.Lerp(dummyPos, targetPos, timeSinceFire); Quaternion wantedRot=Quaternion.LookRotation(dummyPos-thisT.position); thisT.rotation=Quaternion.Slerp(thisT.rotation, wantedRot, Time.deltaTime*speed*(1.5f+curveMod)); thisT.Translate(Vector3.forward * travelDistance); if(currentDist<hitRadius) OnTriggerEnter(null); } else if(type==_SOType.Beam){ if(shootThrough) travelDistance=GetRangePerFrame(); if(line!=null){ line.SetPosition(0, new Vector3(0, 0, 0)); line.SetPosition(1, new Vector3(0, 0, travelDistance)); } if(!shootThrough){ if(hit.collider!=null){ if(Time.time-lastHitCD>0.2f){ if(state==_State.Shot) HitEffect(hit.point); OnTriggerEnter(hit.collider); lastHitCD=Time.time; } if(continousEffect) state=_State.Shot; } } else{ if(Time.time-lastHitCD>0.1f){ lastHitCD=Time.time; RaycastHit[] hitList=Physics.SphereCastAll(thisT.position, hitRadius, thisT.forward, travelDistance); for(int i=0; i<hitList.Length; i++){ if(state==_State.Shot) HitEffect(hitList[i].point); state=_State.Shot; if(hitList[i].collider!=null) OnTriggerEnter(hitList[i].collider); } if(continousEffect) state=_State.Shot; } } } }
private Wave waveE = null; //the current wave used in endless mode #endregion Fields #region Methods //track unit public void AddUnit(Unit unitInstance) { //set destroy callback for the unit unitInstance.SetDestroyCallback(this.UnitDestroy); spawnCount+=1; activeCount+=1; }
//called from unit to add the new SpawnUponDestroy unit to the parent unit's wave public void AddUnitToWave(Unit unitInstance) { waveList[unitInstance.waveID].activeUnitCount+=1; AddUnit(unitInstance); }
protected Vector2 DrawUnitBaseStats(float startX, float startY, Unit unit, bool isPlayer) { TDSEditorUtility.DrawSprite(new Rect(startX, startY, 60, 60), unit.icon); startX+=65; float offsetY=TDSEditor.IsPrefab(unit.gameObject) ? 5 : 0 ; cont=new GUIContent("Name:", "The unit name to be displayed in game"); EditorGUI.LabelField(new Rect(startX, startY+=offsetY, width, height), cont); unit.unitName=EditorGUI.TextField(new Rect(startX+spaceX-65, startY, width-5, height), unit.unitName); cont=new GUIContent("Icon:", "The unit icon to be displayed in game, must be a sprite"); EditorGUI.LabelField(new Rect(startX, startY+=spaceY, width, height), cont); unit.icon=(Sprite)EditorGUI.ObjectField(new Rect(startX+spaceX-65, startY, width-5, height), unit.icon, typeof(Sprite), false); if(TDSEditor.IsPrefab(unit.gameObject)){ cont=new GUIContent("Prefab:", "The prefab object of the unit\nClick this to highlight it in the ProjectTab"); EditorGUI.LabelField(new Rect(startX, startY+=spaceY, width, height), cont); EditorGUI.ObjectField(new Rect(startX+spaceX-65, startY, width-5, height), unit.gameObject, typeof(GameObject), false); } else{ EditorGUI.HelpBox(new Rect(startX, startY+=spaceY, width+spaceX-65, height+5), "The unit being edited is not a prefab", MessageType.Warning); startY+=5; } startX-=65; startY+=spaceY; EditorGUI.LabelField(new Rect(startX, startY+=spaceY, width, height), "Basic Stats", headerStyle); startY+=5; cont=new GUIContent("Hit Point:", "The hit-point capacity of the unit"); EditorGUI.LabelField(new Rect(startX, startY+=spaceY, width, height), cont); unit.hitPointFull=EditorGUI.FloatField(new Rect(startX+spaceX, startY, 40, height), unit.hitPointFull); unit.startHitPointAtFull=EditorGUI.Toggle(new Rect(startX+spaceX+50, startY, 40, height), unit.startHitPointAtFull); EditorGUI.LabelField(new Rect(startX+spaceX+65, startY, width, height), " - start at full"); cont=new GUIContent("Hit Point Regen:", "The amount of hit-point regenerated per second"); EditorGUI.LabelField(new Rect(startX, startY+=spaceY, width, height), cont); unit.hpRegenRate=EditorGUI.FloatField(new Rect(startX+spaceX, startY, 40, height), unit.hpRegenRate); cont=new GUIContent("Hit Point Stagger:", "The duration in second in which the hit-point regen would stop after the unit being hit"); EditorGUI.LabelField(new Rect(startX, startY+=spaceY, width, height), cont); if(unit.hpRegenRate>0) unit.hpRegenStagger=EditorGUI.FloatField(new Rect(startX+spaceX, startY, 40, height), unit.hpRegenStagger); else EditorGUI.LabelField(new Rect(startX+spaceX, startY, 40, height), "-"); if(isPlayer){ startY+=10; cont=new GUIContent("Energy:", "The energy capacity of the unit"); EditorGUI.LabelField(new Rect(startX, startY+=spaceY, width, height), cont); unit.energyFull=EditorGUI.FloatField(new Rect(startX+spaceX, startY, 40, height), unit.energyFull); unit.startEnergyAtFull=EditorGUI.Toggle(new Rect(startX+spaceX+50, startY, 40, height), unit.startEnergyAtFull); EditorGUI.LabelField(new Rect(startX+spaceX+65, startY, width, height), " - start at full"); cont=new GUIContent("Energy Rate:", "The rate (per second) in which the energy will recharge"); EditorGUI.LabelField(new Rect(startX, startY+=spaceY, width, height), cont); unit.energyRate=EditorGUI.FloatField(new Rect(startX+spaceX, startY, 40, height), unit.energyRate); } startY+=10; cont=new GUIContent("Armor Type:", "The armor type of the unit\nArmor type can be configured in Damage Armor Table Editor"); EditorGUI.LabelField(new Rect(startX, startY+=spaceY, width, height), cont); if(armorTypeLabel.Length>0) unit.armorType=EditorGUI.Popup(new Rect(startX+spaceX, startY, width, height), unit.armorType, armorTypeLabel); else{ if(GUI.Button(new Rect(startX+spaceX, startY, 83, height-2), "Add Type")){ DamageTableEditorWindow.Init(); } } return new Vector2(startX, startY); }
public static void NewUnit(Unit unit) { if(onNewUnitE!=null) onNewUnitE(unit); }
void Awake() { instance = (Unit)target; LoadDB(); }
protected Vector2 DrawDestroyEffectObj(float startX, float startY, Unit unit) { cont=new GUIContent("DestroyCamShake:", "The camera shake magnitude whenever the unit is destroyed"); EditorGUI.LabelField(new Rect(startX, startY, width, height), cont); unit.destroyCamShake=EditorGUI.FloatField(new Rect(startX+spaceX, startY, 40, height), unit.destroyCamShake); startY+=10; cont=new GUIContent("DestroyedEffectObj:", "The object to be spawned when the unit is destroyed (optional)"); EditorGUI.LabelField(new Rect(startX, startY+=spaceY, width, height), cont); unit.destroyedEffectObj=(GameObject)EditorGUI.ObjectField(new Rect(startX+spaceX, startY, width, height), unit.destroyedEffectObj, typeof(GameObject), false); cont=new GUIContent("AutoDestroy Effect:", "Check if the effect object needs to be removed from the game"); EditorGUI.LabelField(new Rect(startX, startY+=spaceY, width, height), cont); if(unit.destroyedEffectObj!=null){ unit.autoDestroyDObj=EditorGUI.Toggle(new Rect(startX+spaceX, startY, 40, height), unit.autoDestroyDObj); if(unit.autoDestroyDObj){ cont=new GUIContent(" - Duration:", "The delay in seconds before the effect object is destroyed"); EditorGUI.LabelField(new Rect(startX+spaceX+15, startY, width, height), cont); unit.dObjActiveDuration=EditorGUI.FloatField(new Rect(startX+spaceX+width-58, startY, 40, height), unit.dObjActiveDuration); } } else EditorGUI.LabelField(new Rect(startX+spaceX, startY, 40, height), "-"); return new Vector2(startX, startY); }
public bool isAOE = false; //marked if the attack is AOE #endregion Fields #region Constructors //create a new attackInstance, given the AttackStats (the set of stats for the attack unit or ability) public AttackInstance(Unit src=null, AttackStats aSt=null) { aStats=aSt; }
//remove unit from tracker (call by every hostile unit upon deactivation) public static void RemoveUnit(Unit unit) { allUnitList.Remove(unit); }
//add unit to be tracked (called by every hostile unit upon activation) public static void AddUnit(Unit unit) { if(allUnitList.Contains(unit)) return; allUnitList.Add(unit); }
public void _UnitDestroyed(Unit unit) { if(objective!=null) objective.UnitDestroyed(unit); }
//call to inform objective that a unit has been destroyed public static void UnitDestroyed(Unit unit) { if(instance!=null) instance._UnitDestroyed(unit); }