Esempio n. 1
0
    public static float DistanceFromGround(Rigidbody player, out PillarBehaviour hitPillar)
    {
        // Find the highest pillar cllider under the player and return the distance from it
        hitPillar = null;
        float highestHit = -1;
        var   hits       = Physics.RaycastAll(
            player.transform.position + player.transform.up,
            -player.transform.up,
            2 * UserDefinedConstants.sphereRadius,
            1 << LayerMask.NameToLayer("Environment"));

        if (hits.Length == 0)
        {
            Debug.LogError("Nothing under player!");
            return(-1);
        }
        foreach (var hit in hits)
        {
            var pillar = hit.collider.gameObject.GetComponent <PillarBehaviour>();
            if (pillar != null && pillar.currentHeight > highestHit)
            {
                hitPillar  = pillar;
                highestHit = pillar.currentHeight;
            }
        }
        if (hitPillar == null)
        {
            Debug.LogError(string.Format("Raycast didn't get a pillar / bounding-sphere hit! Hit {0} instead", hits[0].collider.gameObject.name));
            return(-1);
        }
        float dist = (UserDefinedConstants.sphereRadius - hitPillar.currentHeight) - player.position.magnitude; // Dist of pillar surface from origin minus dist of player from origin

        return(dist);
    }
    public static PillarBehaviour Create(
        bool isHexagon,
        Vector3 location,
        float edgeLength,
        float h,
        float collExpansion,
        int pillarId = -1)
    {
        Object          obj       = isHexagon ? Resources.Load("Prefabs/Hexagon") : Resources.Load("Prefabs/Pentagon");
        GameObject      pillarObj = Instantiate(obj, location, Quaternion.identity) as GameObject;
        PillarBehaviour pillar    = pillarObj.GetComponent <PillarBehaviour>();

        pillar.isHex              = isHexagon;
        pillar.edge               = edgeLength;
        pillar.targetHeight       = h;
        pillar.currentHeight      = h;
        pillar.maxHeight          = maxHeightPercentage * UserDefinedConstants.sphereRadius;
        pillar.extensionDelta     = extensionDeltaPercentage * UserDefinedConstants.sphereRadius;
        pillar.timeToTarget       = 0f;
        pillar.collisionExpansion = collExpansion;
        pillar.extending          = false;
        pillar.primedToLaunch     = false;
        pillar.heightLocked       = false;
        pillar.id            = pillarId;
        pillar.mesh          = new Mesh();
        pillar.collMesh      = new Mesh();
        pillar.needRedraw    = true;
        pillar.meshVertexMap = new Dictionary <int, int>();
        return(pillar);
    }
    private void extensionFX()
    {
        // We want to play a sound from the height of the lowest neighbor (lower than us)
        PillarBehaviour lowestNeighbor = null;

        foreach (PillarBehaviour neighbor in neighbors)
        {
            if (neighbor.currentHeight > currentHeight + 1)
            {
                continue;
            }
            // We'll play a sound from the height of the lowest-height neighbor (if we're not surrounded by higher neighbors).
            if (lowestNeighbor == null || lowestNeighbor.currentHeight > neighbor.currentHeight)
            {
                lowestNeighbor = neighbor;
            }
        }
        float   soundHeight   = lowestNeighbor == null ? currentHeight : lowestNeighbor.currentHeight;
        Vector3 soundLocation = transform.position - (soundHeight * transform.position.normalized);

        AudioSource.PlayClipAtPoint(extensionSoundSteam, soundLocation);
        AudioSource.PlayClipAtPoint(extensionSoundScreech[Mathf.FloorToInt(Random.Range(0, extensionSoundScreech.Length - 0.01f))], soundLocation);

        // We show steam coming out from the center of the pillar
        Vector3 steamLocation = soundLocation + 15 * transform.position.normalized; // A little lower
        var     steam         = Instantiate(steamPrefab, steamLocation, Quaternion.identity);

        steam.transform.LookAt(Vector3.zero);
        Destroy(steam, steam.GetComponent <ParticleSystem>().main.duration * 5);
    }
Esempio n. 4
0
    /** Only the shooter's instance of the projectile has a collider */
    void OnCollisionEnter(Collision col)
    {
        if (destroyed)
        {
            return;            // Don' process more than one collision... hope this helps...?
        }
        // The first thing a projectile hits should destroy it (unless it's the shooter)
        GameObject obj = col.gameObject;

        // Check if it's a player. If it is, filter out the shooter.
        PlayerMovementController pmc = obj.GetComponent <PlayerMovementController>();
        bool hitPlayer = (pmc != null);

        if (hitPlayer)
        {
            // Is this the shooter?
            if (Tools.NullToEmptyString(obj.GetComponent <PhotonView>().Owner.UserId) == shooterId)
            {
                return;
            }
        }

        // Did we hit a pillar?
        PillarBehaviour pillar    = obj.GetComponent <PillarBehaviour>();
        bool            hitPillar = (pillar != null);

        if (hitPillar)
        {
            // TODO: One day I'll find out why objects are suddenly null...
            if (pillarCtrl == null)
            {
                InitControllers();
            }
            pillarCtrl.BroadcastHitPillar(pillar.id);
        }

        // Is this projectile seeking a targetable player? If so we need to tell him we're not seeking him anymore
        if (lockedOn)
        {
            target.BroadcastBecameUntargeted(shooterId);
        }

        // Did we hit the sun?
        SunController sun = obj.GetComponent <SunController>();

        if (sun != null)
        {
            sun.BroadcastHit(shooterId);
        }

        // In any case, all collisions destroy the projectile
        explosionCtrl.BroadcastExplosion(transform.position, shooterId, false);
        projectileCtrl.BroadcastDestroyProjectile(projectileId);
        destroyed = true;
    }
    void ComputeExplosionPositions()
    {
        // We're in RPC context here (someone broadcasted a sun hit). We only broadcast an explosion if we're the shooter so otherwise we don't care
        if (shooterId != Tools.NullToEmptyString(PhotonNetwork.LocalPlayer.UserId))
        {
            return;
        }

        // Find all objects in the sunray. Should always hit a pillar, at least.
        RaycastHit[] hits = Physics.RaycastAll(Vector3.zero, target.position);
        if (hits.Length == 0)
        {
            Debug.LogError("Sunray found nothing to hit with explosion! Exploding in the sun...");
            explosionPositions = new List <Vector3> {
                Vector3.zero
            };
            return;
        }

        // Find the highest hit pillar
        PillarBehaviour hitPillar         = null;
        Vector3         hitPillarPosition = Vector3.zero;

        foreach (var hit in hits)
        {
            // Ignore non-pillar objects
            PillarBehaviour pillar = hit.collider.GetComponent <PillarBehaviour>();
            if (pillar == null)
            {
                continue;
            }
            // Only take the highest hit pillar (with hitpoint closest to (0,0,0))
            if (hitPillar == null || hitPillarPosition.magnitude > hit.point.magnitude)
            {
                hitPillar         = pillar;
                hitPillarPosition = hit.point;
            }
        }

        // Add the hit pillar location to the explosion list, and find all hit players above the pillar
        explosionPositions = new List <Vector3> {
            hitPillarPosition
        };
        hitPillarId = hitPillar.id;
        foreach (var hit in hits)
        {
            // Ignore the sun itself, and all objects below the height of the hit pillar
            if (hit.point.magnitude > hitPillarPosition.magnitude || hit.collider.gameObject.name == "Sun")
            {
                continue;
            }
            // If this is a network character closer to the sun than the top of the pillar, add the hitpoint.
            // However, if player is grounded, don't trigger an explosion; player should be taking damage from the explosion on the pillar
            bool      isNetChar = hit.collider.GetComponent <NetworkCharacter>() != null;
            Rigidbody rb        = hit.collider.GetComponent <Rigidbody>();
            bool      grounded  = rb != null && GeoPhysics.IsPlayerGrounded(rb);
            if (isNetChar && !grounded)
            {
                explosionPositions.Add(hit.point);
            }
        }
    }
Esempio n. 6
0
    public static bool IsPlayerGrounded(Rigidbody player, out PillarBehaviour hitPillar)
    {
        float dist = DistanceFromGround(player, out hitPillar);

        return(hitPillar == null ? false : dist < 0.1f);
    }