예제 #1
0
    private void GenerateCBodiesAsteroids(int nCBodiesAsteroidClusters, GameObject centreCBodyStar)
    {
        //Properties
        float minimumDistanceBetweenClusters = 100f;
        float distanceOut = 1300f - minimumDistanceBetweenClusters;
        float randSpacing;
        float spawnRadius;
        float spawnAngle;
        int   clusterSize;
        byte  clusterType;

        //Spawn all
        for (int i = 0; i < nCBodiesAsteroidClusters; i++)
        {
            //Instance cBody
            randSpacing = Random.Range(0f, 600f) + Mathf.Pow(Random.Range(0f, 15f), 2f);
            spawnRadius = distanceOut + minimumDistanceBetweenClusters + randSpacing;
            distanceOut = spawnRadius;                          //increment distanceOut for the next cBody
            spawnAngle  = Random.Range(0f, 360f);
            clusterSize = Control.LowBiasedRandomIntSquared(4); //range of 1 to 16 (4^2 = 16)

            //We don't have to add 1 here to format for Random.Range max being exclusive for ints because the length is already 1 greater than the index (since index starts at 0)
            clusterType = (byte)Random.Range(0, Ore.typeLength);

            for (int clusterI = 0; clusterI < clusterSize; clusterI++)
            {
                GameObject instanceCBodyAsteroid = Instantiate(
                    cBodyAsteroid,
                    new Vector3(
                        Mathf.Cos(spawnAngle) * spawnRadius,
                        0f,
                        Mathf.Sin(spawnAngle) * spawnRadius
                        ),
                    Quaternion.Euler(
                        Random.Range(0f, 360f),
                        Random.Range(0f, 360f),
                        Random.Range(0f, 360f)
                        )
                    );

                //Put in CBodies tree
                instanceCBodyAsteroid.transform.parent = cBodiesAsteroids.transform;

                //Spread out within cluster
                instanceCBodyAsteroid.transform.position += 2f * new Vector3(Random.value, Random.value, Random.value);

                Gravity instanceCBodyGravityScript = instanceCBodyAsteroid.GetComponent <Gravity>();
                //Orbit central star
                instanceCBodyGravityScript.SetVelocityToOrbit(centreCBodyStar, spawnAngle);

                CBodyAsteroid instanceCBodyAsteroidScript = instanceCBodyAsteroid.GetComponent <CBodyAsteroid>();
                //Randomize size and type
                instanceCBodyAsteroidScript.SetSize(CBodyAsteroid.GetRandomSize()); //MUST SET SIZE FIRST SO THAT MODEL IS SELECTED
                instanceCBodyAsteroidScript.SetType(clusterType);
                //Give control reference
                instanceCBodyAsteroidScript.control = control;
                instanceCBodyGravityScript.control  = control;
            }
        }
    }
예제 #2
0
    private void DealExplosionDamageAndForce()
    {
        //Check for colliders in the area
        Collider[] collidersInRadius = Physics.OverlapSphere(transform.position, EXPLOSION_RADIUS);
        foreach (Collider collider in collidersInRadius)
        {
            //Don't bother raycasting unless the collider in the area is an asteroid
            if (StringIsAnAsteroidModel(collider.gameObject.name))
            {
                //Cast a ray to make sure the asteroid is in LOS
                LayerMask someLayerMask  = -1;
                Vector3   rayDirection   = (collider.transform.position - transform.position).normalized;
                float     rayDistanceMax = (collider.transform.position - transform.position).magnitude;

                if (Physics.Raycast(transform.position, rayDirection, out RaycastHit hit, rayDistanceMax, someLayerMask, QueryTriggerInteraction.Ignore))
                {
                    //Debug.LogFormat("{0}", hit.collider.name);
                    //We need to be ignoring triggers?

                    //Make sure the ray is hitting an asteroid (something else could be in the way blocking LOS) that is within range
                    float distanceBetweenHitAndEpicentre = (transform.position - hit.point).magnitude;
                    //Debug.Log(hit.transform.name);
                    if (distanceBetweenHitAndEpicentre < EXPLOSION_RADIUS && hit.transform.name == control.generation.cBodyAsteroid.name + "(Clone)")
                    {
                        CBodyAsteroid asteroidScript = hit.transform.GetComponent <CBodyAsteroid>();

                        //Don't bother with already destroyed asteroids
                        if (!asteroidScript.destroyed)
                        {
                            //THIS RUNS FOUR TIMES BECAUSE IT IS HITTING THE TRIGGER COLLIDERS



                            //Explosion push force
                            //collider.GetComponent<Rigidbody>().AddExplosionForce(EXPLOSION_STRENGTH, transform.position, EXPLOSION_RADIUS);
                            Vector3 directionFromEpicentreToHit = (hit.point - transform.position).normalized;
                            Vector3 finalForceVector            = directionFromEpicentreToHit * EXPLOSION_PUSH_STRENGTH * (1f - (distanceBetweenHitAndEpicentre / EXPLOSION_RADIUS));
                            //Debug.Log(finalForceVector.magnitude);
                            //Model Object -> Model Size Folder -> All Models Folder -> Complete Asteroid
                            //collider.transform.parent.parent.parent.GetComponent<Rigidbody>().AddForce(finalForceVector);
                            //hit.transform.GetComponent<Rigidbody>().AddForce(finalForceVector);

                            //Explosion damage
                            Vector3 directionHitFrom = (transform.position - hit.point).normalized;
                            asteroidScript.Damage(2, directionHitFrom, hit.point);
                        }
                    }
                }
            }
        }
    }
예제 #3
0
    private void UpdateCollisionDetection()
    {
        /*
         * Unity's collision detection system is great for some things,
         * But for weapon projectiles it often doesn't do a good enough job at detecting them
         * So we use this custom method instead
         *
         * Here we use raycasting to check the space in front of the projectile for collidables
         * The distance we check ahead increases with the projectile's speed to prevent phasing
         *
         * We also have to be careful to ignore the trigger colliders since those are used for the waypoint and target system
         *
         * In the raycast, we cast out from the transform.right direction since the model is rotated
         */

        float minimumRaycastDistance = 20f; //this value must be high enough that the projectile does not phase through objects directly in front of the player
        float raycastDistance        = minimumRaycastDistance * rb.velocity.magnitude * Time.deltaTime;

        //Debug.Log(raycastDistance);
        //Debug.DrawRay(transform.position, transform.right * raycastDistance, Color.red);

        //if (Physics.Raycast(transform.position, transform.right, out RaycastHit hit, raycastDistance))

        LayerMask someLayerMask = -1;

        if (Physics.Raycast(transform.position, transform.right, out RaycastHit hit, raycastDistance, someLayerMask, QueryTriggerInteraction.Ignore))
        {
            //Debug.Log("Laser hit object: " + hit.transform.name);

            if (hit.transform.name == "CBodyAsteroid(Clone)")
            {
                CBodyAsteroid asteroidScript = hit.transform.GetComponent <CBodyAsteroid>();

                //Break apart asteroid
                if (!asteroidScript.destroyed)
                {
                    Vector3 direction = (transform.position - hit.point).normalized;
                    asteroidScript.Damage(1, direction, hit.point);

                    //Reset tooltip certainty
                    control.ui.tipAimCertainty = 0f;
                }
            }

            //Deactivate self
            DeactivateSelf();
        }
    }
예제 #4
0
    public GameObject SpawnAsteroidManually(Vector3 position, Vector3 velocity, string size, byte type, byte health) //bool randomType)
    {
        GameObject instanceCBodyAsteroid = Instantiate(
            cBodyAsteroid,
            position,
            Quaternion.Euler(
                Random.Range(0f, 360f),
                Random.Range(0f, 360f),
                Random.Range(0f, 360f)
                )
            );

        CBodyAsteroid instanceCBodyAsteroidScript = instanceCBodyAsteroid.GetComponent <CBodyAsteroid>();

        //Put in CBodies tree
        instanceCBodyAsteroid.transform.parent = cBodiesAsteroids.transform;

        //Give control reference
        instanceCBodyAsteroidScript.control = control;
        instanceCBodyAsteroid.GetComponent <Gravity>().control = control;

        //Set velocity
        instanceCBodyAsteroid.GetComponent <Rigidbody>().velocity = velocity;

        //Randomize size and type
        instanceCBodyAsteroidScript.SetSize(size);
        //instanceCBodyAsteroidScript.SetSize(instanceCBodyAsteroidScript.RandomSize()); //MUST SET SIZE FIRST SO THAT MODEL IS SELECTED

        //Type
        instanceCBodyAsteroidScript.SetType(type);

        /*
         * if (randomType)
         * {
         *  instanceCBodyAsteroidScript.SetType((byte)Random.Range(0, Ore.typeLength));
         * }
         * else
         * {
         *  instanceCBodyAsteroidScript.SetType(0);
         * }
         */

        //Health
        instanceCBodyAsteroidScript.health = health;

        return(instanceCBodyAsteroid);
    }
예제 #5
0
    private void SpawnAsteroid(string size)
    {
        //Instantiate at parent position, plus some randomness
        GameObject instanceCBodyAsteroid = Instantiate(
            control.generation.cBodyAsteroid,
            transform.position + (1.2f * new Vector3(Random.value, Random.value, Random.value)),
            Quaternion.Euler(
                Random.Range(0f, 360f),
                Random.Range(0f, 360f),
                Random.Range(0f, 360f)
                )
            );

        //Put in CBodies tree
        instanceCBodyAsteroid.transform.parent = control.generation.cBodiesAsteroids.transform;

        //Pass control reference
        instanceCBodyAsteroid.GetComponent <Gravity>().control = control;

        //Rigidbody
        Rigidbody instanceCBodyAsteroidRb = instanceCBodyAsteroid.GetComponent <Rigidbody>();

        //Ignore all collisions unless explicitly enabled (once asteroid is separated from siblings)
        instanceCBodyAsteroidRb.detectCollisions = false;
        //Copy velocity and add some random impulse force
        instanceCBodyAsteroidRb.velocity              = rb.velocity;
        instanceCBodyAsteroidRb.angularVelocity       = rb.angularVelocity;
        instanceCBodyAsteroidRb.inertiaTensor         = rb.inertiaTensor;
        instanceCBodyAsteroidRb.inertiaTensorRotation = rb.inertiaTensorRotation;
        instanceCBodyAsteroidRb.AddForce(25f * new Vector3(
                                             0.5f + (0.5f * Random.value),
                                             0.5f + (0.5f * Random.value),
                                             0.5f + (0.5f * Random.value)
                                             ));
        instanceCBodyAsteroidRb.AddTorque(100f * new Vector3(
                                              Random.value,
                                              Random.value,
                                              Random.value
                                              ));

        //Script
        CBodyAsteroid instanceCBodyAsteroidScript = instanceCBodyAsteroid.GetComponent <CBodyAsteroid>();

        instanceCBodyAsteroidScript.control = control;
        instanceCBodyAsteroidScript.SetSize(size);
        instanceCBodyAsteroidScript.SetType(type);
    }
예제 #6
0
    public void DisableSelfAndPlanDestroy()
    {
        //Emit particles
        GetComponent <ParticlesDamageRock>().EmitDamageParticles(7, Vector3.zero, transform.position, true);

        //Disable self
        GetComponent <SphereCollider>().enabled = false; //Disable waypoint trigger
        rb.detectCollisions = false;
        model.SetActive(false);
        transform.Find("Map Model").gameObject.SetActive(false);

        //Disable Station
        if (hasStation)
        {
            Destroy(instancedStation, 0f);
        }

        //Gravitate toward centre star only (so that the lack of the hitbox doesn't cause it to accelerate to infinity)
        GetComponent <Gravity>().gravitateTowardCentreStarOnly = true;

        //Spawn regular asteroids
        byte type = CBodyAsteroid.GetRandomType();

        for (int i = 0; i < 7; i++)
        {
            //Spawn
            GameObject asteroid = control.generation.SpawnAsteroidManually(
                transform.position,
                rb.velocity,
                CBodyAsteroid.GetRandomSize(),
                type,
                CBodyAsteroid.HEALTH_MAX
                );

            //Spread out
            asteroid.transform.position += 16f * new Vector3(Random.value, Random.value, Random.value);
        }

        //Play sound
        GetComponent <AudioSource>().Play();

        //Remember is disabled
        disabled = true;
    }
예제 #7
0
    private void Start()
    {
        //Check for colliders in the area
        Collider[] collidersInRadius = Physics.OverlapSphere(transform.position, EXPLOSION_RADIUS);
        foreach (Collider collider in collidersInRadius)
        {
            //Don't bother raycasting unless the collider in the area is an asteroid
            if (collider.gameObject.name == control.generation.cBodyAsteroid.name + "(Clone)")
            {
                //Cast a ray to make sure the asteroid is in LOS
                LayerMask someLayerMask  = -1;
                Vector3   rayDirection   = (collider.transform.position - transform.position).normalized;
                float     rayDistanceMax = (collider.transform.position - transform.position).magnitude;

                if (Physics.Raycast(transform.position, rayDirection, out RaycastHit hit, rayDistanceMax, someLayerMask, QueryTriggerInteraction.Ignore))
                {
                    //Make sure the ray is hitting an asteroid (something else could be in the way blocking LOS)
                    if (hit.transform.name == "CBodyAsteroid(Clone)")
                    {
                        CBodyAsteroid asteroidScript = hit.transform.GetComponent <CBodyAsteroid>();

                        //Don't bother with already destroyed asteroids
                        if (!asteroidScript.destroyed)
                        {
                            //Explosion push force
                            collider.GetComponent <Rigidbody>().AddExplosionForce(EXPLOSION_STRENGTH, transform.position, EXPLOSION_RADIUS);

                            //Explosion damage
                            Vector3 directionHitFrom = (transform.position - hit.point).normalized;
                            asteroidScript.Damage(1, directionHitFrom, hit.point);
                        }
                    }
                }
            }
        }

        //Destroy self quickly after being created
        Destroy(gameObject, 2f);
    }
예제 #8
0
    private void Update()
    {
        //DEBUG
        //---------------------------------------------------
        //Free money
        if (binds.GetInputDown(binds.bindCheat1))
        {
            currency += 1000;
            control.ui.UpdateAllPlayerResourcesUI();
            control.ui.SetTip("Show me the money.");
        }

        //Add ore water

        /*
         * if (binds.GetInputDown(binds.bindThrustVectorDecrease))
         * {
         *  ore[ORE_WATER] += 1.0;
         *  control.ui.UpdateAllPlayerResourcesUI();
         * }
         */

        //Teleport forward

        /*
         * if (binds.GetInputDown(binds.bindThrustVectorIncrease))
         * {
         *  transform.position += transform.forward * 1e4f;
         *  Debug.Log("Teleported forward: distance to star " + (control.generation.instanceCentreStar.transform.position - transform.position).magnitude);
         * }
         */

        //Spawn
        if (binds.GetInputDown(binds.bindCheat2))
        {
            control.generation.SpawnAsteroidManually(
                transform.position + transform.forward * 3f,
                rb.velocity,
                CBodyAsteroid.GetRandomSize(),
                CBodyAsteroid.GetRandomType(),
                CBodyAsteroid.HEALTH_MAX
                );
            control.ui.SetTip("Spawned one asteroid.");
            upgradeLevels[control.commerce.UPGRADE_SEISMIC_CHARGES] = 1;
            control.ui.SetTip("Seismic charges unlocked.");
        }

        /*
         * if (binds.GetInputDown(binds.bindThrustVectorDecrease))
         * {
         *  control.SpawnPlanetoidManually(transform.position + transform.forward * 20f, rb.velocity, null);
         *  Debug.Log("Spawned one planetoid");
         * }
         */


        //Slow motion

        /*
         * if (binds.GetInput(binds.bindPrimaryFire))
         * {
         *  Time.timeScale = 0.01f;
         * }
         * else if (!Menu.menuOpenAndGamePaused)
         * {
         *  Time.timeScale = 1f;
         * }
         */

        //---------------------------------------------------

        //Slow update
        if (Time.frameCount % 3 == 0)
        {
            SlowUpdate();
        }

        //Have the position mount follow the player position
        positionMount.transform.position = transform.position;

        //Setup the camera
        if (!fovSet)
        {
            SetCameraSettings();
        }

        //AUDIO
        UpdateAudio();

        //Don't run if paused
        if (!Menu.menuOpenAndGamePaused)
        {
            UpdateGetIfMoving();            //Check if moving at all so that it only has to be checked once per update
            UpdatePlayerWeapons();          //Shoot stuff

            UpdatePlayerEngineEffect();     //Set engine glow relative to movement

            //Fuel decrement
            if (canAndIsMoving)
            {
                vitalsFuel = Math.Max(0.0, vitalsFuel - ((vitalsFuelConsumptionRate / (1 + upgradeLevels[control.commerce.UPGRADE_FUEL_EFFICIENCY])) * Time.deltaTime));
            }

            //Fuel increment (in-situ refinery)
            bool missingEnoughFuel   = vitalsFuel < vitalsFuelMax - REFINERY_FUEL_OUT_RATE;
            bool hasUpgrade          = upgradeLevels[control.commerce.UPGRADE_IN_SITU_FUEL_REFINERY] >= 1;
            bool hasEnoughOre        = ore[ORE_WATER] > REFINERY_ORE_WATER_IN_RATE;
            bool enoughTimeHasPassed = Time.time > refineryTimeAtLastRefine + REFINERY_TIME_BETWEEN_REFINES;

            if (missingEnoughFuel && hasUpgrade && hasEnoughOre && enoughTimeHasPassed && control.settings.refine)
            {
                ore[ORE_WATER] -= REFINERY_ORE_WATER_IN_RATE;
                vitalsFuel     += REFINERY_FUEL_OUT_RATE;
                control.ui.UpdatePlayerOreWaterText();
                refineryTimeAtLastRefine = Time.time;
            }

            //Warn on loop if out of fuel
            if (vitalsFuel <= 0d && warningUIFlashTime <= 0f)
            {
                FlashWarning("Fuel reserves empty");

                //Loop smoothly and indefinitely
                warningUIFlashTime = warningUIFlashTotalDuration * 100f;
            }

            //Without this it would be possible for the out of fuel warning to flash indefinitely if you ran out of fuel right as you entered a station
            if (vitalsFuel > 0d && warningUIText.text == "Fuel reserves empty")
            {
                warningUIFlashTime     = 0f;
                warningUIFlashPosition = 1f;
            }

            //Update map player ship position
            transform.parent.Find("Ship Map Model").position = transform.position;

            /*
             * transform.parent.Find("Ship Map Model").position.Set(
             *  transform.position.x,
             *  1000f,
             *  transform.position.z
             * );
             */
        }
    }