// Update is called once per frame
    void Update()
    {
        fwdBack        = Input.GetAxis("Vertical");
        leftRight      = Input.GetAxis("Horizontal");
        grounded       = GeoPhysics.IsPlayerGrounded(rb);
        distFromGround = GeoPhysics.DistanceFromGround(rb);

        UpdateMove();
        UpdateJump();
        UpdateLand();
    }
    // Assumes rigidbody is collided with pillar, and is just as close to the origin as the pillar.
    // TODO: This could be given some more thought...
    private bool isOverPillar(Rigidbody rb)
    {
        PillarBehaviour underneath;

        if (!GeoPhysics.IsPlayerGrounded(rb, out underneath))
        {
            return(false);
        }
        // Return true <==> the object is grounded on this specific pillar
        return(underneath != null ? underneath.id == id : false);
    }
    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);
            }
        }
    }
 // Update is called once per frame
 void FixedUpdate()
 {
     GeoPhysics.ApplyGravity(rb);
 }