Skip to content
Permalink
07bb02fdb8
Switch branches/tags

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?
Go to file
 
 
Cannot retrieve contributors at this time
242 lines (203 sloc) 8.42 KB
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);
}
}
}
}