Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Platformer/Platformer/Assets/Scripts/PlatformController.cs
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
242 lines (203 sloc)
8.42 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
using System.Collections.Generic; | |
public class PlatformController : RaycastController | |
{ | |
//what layer to intereact with | |
public LayerMask passengerMask; | |
//way points to move to | |
public Vector3[] localWaypoints; | |
Vector3[] globalWaypoints; | |
//Basic data for the moving platform | |
public float speed; | |
public bool cyclic; | |
public float waitTime; | |
[Range(0, 2)] | |
public float easeAmount; | |
//to calculate speed and move time | |
int fromWaypointIndex; | |
float percentBetweenWaypoints; | |
float nextMoveTime; | |
List<PassengerMovement> passengerMovement; | |
Dictionary<Transform, Controller2D> passengerDictionary = new Dictionary<Transform, Controller2D>(); | |
//ovveride raycast controller start | |
public override void Start() | |
{ | |
base.Start(); | |
//waypoint setup | |
globalWaypoints = new Vector3[localWaypoints.Length]; | |
for (int i = 0; i < localWaypoints.Length; i++) | |
{ | |
globalWaypoints[i] = localWaypoints[i] + transform.position; | |
} | |
} | |
void Update() | |
{ | |
//call updateraycast origins | |
UpdateRaycastOrigins(); | |
//velocity of platform | |
Vector3 velocity = CalculatePlatformMovement(); | |
CalculatePassengerMovement(velocity); | |
MovePassengers(true); | |
transform.Translate(velocity); | |
MovePassengers(false); | |
} | |
//platform slowing down aka ease | |
float Ease(float x) | |
{ | |
float a = easeAmount + 1; | |
return Mathf.Pow(x, a) / (Mathf.Pow(x, a) + Mathf.Pow(1 - x, a)); | |
} | |
//calculate movement of the platform | |
Vector3 CalculatePlatformMovement() | |
{ | |
//dont move | |
if (Time.time < nextMoveTime) | |
{ | |
return Vector3.zero; | |
} | |
//Calculating the next movement | |
fromWaypointIndex %= globalWaypoints.Length; | |
int toWaypointIndex = (fromWaypointIndex + 1) % globalWaypoints.Length; | |
//distance between points, references global waypoints | |
float distanceBetweenWaypoints = Vector3.Distance(globalWaypoints[fromWaypointIndex], globalWaypoints[toWaypointIndex]); | |
percentBetweenWaypoints += Time.deltaTime * speed / distanceBetweenWaypoints; | |
percentBetweenWaypoints = Mathf.Clamp01(percentBetweenWaypoints); | |
//eased oercentage | |
float easedPercentBetweenWaypoints = Ease(percentBetweenWaypoints); | |
//Lerp, which you talked about in class before | |
Vector3 newPos = Vector3.Lerp(globalWaypoints[fromWaypointIndex], globalWaypoints[toWaypointIndex], easedPercentBetweenWaypoints); | |
//if its more than 1% between waypoints | |
if (percentBetweenWaypoints >= 1) | |
{ | |
percentBetweenWaypoints = 0; | |
fromWaypointIndex++; | |
//if it goes in a cyclic nature | |
if (!cyclic) | |
{ | |
if (fromWaypointIndex >= globalWaypoints.Length - 1) | |
{ | |
fromWaypointIndex = 0; | |
System.Array.Reverse(globalWaypoints); | |
} | |
} | |
nextMoveTime = Time.time + waitTime; | |
} | |
return newPos - transform.position; | |
} | |
//move the passangers before the platform moves | |
void MovePassengers(bool beforeMovePlatform) | |
{ | |
foreach (PassengerMovement passenger in passengerMovement) | |
{ | |
if (!passengerDictionary.ContainsKey(passenger.transform)) | |
{ | |
passengerDictionary.Add(passenger.transform, passenger.transform.GetComponent<Controller2D>()); | |
} | |
if (passenger.moveBeforePlatform == beforeMovePlatform) | |
{ | |
passengerDictionary[passenger.transform].Move(passenger.velocity, passenger.standingOnPlatform); | |
} | |
} | |
} | |
//calculate how fast to move passanger before platform | |
void CalculatePassengerMovement(Vector3 velocity) | |
{ | |
HashSet<Transform> movedPassengers = new HashSet<Transform>(); | |
passengerMovement = new List<PassengerMovement>(); | |
float directionX = Mathf.Sign(velocity.x); | |
float directionY = Mathf.Sign(velocity.y); | |
// Vertically moving platform | |
if (velocity.y != 0) | |
{ | |
float rayLength = Mathf.Abs(velocity.y) + skinWidth; | |
for (int i = 0; i < verticalRayCount; i++) | |
{ | |
Vector2 rayOrigin = (directionY == -1) ? raycastOrigins.bottomLeft : raycastOrigins.topLeft; | |
rayOrigin += Vector2.right * (verticalRaySpacing * i); | |
RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.up * directionY, rayLength, passengerMask); | |
if (hit && hit.distance !=0) //&& player is not in platform | |
{ | |
if (!movedPassengers.Contains(hit.transform)) | |
{ | |
movedPassengers.Add(hit.transform); | |
float pushX = (directionY == 1) ? velocity.x : 0; | |
float pushY = velocity.y - (hit.distance - skinWidth) * directionY; | |
passengerMovement.Add(new PassengerMovement(hit.transform, new Vector3(pushX, pushY), directionY == 1, true)); | |
} | |
} | |
} | |
} | |
// Horizontally moving platform | |
if (velocity.x != 0) | |
{ | |
float rayLength = Mathf.Abs(velocity.x) + skinWidth; | |
for (int i = 0; i < horizontalRayCount; i++) | |
{ | |
Vector2 rayOrigin = (directionX == -1) ? raycastOrigins.bottomLeft : raycastOrigins.bottomRight; | |
rayOrigin += Vector2.up * (horizontalRaySpacing * i); | |
RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.right * directionX, rayLength, passengerMask); | |
if (hit && hit.distance != 0) | |
{ | |
if (!movedPassengers.Contains(hit.transform)) | |
{ | |
movedPassengers.Add(hit.transform); | |
float pushX = velocity.x - (hit.distance - skinWidth) * directionX; | |
float pushY = -skinWidth; | |
passengerMovement.Add(new PassengerMovement(hit.transform, new Vector3(pushX, pushY), false, true)); | |
} | |
} | |
} | |
} | |
// Passenger on top of a horizontally or downward moving platform | |
if (directionY == -1 || velocity.y == 0 && velocity.x != 0) | |
{ | |
float rayLength = skinWidth * 2; | |
for (int i = 0; i < verticalRayCount; i++) | |
{ | |
Vector2 rayOrigin = raycastOrigins.topLeft + Vector2.right * (verticalRaySpacing * i); | |
RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.up, rayLength, passengerMask); | |
if (hit && hit.distance != 0) | |
{ | |
if (!movedPassengers.Contains(hit.transform)) | |
{ | |
movedPassengers.Add(hit.transform); | |
float pushX = velocity.x; | |
float pushY = velocity.y; | |
passengerMovement.Add(new PassengerMovement(hit.transform, new Vector3(pushX, pushY), true, false)); | |
} | |
} | |
} | |
} | |
} | |
//struct to keep some variables as well as passenger movement | |
struct PassengerMovement | |
{ | |
public Transform transform; | |
public Vector3 velocity; | |
public bool standingOnPlatform; | |
public bool moveBeforePlatform; | |
public PassengerMovement(Transform _transform, Vector3 _velocity, bool _standingOnPlatform, bool _moveBeforePlatform) | |
{ | |
transform = _transform; | |
velocity = _velocity; | |
standingOnPlatform = _standingOnPlatform; | |
moveBeforePlatform = _moveBeforePlatform; | |
} | |
} | |
//Draw the little crosses so we can see, aka the waypoints | |
void OnDrawGizmos() | |
{ | |
if (localWaypoints != null) | |
{ | |
Gizmos.color = Color.red; | |
float size = .3f; | |
for (int i = 0; i < localWaypoints.Length; i++) | |
{ | |
Vector3 globalWaypointPos = (Application.isPlaying) ? globalWaypoints[i] : localWaypoints[i] + transform.position; | |
Gizmos.DrawLine(globalWaypointPos - Vector3.up * size, globalWaypointPos + Vector3.up * size); | |
Gizmos.DrawLine(globalWaypointPos - Vector3.left * size, globalWaypointPos + Vector3.left * size); | |
} | |
} | |
} | |
} |