void Awake() { unit = GetComponent <RTSUnit>(); unit.onMakeActiveUnit += (bool active) => { if (active) { menu = RTSUI.active.ShowMenu(); for (int i = 0; i < items.Length; i++) { var item = items[i]; menu.AddItem(item.menuItem, () => { if (queue.Count >= maxQueueSize) { return; } if (RTSManager.instance.GetPlayer(1).resources.GetResource(RTSUnit.Type.ResourceCrystal) < item.cost) { RTSManager.instance.audio.Play(RTSUI.active.notEnoughResources); } else { RTSManager.instance.GetPlayer(1).resources.AddResource(RTSUnit.Type.ResourceCrystal, -item.cost); AddToQueue(item); } }); } } else if (menu != null) { menu.Hide(); } }; }
RTSUnit FindClosest(Vector3 point) { var units = RTSManager.instance.units.units; RTSUnit closest = null; var dist = float.PositiveInfinity; for (int i = 0; i < units.Count; i++) { var unit = units[i]; if (unit.type != type || (reserve && unit.reservedBy != null)) { continue; } if (unit.resource != null && !unit.resource.harvestable) { continue; } var d = (unit.transform.position - point).sqrMagnitude; if (d < dist) { dist = d; closest = unit; } } return(closest); }
void UpdateActiveUnit() { if (!batchSelection) { activeUnit = selectedUnits.Count > 0 ? selectedUnits[0] : null; } }
public void OnSelected(RTSUnit unit) { if (!selectedUnits.Contains(unit)) { selectedUnits.Add(unit); } UpdateActiveUnit(); }
void Awake() { unit = GetComponent <RTSUnit>(); animator = GetComponent <Animator>(); ctx = new BTContext { animator = animator, transform = transform, unit = unit }; }
public void SetDestination(Vector3 destination, MovementMode mode) { if (ai != null && this) { reachedDestination = false; movementMode = mode; ai.destination = lastDestination = destination; (ai as AIBase).rvoDensityBehavior.ClearDestinationReached(); ai.SearchPath(); if (mode == MovementMode.Move) { attackTarget = null; } } }
public override bool Aim(RTSUnit target) { bool rotationDone = true; if (rotationRootY != null) { var dir = target.transform.position - rotationRootY.position; dir.y = 0; var targetRot = Quaternion.LookRotation(dir); rotationRootY.rotation = Quaternion.RotateTowards(rotationRootY.rotation, targetRot, rotationSpeed * Time.deltaTime); rotationDone = Quaternion.Angle(targetRot, rotationRootY.rotation) < rotationSpeed * 0.1f; } return(base.Aim(target) && rotationDone); }
public override void Attack(RTSUnit target) { base.Attack(target); if (sfx.Length > 0) { AudioSource.PlayClipAtPoint(sfx[Random.Range(0, sfx.Length)], transform.position, volume); } if (sourceEffect != null) { GameObject.Instantiate(sourceEffect, sourceEffectRoot != null ? sourceEffectRoot.position : transform.position, sourceEffectRoot != null ? sourceEffectRoot.rotation : Quaternion.LookRotation(target.transform.position - transform.position, Vector3.up)); } if (targetEffect != null) { GameObject.Instantiate(targetEffect, target.transform.position, Quaternion.LookRotation(transform.position - target.transform.position, Vector3.up)); } target.ApplyDamage(damage); }
void Awake() { unit = GetComponent <RTSUnit>(); unit.onMakeActiveUnit += (bool active) => { if (active) { menu = RTSUI.active.ShowMenu(); for (int i = 0; i < items.Length; i++) { var item = items[i]; menu.AddItem(item.menuItem, () => { RTSUI.active.StartBuildingPlacement(item); }); } } else if (menu != null) { menu.Hide(); } }; }
void HandleSelection() { var overUI = UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject(); if (state != State.Normal && state != State.Dragging) { return; } if (!overUI && Input.GetKeyDown(KeyCode.Mouse0)) { dragStart = Input.mousePosition; state = State.Dragging; hasSelected = false; } if (state == State.Dragging) { Vector2 dragEnd = Input.mousePosition; var mn = Vector2.Min(dragStart, dragEnd); var mx = Vector2.Max(dragStart, dragEnd); var rect = Rect.MinMaxRect(mn.x, mn.y, mx.x, mx.y); bool isSelecting = (dragEnd - dragStart).magnitude > 5; hasSelected |= isSelecting; selectionBox.gameObject.SetActive(isSelecting); if (isSelecting) { selectionBox.offsetMin = Vector2.Min(dragStart, dragEnd); selectionBox.offsetMax = Vector2.Max(dragStart, dragEnd); } if (!Input.GetKey(KeyCode.Mouse0)) { state = State.Normal; selectionBox.gameObject.SetActive(false); if (isSelecting) { RTSManager.instance.units.SetSelection(unit => { var screenPos = RTSManager.instance.units.cam.WorldToScreenPoint(unit.transform.position); return(rect.Contains(screenPos)); }); } else { // Clicking var hit = RaycastScreenPoint(dragEnd, -1); var p = hit.point; float clickFuzzDistance = 0.1f; float minDist = 0; RTSUnit minUnit = hit.collider != null?hit.collider.gameObject.GetComponentInParent <RTSUnit>() : null; if (minUnit == null) { foreach (var unit in RTSManager.instance.units.units) { var dir = unit.transform.position - p; dir.y = 0; var dist = dir.magnitude - unit.radius - clickFuzzDistance; if (dist < minDist) { minDist = dist; minUnit = unit; } } } RTSManager.instance.units.SetSelection(u => u == minUnit); } } else if (hasSelected) { foreach (var unit in RTSManager.instance.units.units) { var screenPos = RTSManager.instance.units.cam.WorldToScreenPoint(unit.transform.position); unit.selectionIndicatorEnabled = rect.Contains(screenPos); } } } }
public void RemoveUnit(RTSUnit unit) { OnDeselected(unit); units.Remove(unit); }
public void AddUnit(RTSUnit unit) { units.Add(unit); }
public void OnDeselected(RTSUnit unit) { selectedUnits.Remove(unit); UpdateActiveUnit(); }
// Update is called once per frame protected virtual void OnUpdate(List <RTSUnit>[] unitsByOwner) { if (ai == null) { // Stationary unit if (weapon != null) { float minDist = detectionRange * detectionRange; for (int player = 0; player < unitsByOwner.Length; player++) { if (!owner.IsHostile(RTSManager.instance.GetPlayer(player))) { continue; } for (int i = 0; i < unitsByOwner[player].Count; i++) { var unit = unitsByOwner[player][i]; var dist = (unit.position - position).sqrMagnitude; if (dist < minDist) { attackTarget = unit; minDist = dist; } } } if (attackTarget != null) { if (!weapon.InRangeOf(attackTarget.position)) { attackTarget = null; } else { if (weapon.Aim(attackTarget)) { weapon.Attack(attackTarget); } } } } if (attackTarget != null) { lastSeenAttackTarget = Time.time; } } else { rvo.locked = false | locked; // this.reachedDestination will be true once the AI has reached its destination // and it will stay true until the next time SetDestination is called. reachedDestination |= (ai as AIBase).rvoDensityBehavior.reachedDestination; if (weapon != null) { bool canAttack = movementMode == MovementMode.AttackMove; // This takes into account path calculations as well as if the AI stops far away from the destination due to being part of a large group canAttack |= reachedDestination && movementMode == MovementMode.Move; if (canAttack) { float minDist = detectionRange * detectionRange; Profiler.BeginSample("Distance"); var pos = position; for (int player = 0; player < unitsByOwner.Length; player++) { if (!owner.IsHostile(RTSManager.instance.GetPlayer(player))) { continue; } var enemies = unitsByOwner[player]; for (int i = 0; i < enemies.Count; i++) { var enemy = enemies[i]; var dist = (enemy.position - pos).sqrMagnitude; if (dist < minDist) { attackTarget = enemy; minDist = dist; } } } Profiler.EndSample(); float rangeFuzz = 1.1f; if (attackTarget != null && (attackTarget.position - position).magnitude > detectionRange * rangeFuzz) { attackTarget = null; } bool wantsToAttack = false; if (attackTarget != null) { if (!weapon.InRangeOf(attackTarget.position)) { ai.destination = attackTarget.position; } else { wantsToAttack = true; if (weapon.Aim(attackTarget)) { weapon.Attack(attackTarget); } } } if (attackTarget != null) { lastSeenAttackTarget = Time.time; } if (!weapon.canMoveWhileAttacking && (wantsToAttack || weapon.isAttacking)) { rvo.locked = true; } } } // Move back to original destination in case we followed an enemy for some time if (Time.time - lastSeenAttackTarget > 2) { ai.destination = lastDestination; } } }
public virtual void Attack(RTSUnit target) { lastAttackTime = Time.time; }
public virtual bool Aim(RTSUnit target) { return(Time.time - lastAttackTime >= cooldown); }