private void Explode()
    {
        // detach rocket trail
        rocketTrail.Stop();
        rocketTrail.transform.SetParent(null);
        Destroy(rocketTrail.gameObject, rocketTrail.duration);

        // freeze position
        rb.isKinematic = true;
        collided       = true;

        // hide geometry
        foreach (Renderer r in GetComponentsInChildren <Renderer>())
        {
            if (r != GetComponent <Renderer> ())
            {
                r.enabled = false;
            }
        }

        // explode
        explosion.Play();

        // damage and apply explosion force to objects
        // add gravity down vector to boost upward force on explosion
        Utilities.CreateExplosion(transform.position + GlobalGravityControl.GetCurrentGravityVector(),
                                  expRadius, expDamage, expForce);

        // destroy ui marker
        uiMarker.DestroyMarker();

        // destroy after exploding
        Destroy(gameObject, explosion.duration);
    }
예제 #2
0
    // Gets the collective gravity of all planets and updates the GlobalGravityControl
    private void UpdateGravity()
    {
        Vector3 newGravDir = Vector3.zero;

        Vector3 strongest = Vector3.zero;

        foreach (PlanetaryGravitySource source in gravitySources)
        {
            Vector3 sourceGravity = source.GetGravityVector();

            if (sourceGravity.magnitude > strongest.magnitude)
            {
                strongest = sourceGravity;
            }

            newGravDir += sourceGravity;
        }

        // Aligns gravity direction to cumulative direction - overall center of mass
        //float newGravStrength = newGravDir.magnitude;
        //newGravDir.Normalize();
        //GlobalGravityControl.ChangeGravity(newGravDir, newGravStrength, true);

        // Always aligns gravity direction to strongest source
        float newGravStrength = Vector3.Dot(newGravDir.normalized, strongest.normalized) * strongest.magnitude; // takes component along strongest source

        strongest.Normalize();
        GlobalGravityControl.ChangeGravity(strongest, newGravStrength, false);
    }
예제 #3
0
 void OnAttachKnife(object sender, object args)
 {
     knifeController    = (KnifeController)args;
     knifeObject        = knifeController.gameObject;
     safeWarpCollider   = knifeObject.GetComponentInChildren <SafeWarpCollider>();
     colliding          = false;
     transform.position = knifeObject.transform.position;
     transform.rotation = GlobalGravityControl.GetGravityRotation();
     lastUsablePos      = knifeObject.transform.position;
     Enabled(true);
 }
예제 #4
0
    /*
     * Performs a vault to the height of the ledge in front of the player
     */
    private IEnumerator PerformVault()
    {
        vaulting = true;

        while (PlayerCollisionController.GetVaultHeight() > 0f)
        {
            // Get the force required to move the player up to the level of the ledge
            float force = Mathf.Sqrt(PlayerCollisionController.GetVaultHeight() * -2 *
                                     -GlobalGravityControl.GetGravityStrength());

            rb.velocity = transform.up * force;
            yield return(0);
        }

        vaulting = false;
    }
 /*
  * Player must be last child
  */
 void Update()
 {
     if (linkGrav || target.IsChildOf(transform))
     {
         currentGrav = GlobalGravityControl.GetGravityTarget();
         Vector3 newGrav = (transform.position - target.position).normalized;
         if (currentGrav != newGrav)
         {
             if (invertGravDirection)
             {
                 GlobalGravityControl.ChangeGravity(-newGrav, true);
             }
             else
             {
                 GlobalGravityControl.ChangeGravity(newGrav, true);
             }
         }
     }
 }
    void Awake()
    {
        rotationObjects = (RotateToGravity[])FindObjectsOfType(typeof(RotateToGravity));

        player = GameObject.FindGameObjectWithTag("Player");

        if (player == null)
        {
            Debug.LogError("No player object found");
        }

        playerMotor = player.GetComponent <PlayerMotor>();

        currentGravDirection = -player.transform.up;
        targetGravDirection  = currentGravDirection;

        baseGravStrength = currentGravStrength;

        instance = this;
    }
예제 #7
0
    /*
     * Triggers a transition back to default gravity after a certain time.
     *
     * Used to apply time limit to player gravity shifting
     */
    IEnumerator GravShiftCountdown()
    {
        // TODO: MAY WANT TO REMOVE THIS
        float t = 0.0f;

        while (t < 1f)
        {
            // Don't count down if frozen (stops countdown from running while warp transition is happening)
            if (!frozen)
            {
                t += Time.deltaTime * (Time.timeScale / gravShiftTimeLimit);
            }

            yield return(0);
        }

        // TODO: uncomment this if removing above
        //yield return new WaitForSeconds(gravShiftTimeLimit);

        // trigger transition back to default gravity
        GlobalGravityControl.TransitionToDefault();
    }
예제 #8
0
    // applies a constant gravity value to the closest grav source
    void UpdateGravity()
    {
        FixedPlanetGravSource closestSource = null;
        float closestDist = float.MaxValue;

        foreach (FixedPlanetGravSource source in gravitySources)
        {
            float distToTarget = source.GetDistToSurface();
            if (distToTarget < closestDist)
            {
                closestDist   = distToTarget;
                closestSource = source;
            }
        }

        if (closestSource == null)
        {
            return;
        }

        GlobalGravityControl.ChangeGravity(closestSource.GetGravityVector(), closestSource.GetGravityStrength(), false);
    }
예제 #9
0
    private void LogPlayerStats()
    {
        // print/log position velocity etc
        string playerDebugString = "Player: ";

        playerDebugString += "Pos " + player.transform.position + " ";
        playerDebugString += "Vel " + playerRb.velocity + " ";
        playerDebugString += "Spd " + playerRb.velocity.magnitude.ToString("F2") + " ";

        float localXZSpeed = Vector3.ProjectOnPlane(playerRb.velocity, GlobalGravityControl.GetCurrentGravityVector()).magnitude;
        float localYSpeed  = Vector3.Project(playerRb.velocity, GlobalGravityControl.GetCurrentGravityVector()).magnitude;

        playerDebugString += "lclXZ " + localXZSpeed.ToString("F2") + " ";
        playerDebugString += "lclY " + localYSpeed.ToString("F2") + " ";

        playerDebugString += "Input: " + motor.GetInputVelocity();

        //// dont print new line if identical to last line
        //if (playerDebugString == lastDebugString)
        //    return;

        Debug.Log(playerDebugString);
        //lastDebugString = playerDebugString;
    }
예제 #10
0
    /*
     * Warps the player to the current knife position, inheriting velocity and moving gravity vectors if required
     */
    public void WarpToKnife(bool _shiftGravity, KnifeController _knifeController, FibreOpticController _fibreOpticController = null)
    {
        if (frozen)
        {
            return;
        }

        // record starting position and rotation for transitionCamera
        Vector3    camStartPos    = cam.transform.position;
        Quaternion camStartRot    = cam.transform.rotation;
        Vector3    relativeFacing = cam.transform.forward;

        Vector3 newGravDirection = _knifeController.GetGravVector();

        bool fibreOpticWarp = _fibreOpticController != null;

        // Shift gravity if the difference between current gravity and surface normal is
        // above the threshold defined by warpGravShiftAngle
        float surfaceDiffAngle = Vector3.Angle(-transform.up, newGravDirection);
        bool  gravityShift     = (_shiftGravity && surfaceDiffAngle > warpGravShiftAngle && newGravDirection != Vector3.zero);

        if (gravityShift)
        {
            this.PostNotification(GravityWarpNotification, _knifeController.GetStuckObject());
        }
        else
        {
            this.PostNotification(WarpNotification);
        }

        // rotate to face new direction at end of warp.
        // needed for gravity and fibreoptic warps
        if (gravityShift)
        {
            RotateToDirection(newGravDirection, relativeFacing);
        }
        else if (fibreOpticWarp)
        {
            RotateToDirection(currentGravVector, _fibreOpticController.GetExitDirection(), true);
        }

        // Determine transitionCamera end rotation
        Quaternion camEndRot = (gravityShift) ? transform.rotation : camStartRot;

        // Setup transitionCamera
        transCamController.Setup(cam.fieldOfView, camStartPos, _knifeController, cameraRelativePos, camStartRot, camEndRot, gravityShift, _fibreOpticController);

        cam.enabled = false;
        Freeze();

        // Begin warp transition
        transCamController.StartTransition();

        if (gravityShift)
        {
            GlobalGravityControl.TransitionGravity(newGravDirection, transCamController.GetDuration());

            // Begin gravity shift countdown coroutine
            if (gravShiftTimerCoroutine != null)
            {
                StopCoroutine(gravShiftTimerCoroutine);
            }

            gravShiftTimerCoroutine = StartCoroutine("GravShiftCountdown");
        }
    }
예제 #11
0
    /*
     * TODO: move or remove
     *
     * Try locking skybox and scene lighting to XZ orientation of the player
     *
     *  - Could take this one step further
     *  Rotate skybox and lighting at the same time as gravity, but in
     *  a different (opposite?) direction.
     *
     *  Get a cool light/shadow sweep effect when warping
     *  Will need a slower warp for this effect though
     *
     *  Puzzle elements!!
     *  Other pieces of scenery that rotate when gravity shifts
     *  paths that can only be accessed when gravity is in a particular direction?
     */

    /*
     * Handles GravityChangeNotification, updates local current gravity variable
     */
    void OnGravityChange(object sender, object args)
    {
        currentGravVector = GlobalGravityControl.GetCurrentGravityVector();
    }
예제 #12
0
    /*
     * Handles transition logic for fibreoptic warps.
     *
     * Transitions to the start of the fibre, then along it
     */
    IEnumerator FibreTransitionCamera()
    {
        float fibreOpticDuration = fibreOpticController.GetDuration();

        float totalDuration = duration + fibreOpticDuration;
        bool  transitionFov = totalDuration > 0.5f;

        float t = 0.0f;

        while (t < 1.0f)
        {
            t += Time.deltaTime * (Time.timeScale / duration);
            t  = Mathf.Clamp01(t);

            float lerpPercent = t * t * t; // modify t value to allow non-linear transitions

            // lerp position and rotation
            transform.position = Vector3.Lerp(startPos, fibreOpticController.GetPosition(), lerpPercent);
            transform.rotation = Quaternion.Lerp(startRot, fibreOpticController.GetStartRotation(), lerpPercent);

            // Warp camera effects
            float totalT = (t * duration) / totalDuration;
            WarpCameraEffects(totalT, transitionFov);

            yield return(0);
        }

        // Fibre optic warp transition here
        float t2 = 0f;

        while (t2 < 1f)
        {
            t2 += Time.deltaTime * (Time.timeScale / fibreOpticDuration);
            t2  = Mathf.Clamp01(t2);

            transform.position = fibreOpticController.GetBezierPosition(t2);

            Vector3    tangent     = fibreOpticController.GetBezierTangent(t2);
            Quaternion newRotation = GlobalGravityControl.GetRotationToDir(tangent);

            // rotate camera to face bezier tangent and lean slightly depending on angle of turn
            // Lots of calculations. may be a bit much for such a subtle effect :P
            float tAlt = Mathf.Abs((2f * t2) - 1f);
            tAlt = 1f - (tAlt * tAlt);
            Vector3 flattened = Vector3.ProjectOnPlane(tangent, transform.up).normalized;
            float   angle     = Vector3.Angle(transform.forward, flattened) * 10f * tAlt;
            float   dot       = Vector3.Dot(tangent, transform.right);

            Quaternion lean = Quaternion.AngleAxis((dot < 0) ? angle : -angle, tangent);
            newRotation = Quaternion.RotateTowards(newRotation, lean * newRotation, 10f);

            transform.rotation = newRotation;

            // Warp camera effects
            float totalT = (duration + (t2 * fibreOpticDuration)) / totalDuration;
            WarpCameraEffects(totalT, transitionFov);

            yield return(0);
        }

        Info <Vector3, Vector3, bool, FibreOpticController> info = new Info <Vector3, Vector3, bool, FibreOpticController>(knifeController.GetWarpPosition(),
                                                                                                                           knifeController.transform.up,
                                                                                                                           knifeController.AutoWarp(), fibreOpticController);

        this.PostNotification(WarpEndNotification, info);

        //Destroy(gameObject);
        Disable();
    }
예제 #13
0
 // Update current gravity direction and strength
 void UpdateGravityValues()
 {
     currentGravityStrength = GlobalGravityControl.GetGravityStrength() * gravityModifier;
     currentGravityVector   = GlobalGravityControl.GetCurrentGravityVector();
 }
예제 #14
0
    /*
     * Throw knife at given strength
     */
    void ThrowKnife(float _strength, bool _secondary = false)
    {
        if (currentWarps < 1)
        {
            return;
        }

        // TODO: replace with consistent knife instances. one for each type
        // instantiate knife prefab
        knife           = Instantiate((_secondary) ? secondaryKnifePrefab : primaryKnifePrefab, transform.position, GlobalGravityControl.GetGravityRotation());
        knifeController = knife.GetComponent <KnifeController>();

        // check that we have actually got a knife
        if (knifeController == null)
        {
            Debug.LogError("No KnifeController found on knife prefab");
            return;
        }

        // set up and throw knife object
        knifeController.Setup(knifeInHand.transform, warpLookAheadCollider);
        knifeController.Throw(transform.forward * _strength);

        // hide knife view object
        HideKnife(true);
    }
예제 #15
0
 public Quaternion GetEndRotation()
 {
     //return Quaternion.AngleAxis(180, otherEndFibreOpticController.transform.up) * otherEndFibreOpticController.transform.rotation;
     return(GlobalGravityControl.GetRotationToDir(otherEndFibreOpticController.GetDirection()));
 }
예제 #16
0
 // Get rotations for aligning transition camera
 public Quaternion GetStartRotation()
 {
     return(GlobalGravityControl.GetRotationToDir(-GetDirection()));
 }
예제 #17
0
 void OnGravityChangeNotification(object sender, object args)
 {
     currentGravVector   = GlobalGravityControl.GetCurrentGravityVector();
     currentGravRotation = GlobalGravityControl.GetGravityRotation();
 }