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();
                }
            };
        }
Exemple #2
0
        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);
        }
Exemple #3
0
 void UpdateActiveUnit()
 {
     if (!batchSelection)
     {
         activeUnit = selectedUnits.Count > 0 ? selectedUnits[0] : null;
     }
 }
Exemple #4
0
 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
            };
        }
Exemple #6
0
 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();
                }
            };
        }
Exemple #10
0
        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);
                    }
                }
            }
        }
Exemple #11
0
 public void RemoveUnit(RTSUnit unit)
 {
     OnDeselected(unit);
     units.Remove(unit);
 }
Exemple #12
0
 public void AddUnit(RTSUnit unit)
 {
     units.Add(unit);
 }
Exemple #13
0
 public void OnDeselected(RTSUnit unit)
 {
     selectedUnits.Remove(unit);
     UpdateActiveUnit();
 }
Exemple #14
0
        // 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;
                }
            }
        }
Exemple #15
0
 public virtual void Attack(RTSUnit target)
 {
     lastAttackTime = Time.time;
 }
Exemple #16
0
 public virtual bool Aim(RTSUnit target)
 {
     return(Time.time - lastAttackTime >= cooldown);
 }