//***********************************************************
// Filename: DistortedTeleport.cs
// Author: Moritz Kolvenbach, Marco Fendrich
// Last changes: Thursday, 9th of August 2018
// Content: Class that adds rotation and a tilt via controller to AdjustableSpeedTeleport but only after maximum of parabola
//***********************************************************
using UnityEngine;
///
/// Child class of CurveTeleport adding rotation and a tilt via controller but only after maximum of parapola
///
public class DistortedTeleport : CurveTeleport
{
///
/// Entire calculation is analogue to except:
/// the commented lines
/// acceleration was replaced with distortedAcceleration (simply being tilted according to controller)
///
protected override void UpdateProjectionPoints()
{
normalisedVelocity = transform.TransformDirection(initialVelocity);
projectionPoints.Clear();
projectionPoints.Add(transform.position);
// acceleration from maximum of parabola onwards; starting with normal acceleration
Vector3 distortedAcceleration = acceleration;
Vector3 last = transform.position;
// trigger for points after maximum
bool distortionTriggered = false;
for (int i = 0; i < pointCount; i++)
{
float t = pointSpacing / normalisedVelocity.magnitude;
normalisedVelocity = normalisedVelocity + distortedAcceleration * t;
// if maximum wasn't reached before and velocity is now negative - therefore past maximum
if (normalisedVelocity.y < 0 && !distortionTriggered)
{
// set acceleration to tilt with controller
distortedAcceleration =
Quaternion.Euler(limitRotation(transform.rotation.eulerAngles, 80)) * acceleration * 10F;
// remove latest point as this one will be past the maximum yet calculated with normal acceleration
projectionPoints.RemoveAt(projectionPoints.Count-1);
distortionTriggered = true;
}
Vector3 next = last + normalisedVelocity * t + 0.5F * distortedAcceleration * t * t;
Vector3 castHit;
Vector3 norm;
bool endOnNavmesh;
if (navMesh.Linecast(last, next, out endOnNavmesh, out castHit, out norm))
{
// add rotation according to the angle in which the last point stands to the hit point on the ground times 1.5
// get angle of last point to hit point
Vector2 projectedEnd = new Vector2(castHit.x - projectionPoints[projectionPoints.Count - 1].x, castHit.z - projectionPoints[projectionPoints.Count - 1].z);
// get angle of controller
Vector2 controllerDirection = new Vector2(transform.forward.x, transform.forward.z);
// get difference between those two angles to get actual offset independent of world space
rotation = Vector2.SignedAngle(projectedEnd, controllerDirection) * 1.5F;
projectionPoints.Add(castHit);
normalisedHitPoint = norm;
pointOnNavMesh = endOnNavmesh;
return;
}
else
{
projectionPoints.Add(next);
}
last = next;
}
normalisedHitPoint = Vector3.up;
pointOnNavMesh = false;
}
}