Exemple #1
0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //  Called every frame. Scales down the unit's transform if its dead &
    //  Despawn when finished.
    /// </summary>
    private void UpdateDeathShrinker()
    {
        // Check if the unit should be shrinking
        if (_StartShrinking && !IsAlive() && ShrinkWhenDestroyed)
        {
            // Get in the cold ass water
            transform.localScale -= Vector3.one * ShrinkSpeed * Time.deltaTime;
            if (transform.localScale.x < 0.01f)
            {
                // Deselect / De-highlight
                if (_Player)
                {
                    _Player.RemoveFromSelection(this);
                }
                SetIsHighlighted(false);
                SetIsSelected(false);

                // MAXIMUM shrinkage
                _StartShrinking = false;

                // This is so that the next time the object is spawned - it is at its default state already
                _ObjectState = WorldObjectStates.Default;

                // Despawn the object
                transform.localScale = new Vector3(1f, 1f, 1f);
                ObjectPooling.Despawn(gameObject);
            }
        }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //  Called each frame.
    /// </summary>
    private void Update()
    {
        if (_UnitAttached != null && _CameraAttached != null)
        {
            // Unit is alive - display the widget
            if (_UnitAttached.IsInWorld() && _UnitAttached.GetVeterancyLevel() > 0)
            {
                // Update text
                _TextComponent.text = _UnitAttached.GetVeterancyLevel().ToString();

                // Set world space position
                Vector3 pos = _UnitAttached.transform.position + Offsetting;
                pos.y = pos.y + _UnitAttached.GetObjectHeight();
                transform.position = pos;

                // Constantly face the widget towards the camera
                transform.LookAt(2 * transform.position - _CameraAttached.transform.position);
            }

            // Object is dead/destroyed
            else
            {
                ObjectPooling.Despawn(gameObject);
            }
        }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //  Called each frame.
    /// </summary>
    private void Update()
    {
        if (_WorldObject != null && _CameraAttached != null)
        {
            // Only show widget if the object is currently being built (or in queue)
            if (_WorldObject.GetObjectState() == Abstraction.WorldObjectStates.Building ||
                _WorldObject.GetObjectState() == Abstraction.WorldObjectStates.InQueue)
            {
                // Update text to show how much time is remaining in the build
                int    time         = (int)_WorldObject.GetCurrentBuildTimeRemaining();
                string healthString = time.ToString();
                _TextComponent.text = healthString;

                // Set world space position
                Vector3 pos = _WorldObject.transform.position + Offsetting;
                pos.y = pos.y + _WorldObject.GetObjectHeight();
                transform.position = pos;

                // Constantly face the widget towards the camera
                transform.LookAt(2 * transform.position - _CameraAttached.transform.position);
            }

            // Destroy prefab instance as we no longer need it anymore
            else
            {
                ObjectPooling.Despawn(this.gameObject);
            }
        }
    }
Exemple #4
0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //
    /// </summary>
    /// <returns>
    //  IEnumerator
    /// </returns>
    private IEnumerator DelayedExplosion()
    {
        // Delay
        float normalizedTime = 0f;

        while (normalizedTime <= 1f)
        {
            normalizedTime += Time.deltaTime / CannisterLeakTime;
            yield return(null);
        }

        // Stop leaking & explode
        if (_CannisterLeakEffect != null)
        {
            _CannisterLeakEffect.Stop();
        }
        ExplosionEffectStencil = ObjectPooling.Spawn(ExplosionEffectStencil.gameObject, ExplosionEffectTransform.position, ExplosionEffectTransform.rotation).GetComponent <ParticleSystem>();
        ExplosionEffectStencil.Play();

        // Camera shake
        if (_Player == null)
        {
            _Player = GameManager.Instance.Players[0];
        }
        if (_Player != null)
        {
            _Player.CameraRTS.ExplosionShake(ExplosionEffectTransform.position, ExplosionRadius);
        }

        // Hide/despawn the unit
        _ObjectState = WorldObjectStates.Default;
        ObjectPooling.Despawn(gameObject);
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //  Called each frame.
    /// </summary>
    private void Update()
    {
        if (_Upgrade != null && _CameraAttached != null)
        {
            // Only show widget if the upgrade is currently being built
            if (_Upgrade.IsUpgrading())
            {
                // Update text to show how much time is remaining in the build
                int    time         = (int)_Upgrade.UpgradeTimeRemaining();
                string healthString = time.ToString();
                _TextComponent.text = healthString;

                // Set world space position
                Vector3 pos = _Upgrade.GetBuildingAttached().transform.position + Offsetting;
                pos.y = pos.y + _Upgrade.GetBuildingAttached().GetObjectHeight();
                transform.position = pos;

                // Constantly face the widget towards the camera
                transform.LookAt(2 * transform.position - _CameraAttached.transform.position);
            }

            // Destroy prefab instance as we no longer need it anymore
            else
            {
                ObjectPooling.Despawn(this.gameObject);
            }
        }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //  A coroutine that waits for the seconds specified then attempts to repool
    //  the particle effect (or destroyed entirely if re-pooling isn't possible)
    /// </summary>
    /// <param name="particleEffect"></param>
    /// <param name="delay"></param>
    IEnumerator ParticleDespawn(ParticleSystem particleEffect, float delay)
    {
        // Delay
        yield return(new WaitForSeconds(delay));

        // Despawn the system
        ObjectPooling.Despawn(particleEffect.gameObject);
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //  A coroutine that waits for the seconds specified then attempts to repool
    //  the particle effect (or destroyed entirely if re-pooling isn't possible)
    /// </summary>
    /// <param name="particleEffect"></param>
    /// <param name="delay"></param>
    public IEnumerator ParticleParentDespawn(ParticleSystem particleEffect, float delay)
    {
        // Delay
        ///yield return new WaitForSeconds(delay);
        yield return(new WaitUntil(() => !particleEffect.isPlaying));

        // Despawn the system
        ObjectPooling.Despawn(particleEffect.transform.parent.gameObject);
    }
Exemple #8
0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //  Called when the unit 'dies'.
    /// </summary>
    public override void OnDeath(WorldObject instigator)
    {
        base.OnDeath(instigator);

        // Stop the engine sound
        if (_EngineSound != null)
        {
            ObjectPooling.Despawn(_EngineSound.gameObject);
        }
    }
Exemple #9
0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //  Called when the player presses a button on the selection wheel with this world object
    //  linked to the button.
    /// </summary>
    /// <param name="buildingSlot">
    //  The building slot that instigated the selection wheel.
    //  (EG: If you're making a building, this is the building slot thats being used.)
    /// </param>
    public override void OnWheelSelect(BuildingSlot buildingSlot)
    {
        // Gets reference to the original turret (before the upgrade)
        BaseTurret originalTurret = null;

        if (buildingSlot != null)
        {
            if (buildingSlot.GetBuildingOnSlot() != null)
            {
                originalTurret = buildingSlot.GetBuildingOnSlot().GetComponent <BaseTurret>();
            }
        }

        // Remove old healthbar (if valid)
        float hitpoints = MaxHitPoints;

        if (originalTurret != null)
        {
            hitpoints = originalTurret.GetHitPoints();
            if (originalTurret._HealthBar != null)
            {
                ObjectPooling.Despawn(originalTurret._HealthBar.gameObject);
            }
        }

        // Create weapon
        if (_TowerWeapon != null)
        {
            _TowerWeapon = ObjectPooling.Spawn(_TowerWeapon.gameObject).GetComponent <Weapon>();
        }

        // Start building process
        base.OnWheelSelect(buildingSlot);
        if (_ClonedWorldObject != null)
        {
            // Only proceed if there was a previous building & we're upgrading from that
            if (originalTurret != null)
            {
                // Update player ref
                _ClonedWorldObject.SetPlayer(originalTurret._Player);

                // Set the new base's building state object to be the currently active object
                _ClonedWorldObject.BuildingState = originalTurret.gameObject;
            }

            // Update attached building slot turret reference
            if (buildingSlot != null)
            {
                buildingSlot.SetBuildingOnSlot(_ClonedWorldObject.GetComponent <BaseTurret>());
            }

            // Reset turret's health
            _ClonedWorldObject.SetHitPoints(_ClonedWorldObject.MaxHitPoints);
        }
    }
Exemple #10
0
    //******************************************************************************************************************************
    //
    //      FUNCTIONS
    //
    //******************************************************************************************************************************

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //  A coroutine that waits a few seconds before despawning the sound gameobject reference
    /// </summary>
    /// <returns></returns>
    private IEnumerator DestroySound(AudioSource sound, float delayTime)
    {
        // Delay
        float normalizedTime = 0f;

        while (normalizedTime <= 1f)
        {
            normalizedTime += Time.deltaTime / delayTime;
            yield return(null);
        }

        // Despawn
        ObjectPooling.Despawn(sound.gameObject);
    }
    //******************************************************************************************************************************
    //
    //      FUNCTIONS
    //
    //******************************************************************************************************************************

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //  Called when the player presses a button on the selection wheel with this world object
    //  linked to the button.
    /// </summary>
    /// <param name="buildingSlot">
    //  The building slot that instigated the selection wheel.
    //  (EG: If you're making a building, this is the building slot thats being used.)
    /// </param>
    public override void OnWheelSelect(BuildingSlot buildingSlot)
    {
        // Gets reference to the original generator (before the upgrade)
        Generator originalGenerator = null;

        if (buildingSlot != null)
        {
            if (buildingSlot.GetBuildingOnSlot() != null)
            {
                originalGenerator = buildingSlot.GetBuildingOnSlot().GetComponent <Generator>();
            }
        }

        // Remove old healthbar (if valid)
        float hitpoints = MaxHitPoints;

        if (originalGenerator != null)
        {
            hitpoints = originalGenerator.GetHitPoints();
            if (originalGenerator._HealthBar != null)
            {
                ObjectPooling.Despawn(originalGenerator._HealthBar.gameObject);
            }
        }

        // Start building process
        base.OnWheelSelect(buildingSlot);
        if (_ClonedWorldObject != null)
        {
            // Only proceed if there was a previous building and we are upgrading from that
            if (originalGenerator != null)
            {
                // Update player ref
                _ClonedWorldObject.SetPlayer(originalGenerator._Player);

                // Set the new bases building state object to be the currently active object
                _ClonedWorldObject.BuildingState = originalGenerator.gameObject;
            }

            // Update attached buildingSlot generator reference
            if (buildingSlot != null)
            {
                buildingSlot.SetBuildingOnSlot(_ClonedWorldObject.GetComponent <Generator>());
            }

            // Reset building's health
            _ClonedWorldObject.SetHitPoints(_ClonedWorldObject.MaxHitPoints);
        }
    }
    //******************************************************************************************************************************
    //
    //      FUNCTIONS
    //
    //******************************************************************************************************************************

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //  Called each frame.
    /// </summary>
    private void Update()
    {
        if (_ParticleSystem != null)
        {
            // Wait until the particle has finished its cycle (for force to stop)
            if (!_ParticleSystem.IsAlive() || _DespawnNow)
            {
                // Despawn
                ObjectPooling.Despawn(gameObject);
            }
        }

        // Get reference to the particle system
        else
        {
            _ParticleSystem = GetComponent <ParticleSystem>();
            if (_ParticleSystem == null)
            {
                _ParticleSystem = GetComponentInChildren <ParticleSystem>();
            }
        }
    }
Exemple #13
0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //  Called when the object is killed/destroyed
    /// </summary>
    public virtual void OnDeath(WorldObject instigator)
    {
        // Force deselect
        SetIsSelected(false);

        // Set object state
        _ObjectState = WorldObjectStates.Destroyed;

        // Destroy healthbar
        if (_HealthBar != null)
        {
            // Null the bitch
            _HealthBar.SetObjectAttached(null);
            ObjectPooling.Despawn(_HealthBar.gameObject);
        }

        // Clamping health
        _HitPoints = 0;
        _Health    = 0f;

        // Play OnDeath effect
        if (OnDeathEffect != null)
        {
            // Play
            ParticleSystem effect = ObjectPooling.Spawn(OnDeathEffect.gameObject, transform.position, transform.rotation).GetComponent <ParticleSystem>();
            effect.Play();

            // Despawn particle system once it has finished its cycle
            float effectDuration = effect.duration + effect.startLifetime;
            StartCoroutine(ParticleDespawn(effect, effectDuration));
        }

        // Send message to match feed
        MatchFeed.Instance.AddMessage(string.Concat(ObjectName, " destroyed."));

        // Delay then despawn
        StartCoroutine(DelayedShrinking(3f));
    }
Exemple #14
0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //  Update the current showcase object reference.
    /// </summary>
    /// <param name="button"></param>
    public void ChangeSelection(Button button)
    {
        // Get button reference component
        ShowcaseButtonRef btnref = button.gameObject.GetComponent <ShowcaseButtonRef>();

        // Update showcase object reference
        if (btnref != null && _CurrentShowcaseObject != null)
        {
            // Destroy old showcase object
            ObjectPooling.Despawn(_CurrentShowcaseObject.gameObject);

            // Reset showcase transform
            if (StartingShowcaseTransform != null)
            {
                _ShowcasePosition = StartingShowcaseTransform.position;
            }
            if (StartingShowcaseTransform != null)
            {
                _ShowcaseRotation = StartingShowcaseTransform.rotation;
            }

            // Create new showcase object
            Selectable select = btnref.ObjectReference;
            GameObject gObj   = ObjectPooling.Spawn(select.gameObject, _ShowcasePosition, _ShowcaseRotation);
            _CurrentShowcaseObject = gObj.GetComponent <Selectable>();
            _CurrentShowcaseObject._ObjectState = Abstraction.WorldObjectStates.Active;
            (_CurrentShowcaseObject as WorldObject).SetShowHealthBar(false);

            // Add offset to the showcase position
            _ShowcasePosition.y += _CurrentShowcaseObject.ShowcaseOffsetY;

            // Update camera properties
            if (ShowcaseRenderCamera != null)
            {
                ShowcaseRenderCamera.fieldOfView = _CurrentShowcaseObject.ShowcaseFOV;
            }
        }
    }
Exemple #15
0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //  Called when this object is created.
    /// </summary>
    protected override void Start()
    {
        base.Start();

        if (_PotentialTargets == null)
        {
            _PotentialTargets = new List <WorldObject>();
        }
        else
        {
            _PotentialTargets.Clear();
        }

        // Create copy of its weaopn & re-assign it to replace the old reference
        if (_TowerWeapon != null)
        {
            ObjectPooling.Despawn(_TowerWeapon.gameObject);
        }
        if (TowerWeapon != null)
        {
            _TowerWeapon = ObjectPooling.Spawn(TowerWeapon.gameObject, Vector3.zero, Quaternion.identity).GetComponent <Weapon>();
            _TowerWeapon.SetTowerAttached(this);
        }
    }
Exemple #16
0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //
    /// </summary>
    /// <param name="buildingSlot"></param>
    public override void StartBuildingObject(BuildingSlot buildingSlot)
    {
        base.StartBuildingObject();

        float hitpoints = MaxHitPoints;

        // Only proceed if there was a previous building and we are upgrading from that
        if (_ClonedWorldObject != null)
        {
            Base newBase = _ClonedWorldObject.GetComponent <Base>();
            if (newBase._PreviousBase != null)
            {
                // Dont allow upgrading stacks
                if (!newBase._PreviousBase._UpgradingBase)
                {
                    // Remove old healthbar (if valid)
                    hitpoints = _PreviousBase._HitPoints;
                    if (newBase._PreviousBase._HealthBar != null)
                    {
                        ObjectPooling.Despawn(newBase._PreviousBase._HealthBar.gameObject);
                    }

                    // Update player ref
                    _ClonedWorldObject._Player = newBase._PreviousBase._Player;

                    // Set the new bases queued/building state object to be the currently active base
                    _ClonedWorldObject.InQueueState  = newBase._PreviousBase.gameObject;
                    _ClonedWorldObject.BuildingState = newBase._PreviousBase.gameObject;

                    // Get references to all the buildings that were in the previous base & allocate them to the new one
                    // Depot/Generator slots
                    for (int i = 0; i < newBase.DepotSlots.Count; i++)
                    {
                        // Only go as far as the previous bases slot size
                        if (i < newBase._PreviousBase.DepotSlots.Count)
                        {
                            // Reallocate building to new base (if there is one)
                            if (newBase._PreviousBase.DepotSlots[i] != null)
                            {
                                // Send building to new base
                                if (newBase._PreviousBase.DepotSlots[i].GetBuildingOnSlot() != null)
                                {
                                    newBase._PreviousBase.DepotSlots[i].GetBuildingOnSlot().AttachedBuildingSlot = newBase.DepotSlots[i];
                                    newBase.DepotSlots[i].SetBuildingOnSlot(newBase._PreviousBase.DepotSlots[i].GetBuildingOnSlot());
                                    newBase._PreviousBase.DepotSlots[i].SetBuildingOnSlot(null);
                                }
                            }
                            else
                            {
                                continue;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    // Tower slots
                    for (int i = 0; i < newBase.TowerSlots.Count; i++)
                    {
                        // Only go as far as the previous bases slot size
                        if (i < newBase._PreviousBase.TowerSlots.Count)
                        {
                            // Reallocate tower to new base (if there is one)
                            if (newBase._PreviousBase.TowerSlots[i] != null)
                            {
                                // Send tower to new base
                                if (newBase._PreviousBase.TowerSlots[i].GetBuildingOnSlot() != null)
                                {
                                    newBase._PreviousBase.TowerSlots[i].GetBuildingOnSlot().AttachedBuildingSlot = newBase.TowerSlots[i];
                                    newBase.TowerSlots[i].SetBuildingOnSlot(newBase._PreviousBase.TowerSlots[i].GetBuildingOnSlot());
                                    newBase._PreviousBase.TowerSlots[i].SetBuildingOnSlot(null);
                                }
                            }
                            else
                            {
                                continue;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }

            // Update attached base reference
            if (buildingSlot != null)
            {
                buildingSlot.AttachedBase = _ClonedWorldObject.GetComponent <Base>();
            }

            // Update new bases health with the old bases health
            _ClonedWorldObject.SetHitPoints(hitpoints);
        }
    }
Exemple #17
0
    //******************************************************************************************************************************
    //
    //      FUNCTIONS
    //
    //******************************************************************************************************************************

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //  Called each frame.
    /// </summary>
    private void Update()
    {
        if (_WorldObject != null && _CameraAttached != null)
        {
            // Display text if the object is a building
            if (_BuildingAttached != null)
            {
                _TextComponent.text = _WorldObject.ObjectName;

                // Only show the building name if it is built & active in the game world
                if (_WorldObject.GetObjectState() == Abstraction.WorldObjectStates.Active)
                {
                    _TextComponent.enabled = true;
                }
                else
                {
                    _TextComponent.enabled = false;
                }
            }

            // Don't show the text component if the object is NOT a building
            else
            {
                _TextComponent.enabled = false;
            }

            // Update health bar
            if (HealthSlider != null)
            {
                HealthSlider.value = _WorldObject.GetHealth();
            }

            // Update shield bar
            if (ShieldSlider != null)
            {
                // Show the shield bar if theres some shield left
                if (_WorldObject.GetShieldPoints() > 0)
                {
                    ShieldSlider.value = _WorldObject.GetShield();
                    ShieldSlider.gameObject.SetActive(true);
                }

                // Hide the shield
                else
                {
                    ShieldSlider.gameObject.SetActive(false);
                }
            }

            // Object is alive - display the widget
            if (_WorldObject.IsInWorld())
            {
                // Set world space position
                Vector3 pos = _WorldObject.transform.position + Offsetting;
                pos.y = pos.y + _WorldObject.GetObjectHeight();
                transform.position = pos;

                // Constantly face the widget towards the camera
                transform.LookAt(2 * transform.position - _CameraAttached.transform.position);
            }

            // Object is dead/destroyed
            else
            {
                ObjectPooling.Despawn(gameObject);
            }

            // Update team colour
            UpdateTeamColourFill();
        }
    }
Exemple #18
0
    //******************************************************************************************************************************
    //
    //      FUNCTIONS
    //
    //******************************************************************************************************************************

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //  Called when the object is killed/destroyed
    /// </summary>
    public override void OnDeath(WorldObject instigator)
    {
        // Determine whether the character should explode or not
        float xplode = Random.Range(0f, 1f);

        if (xplode <= ExplodeOnDeathChance)
        {
            _Agent.enabled = false;

            // Cannister leak then explode
            _CannisterLeakEffect = ObjectPooling.Spawn(CannisterLeakStencil.gameObject, CannisterLeakTransform.position, CannisterLeakTransform.rotation).GetComponent <ParticleSystem>();
            _CannisterLeakEffect.Play();

            StartCoroutine(DelayedExplosion());

            // If were in the wave manager's enemies array - remove it
            if (WaveManager.Instance.GetCurrentWaveEnemies().Contains(this))
            {
                WaveManager.Instance.GetCurrentWaveEnemies().Remove(this);
            }
            if (Team == GameManager.Team.Attacking)
            {
                GameManager.Instance.WaveStatsHUD.DeductLifeFromCurrentPopulation();
            }

            // Remove from player's population counter
            else if (Team == GameManager.Team.Defending)
            {
                _Player.RemoveFromArmy(this);
            }

            // Destroy waypoint
            if (_SeekWaypoint != null)
            {
                ObjectPooling.Despawn(_SeekWaypoint.gameObject);
            }

            // Add xp to the instigator (if valid)
            if (instigator != null)
            {
                // Only units can gain XP from kills
                Unit unit = instigator.GetComponent <Unit>();
                if (unit != null)
                {
                    unit.AddVeterancyXP(XPGrantedOnDeath);
                }
            }

            // Force deselect
            SetIsSelected(false);

            // Despawn any damaged threshold particles in play
            for (int i = 0; i < _DamagedParticles.Count; i++)
            {
                ParticleSystem effect = _DamagedParticles[i];
                effect.Stop(true);
                ObjectPooling.Despawn(effect.gameObject);
            }
            if (_DamagedParticles.Count > 0)
            {
                _DamagedParticles.Clear();
            }

            // Set object state
            _ObjectState = WorldObjectStates.Destroyed;

            // Destroy healthbar
            if (_HealthBar != null)
            {
                // Null the bitch
                _HealthBar.SetObjectAttached(null);
                ObjectPooling.Despawn(_HealthBar.gameObject);
            }

            // Clamping health
            _HitPoints = 0;
            _Health    = 0f;

            // Camera shake if neccessary
            if (_Player == null)
            {
                _Player = GameManager.Instance.Players[0];
            }
            if (CameraShakeOnDeath && _Player != null)
            {
                _Player.CameraRTS.ExplosionShake(transform.position, DeathExplosionRadius);
            }

            // Send message to match feed
            if (Team == GameManager.Team.Defending)
            {
                MatchFeed.Instance.AddMessage(string.Concat(ObjectName, " has been killed."));
                _Player.AddUnitsLost();
            }

            // Add to enemies killed stats
            else if (Team == GameManager.Team.Attacking)
            {
                _Player.AddUnitsKilled();
            }
        }

        // Die normally
        else
        {
            base.OnDeath(instigator);
        }
    }
Exemple #19
0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //  Called each frame.
    /// </summary>
    protected override void Update()
    {
        base.Update();

        switch (_ObjectState)
        {
        case WorldObjectStates.Default: {
            // Hide meshes
            if (InQueueState)
            {
                InQueueState.SetActive(false);
            }
            if (BuildingState)
            {
                BuildingState.SetActive(false);
            }
            if (ActiveState)
            {
                ActiveState.SetActive(false);
            }
            if (DestroyedState)
            {
                DestroyedState.SetActive(false);
            }

            // Hide fog of war
            if (_FogOfWarSight != null)
            {
                _FogOfWarSight.enabled = false;
            }
            break;
        }

        case WorldObjectStates.InQueue: {
            // Show inqueue state object
            if (BuildingState)
            {
                BuildingState.SetActive(false);
            }
            if (InQueueState)
            {
                InQueueState.SetActive(true);
            }
            if (ActiveState)
            {
                ActiveState.SetActive(false);
            }
            if (DestroyedState)
            {
                DestroyedState.SetActive(false);
            }

            // Hide fog of war
            if (_FogOfWarSight != null)
            {
                _FogOfWarSight.enabled = false;
            }
            break;
        }

        case WorldObjectStates.Building: {
            // Show building state object
            if (InQueueState)
            {
                InQueueState.SetActive(false);
            }
            if (BuildingState)
            {
                BuildingState.SetActive(true);
            }
            if (ActiveState)
            {
                ActiveState.SetActive(false);
            }
            if (DestroyedState)
            {
                DestroyedState.SetActive(false);
            }

            // Is unit building complete?
            if (SceneManager.GetSceneByName("TutorialScene") == SceneManager.GetActiveScene())
            {
                _ReadyForDeployment = _CurrentBuildTime >= BuildingTimeTutorial;
            }
            else
            {
                _ReadyForDeployment = _CurrentBuildTime >= BuildingTime;
            }

            if (!_ReadyForDeployment)
            {
                // Add to building timer
                if (SceneManager.GetSceneByName("TutorialScene") == SceneManager.GetActiveScene())
                {
                    if (_CurrentBuildTime < BuildingTimeTutorial)
                    {
                        _CurrentBuildTime += Time.deltaTime;
                    }
                }
                else
                {
                    if (_CurrentBuildTime < BuildingTime)
                    {
                        _CurrentBuildTime += Time.deltaTime;
                    }
                }
            }
            else
            {
                // Object has finished building
                OnBuilt();
                _ObjectState = WorldObjectStates.Deployable;
            }

            // Hide fog of war
            if (_FogOfWarSight != null)
            {
                _FogOfWarSight.enabled = false;
            }
            break;
        }

        case WorldObjectStates.Deployable: { break; }

        case WorldObjectStates.Active: {
            // Show active state object
            if (InQueueState)
            {
                InQueueState.SetActive(false);
            }
            if (BuildingState)
            {
                BuildingState.SetActive(false);
            }
            if (ActiveState)
            {
                ActiveState.SetActive(true);
            }
            if (DestroyedState)
            {
                DestroyedState.SetActive(false);
            }

            // Show fog of war
            if (_FogOfWarSight != null)
            {
                _FogOfWarSight.enabled = true;
            }
            break;
        }

        case WorldObjectStates.Destroyed: {
            // Show destroyed state object
            if (InQueueState)
            {
                InQueueState.SetActive(false);
            }
            if (BuildingState)
            {
                BuildingState.SetActive(false);
            }
            if (ActiveState)
            {
                ActiveState.SetActive(false);
            }
            if (DestroyedState)
            {
                DestroyedState.SetActive(true);
            }

            // Hide fog of war
            if (_FogOfWarSight != null)
            {
                _FogOfWarSight.enabled = false;
            }
            break;
        }

        default: break;
        }

        // Update shield to be a normalized range of the object's shield-points
        if (_ShieldPoints > 0)
        {
            _Shield = _ShieldPoints / MaxShieldPoints;

            // Clamp to max points
            if (_ShieldPoints > MaxShieldPoints)
            {
                _ShieldPoints = MaxShieldPoints;
            }
        }
        else
        {
            // Clamp the shield
            _ShieldPoints = 0;
            _Shield       = 0f;
        }

        // Update health to be a normalized range of the object's hitpoints
        if (_HitPoints > 0)
        {
            _Health = _HitPoints / MaxHitPoints;

            // Clamp to max points
            if (_HitPoints > MaxHitPoints)
            {
                _HitPoints = MaxHitPoints;
            }
        }
        else
        {
            // Clamping health
            _HitPoints = 0;
            _Health    = 0f;
        }

        // Despawn any damage particles if our health is above the threshold (IE: after being healed)
        if (_Health > HealthThresholdDamaged)
        {
            for (int i = 0; i < _DamagedParticles.Count; i++)
            {
                ParticleSystem effect = _DamagedParticles[i];
                effect.Stop(true);
                ObjectPooling.Despawn(effect.gameObject);
            }
            if (_DamagedParticles.Count > 0)
            {
                _DamagedParticles.Clear();
            }
        }
        else
        {
            // Update the position of the particle effects so that they are constantly at the attached object
            for (int i = 0; i < _DamagedParticles.Count; i++)
            {
                GameObject effect = _DamagedParticles[i].gameObject;
                effect.transform.position = HealthDamagedParticles[i].ParticleLocation.position;
                effect.transform.rotation = HealthDamagedParticles[i].ParticleLocation.rotation;
            }
        }

        // Change minimap colour based on attacking/defending & team colour
        if (_MinimapQuadRenderer != null)
        {
            // Attacking team colour
            if (Team == GameManager.Team.Attacking)
            {
                _MinimapQuadRenderer.material.color = WaveManager.Instance.AttackingTeamColour;
            }

            // Defending team
            else if (Team == GameManager.Team.Defending)
            {
                // Use individual player colour
                if (_Player)
                {
                    _MinimapQuadRenderer.material.color = _Player.TeamColor;
                }
            }
        }

        // Gradually shrink the character then despawn it once its dead
        UpdateDeathShrinker();
    }
Exemple #20
0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //  Destroys the building & returns some resources back to the player who owns the building.
    /// </summary>
    public void RecycleBuilding()
    {
        // Deselect all objects
        foreach (var selectable in GameManager.Instance.Selectables)
        {
            selectable.SetIsSelected(false);
        }

        // Add resources back to player
        if (_Player != null)
        {
            _Player.SuppliesCount += GetRecycleSuppliesAmount();
            _Player.PowerCount    += GetRecyclePowerAmount();
        }

        // Destroy building
        if (_RecycleOption)
        {
            // Deselect self
            SetIsSelected(false);

            // Destroy Widgets
            if (AttachedBuildingSlot.GetBuildingOnSlot()._HealthBar)
            {
                ObjectPooling.Despawn(AttachedBuildingSlot.GetBuildingOnSlot()._HealthBar.gameObject);
            }
            if (AttachedBuildingSlot.GetBuildingOnSlot()._BuildingProgressCounter)
            {
                ObjectPooling.Despawn(AttachedBuildingSlot.GetBuildingOnSlot()._BuildingProgressCounter.gameObject);
            }

            // Remove from queues/lists
            // Bases
            if (AttachedBuildingSlot.AttachedBase != null)
            {
                AttachedBuildingSlot.AttachedBase.RemoveFromQueue(AttachedBuildingSlot.GetBuildingOnSlot());
                AttachedBuildingSlot.AttachedBase.RemoveFromList(AttachedBuildingSlot.GetBuildingOnSlot());

                if (UI_BuildingQueueWrapper.Instance.ContainsQueue(_BuildingQueueUI))
                {
                    UI_BuildingQueueWrapper.Instance.RemoveFromQueue(_BuildingQueueUI);
                    Destroy(_BuildingQueueUI);
                }
            }
            // Buildings
            if (AttachedBuildingSlot.AttachedBuilding != null && AttachedBuildingSlot.AttachedBase == null)
            {
                AttachedBuildingSlot.AttachedBuilding.RemoveFromQueue(AttachedBuildingSlot.GetBuildingOnSlot());

                if (UI_BuildingQueueWrapper.Instance.ContainsQueue(_BuildingQueueUI))
                {
                    UI_BuildingQueueWrapper.Instance.RemoveFromQueue(_BuildingQueueUI);
                    Destroy(_BuildingQueueUI);
                }
            }

            // Destroy Building
            if (_BuildingQueueUI != null)
            {
                UI_BuildingQueueWrapper.Instance.RemoveFromQueue(_BuildingQueueUI);
            }
            OnDeath(null);

            // Send message to match feed
            MatchFeed.Instance.AddMessage(string.Concat(ObjectName, " recycled."));
        }

        // Make building slot available again
        AttachedBuildingSlot.SetBuildingOnSlot(null);
        AttachedBuildingSlot.gameObject.SetActive(true);

        // Update building queue UI
        if (AttachedBuildingSlot.AttachedBase != null)
        {
            AttachedBuildingSlot.AttachedBase._BuildingQueueUI.UpdateQueueItemList();
        }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //
    /// </summary>
    public void RefreshPanels()
    {
        // Reset lists
        for (int i = 0; i < _UnitInfoPanels.Count; i++)
        {
            ObjectPooling.Despawn(_UnitInfoPanels[i].gameObject);
        }
        _UnitInfos.Clear();
        _UnitInfoPanels.Clear();

        // Add a new panel for each type of unit selected by the player
        for (int i = 0; i < _SelectedUnits.Count; i++)
        {
            // Check if this unit already exists in the info lists
            bool matchingType = false;
            for (int j = 0; j < _UnitInfos.Count; j++)
            {
                // Matching type to existing info
                if (_SelectedUnits[i].UnitType == _UnitInfos[j]._UnitType)
                {
                    // Add to count of the unit info
                    _UnitInfos[j]._Amount++;
                    matchingType = true;
                    break;
                }
            }

            // No unit infos match the selected unit were testing against
            if (!matchingType)
            {
                // Create a new iterator in the info lists
                UnitInfos info = new UnitInfos {
                    _UnitType   = _SelectedUnits[i].UnitType,
                    _Logo       = _SelectedUnits[i].Logo,
                    _CombatType = _SelectedUnits[i].CombatType,
                    _Amount     = 1
                };
                _UnitInfos.Add(info);
            }
        }

        // Create a new panel for each unit info
        for (int i = 0; i < _UnitInfos.Count; i++)
        {
            if (StencilObject != null)
            {
                // Spawn panel & pass unit info data
                UI_UnitInfoPanel panel = ObjectPooling.Spawn(StencilObject.gameObject).GetComponent <UI_UnitInfoPanel>();
                panel.LogoComponent.sprite = _UnitInfos[i]._Logo;
                panel.UnitName.text        = _UnitInfos[i]._UnitType.ToString();
                panel.AmountCounter.text   = _UnitInfos[i]._Amount.ToString();
                panel.SetPanelInfo(_UnitInfos[i]);
                panel.SetPlayer(_Player);

                // Set combat type logo
                switch (_UnitInfos[i]._CombatType)
                {
                case Unit.ECombatType.GroundInfantry:
                    panel.TypeComponent.sprite = GroundInfantryLogo;
                    break;

                case Unit.ECombatType.GroundVehicle:
                    panel.TypeComponent.sprite = GroundVehicleLogo;
                    break;

                case Unit.ECombatType.AirVehicle:
                    panel.TypeComponent.sprite = AirVehicleLogo;
                    break;

                default: break;
                }

                // Set anchoring position
                RectTransform rectT = panel.GetComponent <RectTransform>();
                panel.transform.SetParent(gameObject.transform);
                if (i > 0)
                {
                    // Not the first panel
                    rectT.anchoredPosition = new Vector2((StartingPositionX + (_PanelSize * i) + (OffsetX * i)), StartingPositionY);
                }
                else
                {
                    // First panel
                    rectT.anchoredPosition = new Vector2(StartingPositionX, StartingPositionY);
                }
                _UnitInfoPanels.Add(panel);
            }
        }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //  Called when the projectile is destroyed, this is
    //  usually called when the projectile collides with something
    /// </summary>
    protected void OnDestroy()
    {
        if (ExplodeOnImpact)
        {
            /*
             *  // DEBUGGING SPHERECAST
             *  // Uncomment LINE 273 (the ignore raycast line) otherwise this will give unintended results!
             *  GameObject child = new GameObject();
             *  child.transform.parent = gameObject.transform;
             *  SphereCollider debug = child.AddComponent<SphereCollider>();
             *  debug.radius = ExplosionRadius;
             *  debug.isTrigger = true;
             *  debug.transform.localPosition = new Vector3(0, 0, 0);
             *  child.layer = LayerMask.NameToLayer("Ignore Raycast");
             */

            // Use a spherical raycast for an AOE damage with falloff
            RaycastHit[] hits = Physics.SphereCastAll(transform.position, ExplosionRadius, transform.forward, 0f);
            foreach (var rayHit in hits)
            {
                WorldObject worldObj = rayHit.transform.gameObject.GetComponentInParent <WorldObject>();
                if (worldObj != null)
                {
                    // Get reference to the instigator this projectile belongs to
                    WorldObject worldObjAttached = null;
                    if (_WeaponAttached.GetUnitAttached() != null)
                    {
                        worldObjAttached = _WeaponAttached.GetUnitAttached();
                    }
                    if (_WeaponAttached.GetTowerAttached() != null)
                    {
                        worldObjAttached = _WeaponAttached.GetTowerAttached();
                    }

                    // Friendly fire is OFF
                    if (worldObj.Team != worldObjAttached.Team)
                    {
                        // Determine damage falloff
                        float distanceFromEpicenter = Vector3.Distance(transform.position, rayHit.point);
                        float damageMultiplier      = (distanceFromEpicenter / ExplosionRadius) * DamageFalloff;

                        // Damage the object
                        worldObj.Damage(Mathf.FloorToInt(_Damages.DamageDefault * damageMultiplier));
                    }
                }
            }

            // Play OnDeath effect
            if (ExplosionEffect != null)
            {
                // Play
                ParticleSystem effect = ObjectPooling.Spawn(ExplosionEffect.gameObject, transform.position, transform.rotation).GetComponent <ParticleSystem>();
                effect.Play();

                // Despawn particle system once it has finished its cycle
                float effectDuration = effect.duration + effect.startLifetime;
                StartCoroutine(ParticleDespawn(effect, effectDuration));
            }
        }

        gameObject.SetActive(false);
        ObjectPooling.Despawn(gameObject);
    }
Exemple #23
0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //  Called when the object is killed/destroyed
    /// </summary>
    public virtual void OnDeath(WorldObject instigator)
    {
        // Force deselect
        SetIsSelected(false);

        // Remove from instigators target list
        if (instigator != null)
        {
            (instigator as Unit).RemovePotentialTarget(this);
        }

        // Despawn any damaged threshold particles in play
        for (int i = 0; i < _DamagedParticles.Count; i++)
        {
            ParticleSystem effect = _DamagedParticles[i];
            effect.Stop(true);
            ObjectPooling.Despawn(effect.gameObject);
        }
        if (_DamagedParticles.Count > 0)
        {
            _DamagedParticles.Clear();
        }

        // Set object state
        _ObjectState = WorldObjectStates.Destroyed;

        // Destroy healthbar
        if (_HealthBar != null)
        {
            // Null the reference
            _HealthBar.SetObjectAttached(null);
            ObjectPooling.Despawn(_HealthBar.gameObject);
        }

        // Clamping health
        _HitPoints = 0;
        _Health    = 0f;

        // Play OnDeath(s) effect
        for (int i = 0; i < OnDeathEffects.Count; i++)
        {
            // Play at location
            ParticleSystem effect = ObjectPooling.Spawn(OnDeathEffects[i].ParticleEffect.gameObject,
                                                        OnDeathEffects[i].ParticleLocation.position,
                                                        OnDeathEffects[i].ParticleLocation.rotation).GetComponent <ParticleSystem>();
            effect.Play();
        }

        // Camera shake if neccessary
        if (CameraShakeOnDeath && _Player != null)
        {
            _Player.CameraRTS.ExplosionShake(transform.position, DeathExplosionRadius);
        }

        // Send message to match feed
        if (Team == GameManager.Team.Defending)
        {
            if (this is Unit)
            {
                MatchFeed.Instance.AddMessage(string.Concat(ObjectName, " has been killed."));
            }
            if (!(this is Unit))
            {
                MatchFeed.Instance.AddMessage(string.Concat(ObjectName, " destroyed."));
            }

            _Player.AddUnitsLost();
        }

        // Add to enemies killed stats
        else if (Team == GameManager.Team.Attacking && _Player != null)
        {
            _Player.AddUnitsKilled();
        }

        // Delay then despawn
        StartCoroutine(DelayedShrinking(3f));
    }
Exemple #24
0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //  Called when the projectile is destroyed, this is
    //  usually called when the projectile collides with something
    /// </summary>
    protected void OnDestroy()
    {
        if (ExplodeOnImpact)
        {
            /*
             *  // DEBUGGING SPHERECAST
             *  // Uncomment LINE 273 (the ignore raycast line) otherwise this will give unintended results!
             *  GameObject child = new GameObject();
             *  child.transform.parent = gameObject.transform;
             *  SphereCollider debug = child.AddComponent<SphereCollider>();
             *  debug.radius = ExplosionRadius;
             *  debug.isTrigger = true;
             *  debug.transform.localPosition = new Vector3(0, 0, 0);
             *  child.layer = LayerMask.NameToLayer("Ignore Raycast");
             */

            // Use a spherical raycast for an AOE damage with falloff
            RaycastHit[] hits = Physics.SphereCastAll(transform.position, ExplosionRadius, transform.forward, 0f);
            foreach (var rayHit in hits)
            {
                WorldObject worldObj = rayHit.transform.gameObject.GetComponentInParent <WorldObject>();
                if (worldObj != null)
                {
                    // Get reference to the instigator this projectile belongs to
                    WorldObject worldObjAttached = null;
                    if (_WeaponAttached.GetUnitAttached() != null)
                    {
                        worldObjAttached = _WeaponAttached.GetUnitAttached();
                    }
                    if (_WeaponAttached.GetTowerAttached() != null)
                    {
                        worldObjAttached = _WeaponAttached.GetTowerAttached();
                    }

                    // Friendly fire is OFF
                    if (worldObj.Team != worldObjAttached.Team)
                    {
                        // Determine damage falloff
                        float distanceFromEpicenter = Vector3.Distance(transform.position, rayHit.point);
                        float damageMultiplier      = (distanceFromEpicenter / ExplosionRadius) * DamageFalloff;

                        // Damage the object
                        worldObj.Damage(Mathf.FloorToInt(_Damages.DamageDefault * damageMultiplier));
                    }
                }
            }

            // Play OnDeath effect
            if (ExplosionEffect != null)
            {
                // Play
                ParticleSystem effect = ObjectPooling.Spawn(ExplosionEffect.gameObject, transform.position, transform.rotation).GetComponent <ParticleSystem>();
                effect.Play();
            }

            // Camera shake on explosion
            Player player = null;
            if (_WeaponAttached.GetUnitAttached() != null)
            {
                player = _WeaponAttached.GetUnitAttached()._Player;
            }
            if (_WeaponAttached.GetTowerAttached() != null)
            {
                player = _WeaponAttached.GetTowerAttached()._Player;
            }
            if (player != null)
            {
                player.CameraRTS.ExplosionShake(transform.position, ExplosionRadius);
            }
        }

        // Set the projectile's impact effect to match the weapon's impact effect (if set in the weapon)
        if (_WeaponAttached != null)
        {
            if (_WeaponAttached.DefaultImpactEffect != null)
            {
                ImpactEffect = _WeaponAttached.DefaultImpactEffect;
            }
        }

        // Play impact effect
        if (ImpactEffect != null)
        {
            // Play
            ParticleSystem effect = ObjectPooling.Spawn(ImpactEffect, transform.position, transform.rotation).GetComponentInChildren <ParticleSystem>();
            effect.Play();
        }

        // Play OnDeath effect (this is for when you dont want to use explosion damage properties, but have the effect play still)
        if (ExplosionEffect != null && !ExplodeOnImpact)
        {
            // Play
            ParticleSystem effect = ObjectPooling.Spawn(ExplosionEffect.gameObject, transform.position, transform.rotation).GetComponent <ParticleSystem>();
            effect.Play();
        }

        ObjectPooling.Despawn(gameObject);
    }
Exemple #25
0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    //  Detonates the mine and damages any enemies within the blast radius.
    /// </summary>
    public void DetonateMine()
    {
        /*
         *  // DEBUGGING SPHERECAST
         *  // Uncomment LINE 273 (the ignore raycast line) otherwise this will give unintended results!
         *  GameObject child = new GameObject();
         *  child.transform.parent = gameObject.transform;
         *  SphereCollider debug = child.AddComponent<SphereCollider>();
         *  debug.radius = ExplosionRadius;
         *  debug.isTrigger = true;
         *  debug.transform.localPosition = new Vector3(0, 0, 0);
         *  child.layer = LayerMask.NameToLayer("Ignore Raycast");
         */

        // Use a spherical raycast for an AOE damage with falloff
        RaycastHit[] hits = Physics.SphereCastAll(transform.position, ExplosionRadius, transform.forward, 0f);
        foreach (var rayHit in hits)
        {
            WorldObject worldObj = rayHit.transform.gameObject.GetComponentInParent <WorldObject>();
            if (worldObj != null)
            {
                // Friendly fire is OFF
                if (worldObj.Team != _Team)
                {
                    // Determine damage falloff
                    float distanceFromEpicenter = Vector3.Distance(transform.position, rayHit.point);
                    float damageMultiplier      = (distanceFromEpicenter / ExplosionRadius) * DamageFalloff;

                    // Damage the object
                    worldObj.Damage(Mathf.FloorToInt(Damages.DamageDefault * damageMultiplier));
                }
            }
        }

        // Play OnDeath effect
        if (ExplosionEffect != null)
        {
            // Play
            ParticleSystem effect = ObjectPooling.Spawn(ExplosionEffect.gameObject, transform.position, transform.rotation).GetComponent <ParticleSystem>();
            effect.Play();

            // Despawn particle system once it has finished its cycle
            float effectDuration = effect.duration + effect.startLifetime;
            StartCoroutine(ParticleDespawn(effect, effectDuration));
        }

        // Remove mine from its attached minefield
        if (_MineFieldAttached != null)
        {
            _MineFieldAttached.GetUndetonatedMines().Remove(this);

            // Check if the minefield object should be despawned aswell
            if (_MineFieldAttached.GetUndetonatedMines().Count == 0)
            {
                _MineFieldAttached.OnDeath(null);
            }

            // Despawn mine
            ObjectPooling.Despawn(gameObject);
        }
    }