Question by
$$anonymous$$ · Aug 19, 2017 at 06:08 PM ·
unity 5cameracamera-movement
Switching player controllers
So I am trying to make a game where there are two player objects, a red square, and a blue square, each with unique properties (like death on certain color floors, jump height, speed, etc.). I want the player to be able to hit Shift to switch between the characters. I already have a camera follow setup for one character.
Also, I am using raycast to detect collision, I heard it was smoother and more reliable, so I'm trying it out.
Player.cs
using System.Collections;
using UnityEngine;
[RequireComponent (typeof (Controller2D))]
public class Player : MonoBehaviour {
public float jumpHeight = 4;
public float timeToJumpApex = .4f;
public float accelerationTimeAirborne = .2f;
public float accelerationTimeGrounded = .1f;
float moveSpeed = 6;
float gravity = -20;
float jumpVelocity = 8;
Vector3 velocity;
float velocityXSmoothing;
Controller2D controller;
void Start()
{
controller = GetComponent<Controller2D>();
gravity = -(2 * jumpHeight) / Mathf.Pow(timeToJumpApex, 2);
jumpVelocity = Mathf.Abs(gravity) * timeToJumpApex;
print("Gravity: " + gravity + " Jump Velocty: " + jumpVelocity);
}
void Update()
{
if (controller.collisions.above || controller.collisions.below)
{
velocity.y = 0;
}
Vector2 input = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
if (Input.GetKeyDown(KeyCode.Space) && controller.collisions.below)
{
velocity.y = jumpVelocity;
}
float targetVelocityX = input.x * moveSpeed; ;
velocity.x = Mathf.SmoothDamp(velocity.x, targetVelocityX, ref velocityXSmoothing, (controller.collisions.below) ? accelerationTimeGrounded : accelerationTimeAirborne);
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
}
}
Controller2D.cs
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(BoxCollider2D))]
public class Controller2D : MonoBehaviour
{
public LayerMask collisionMask;
const float skinwidth = .015f;
public int horizontalRayCount = 4;
public int verticalRayCount = 4;
float horizontalRaySpacing;
float verticalRaySpacing;
BoxCollider2D coll;
RaycastOrigins raycastOrigins;
public CollisionInfo collisions;
void Start()
{
coll = GetComponent<BoxCollider2D>();
calculateRaySpacing();
}
public void Move(Vector3 velocity)
{
UpdateRaycastOrigins();
collisions.Reset();
if (velocity.x != 0)
{
HorizontalCollisions(ref velocity);
}
if (velocity.y != 0)
{
VerticalCollisions(ref velocity);
}
transform.Translate(velocity);
}
void HorizontalCollisions(ref Vector3 velocity)
{
float directionX = Mathf.Sign(velocity.x);
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, collisionMask);
Debug.DrawRay(rayOrigin, Vector2.right * directionX * rayLength, Color.red);
if (hit)
{
velocity.x = (hit.distance - skinwidth) * directionX;
rayLength = hit.distance;
collisions.left = directionX == -1;
collisions.right = directionX == 1;
}
}
}
void VerticalCollisions(ref Vector3 velocity)
{
float directionY = Mathf.Sign(velocity.y);
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 + velocity.x);
RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.up * directionY, rayLength, collisionMask);
Debug.DrawRay(rayOrigin, Vector2.up * directionY * rayLength, Color.red);
if (hit)
{
velocity.y = (hit.distance - skinwidth) * directionY;
rayLength = hit.distance;
collisions.below = directionY == -1;
collisions.above = directionY == 1;
}
}
}
void UpdateRaycastOrigins()
{
Bounds bounds = coll.bounds;
bounds.Expand(skinwidth * -2);
raycastOrigins.bottomLeft = new Vector2(bounds.min.x, bounds.min.y);
raycastOrigins.bottomRight = new Vector2(bounds.max.x, bounds.min.y);
raycastOrigins.topLeft = new Vector2(bounds.min.x, bounds.max.y);
raycastOrigins.topRight = new Vector2(bounds.max.x, bounds.max.y);
}
void calculateRaySpacing()
{
Bounds bounds = coll.bounds;
bounds.Expand(skinwidth * -2);
horizontalRayCount = Mathf.Clamp(horizontalRayCount, 2, int.MaxValue);
verticalRayCount = Mathf.Clamp(verticalRayCount, 2, int.MaxValue);
horizontalRaySpacing = bounds.size.y / (horizontalRayCount - 1);
verticalRaySpacing = bounds.size.x / (verticalRayCount - 1);
}
struct RaycastOrigins
{
public Vector2 topLeft, topRight;
public Vector2 bottomLeft, bottomRight;
}
public struct CollisionInfo
{
public bool above, below;
public bool left, right;
public void Reset ()
{
above = below = false;
left = right = false;
}
}
}
CameraFollow.cs
using UnityEngine;
public class CameraFollow : MonoBehaviour {
public Transform target;
public float smoothSpeed = 0.125f;
public Vector3 offset;
void LateUpdate()
{
Vector3 desiredPosition = target.position + offset;
Vector3 smoothedPosition = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed * Time.deltaTime);
transform.position = smoothedPosition;
}
}
Comment