//*********************************************************** // Filename: CurveTeleport.cs // Author: Moritz Kolvenbach, Marco Fendrich // Last changes: Wednesday, 8th of August 2018 // Content: Class that adds a tilt and a rotation via controller to AdjustableSpeedTeleport //*********************************************************** using UnityEngine; /// /// Child class of AdjustableSpeedTeleport adding a tilt and a rotation via controller /// public class CurveTeleport : AdjustableSpeedTeleport { private Vector3 normalisedAcceleration; /// /// Entire calculation is analogue to except: /// the commented lines /// acceleration was replaced with normalisedAcceleration (simply being tilted according to controller) /// protected override void UpdateProjectionPoints() { // tilt rotation corresponding to tilt of controller but limit this tilt to 80° normalisedAcceleration = Quaternion.Euler(limitRotation(transform.rotation.eulerAngles, 80)) * acceleration; normalisedVelocity = transform.TransformDirection(initialVelocity); projectionPoints.Clear(); projectionPoints.Add(transform.position); Vector3 last = transform.position; float t = 0; for (int i = 0; i < pointCount; i++) { t += pointSpacing / CalculateNewVelocity(normalisedVelocity, normalisedAcceleration, t).magnitude; Vector3 next = CalculateNewPosition(transform.position, normalisedVelocity, normalisedAcceleration, 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; } /// /// Limits the eulerAngle vector given as input in its z rotation to the second input given /// /// eulerAngle vector that will be limited in z rotation /// limit in degrees of z rotation left and right /// eulerAngle vector with limited z rotation protected Vector3 limitRotation(Vector3 toBeLimited, float limit) { if (toBeLimited.z < 360-limit && toBeLimited.z > 180) { toBeLimited.z = 360-limit; } else if (toBeLimited.z > limit && toBeLimited.z < 180) { toBeLimited.z = limit; } return toBeLimited; } }