I am learning about unit and trying to figure out how to use the fixed update correctly. I saw that in the platformer kit 2D they used collision detection and movement in fixed update. Thanks in advance.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CustomPhysics : RaycastOrigins
{
protected Vector2 velocity;
private Rigidbody2D rb2d;
private ContactFilter2D contactFilter2D;
private RaycastHit2D[] hitBuffer = new RaycastHit2D[16];
private List<RaycastHit2D> hitList = new List<RaycastHit2D>();
private float shellRadius = 0.015f;
private float minGroundNormalY = 0.0f;
private float minMoveDistance = 0.001f;
bool grounded = false;
private Vector2 groundNormal;
private float gravityModifier = 1f;
protected Animator animator;
protected Vector2 targetVelocity;
private Vector2 currentPosition;
private Vector2 nextPosition;
public Collisions collisons2D;
public float maxClimbingAngle = 60;
public LayerMask groundMask=0;
int facingRight;
private void OnEnable()
{
}
public override void Awake()
{
base.Awake();
rb2d = GetComponent<Rigidbody2D>();
animator = GetComponent<Animator>();
}
// Start is called before the first frame update
public override void Start()
{
base.Start();
contactFilter2D.useTriggers = false;
contactFilter2D.SetLayerMask(Physics2D.GetLayerCollisionMask(gameObject.layer));
contactFilter2D.useLayerMask = true;
Debug.Log("verticalSpacing:" + verticalRaycastSpacing);
}
// Update is called once per frame
void Update()
{
}
private void FixedUpdate()
{
//if (groundNormal.x == 0)
//{
// groundNormal = Vector2.up;
//}
CalculateOrigins();
collisons2D.Reset();
//collisons2D.slopeAngleOld = collisons2D.slopeAngle;
//collisons2D.slopeAngle = 0;
grounded = false;
currentPosition = rb2d.position;
HorizontalCollisions(ref velocity);
VerticalCollisions(ref velocity);
Debug.Log("VELOCITY:"+velocity.y);
Debug.Log("SLOPEANGLE:" + collisons2D.slopeAngle);
nextPosition = currentPosition + velocity;
rb2d.MovePosition(nextPosition);
velocity = Vector2.zero;
Debug.Log("Collisions UP|DOWN:" + collisons2D.up + "|" + collisons2D.down);
Debug.Log("Collisions LEFT|RIGHT:" + collisons2D.left + "|" + collisons2D.right);
Debug.Log("CLIMBINGSLOPE:" + collisons2D.climbingSlope);
//Debug.Log("FacingRight:" + facingRight);
//Debug.Log("velocityY "+ velocity.y);
//animator.SetFloat("velocityX", velocity.x);
animator.SetBool("grounded", grounded);
//Debug.DrawRay(rb2d.position, new Vector2(0, 0.1f) * 10, Color.blue);
//Debug.DrawRay(rb2d.position, moveAlongGround, Color.green);
}
public void Move(Vector2 move)
{
velocity += move;
}
private void HorizontalCollisions(ref Vector2 velocity)
{
float distance = Mathf.Abs(velocity.x) + skinWidth;
float directionX = Mathf.Sign(velocity.x);
for (int i = 0; i < horizontalRaycastsCount; i++)
{
Vector2 rayOrigin = directionX == -1 ? origins.bottomLeft : origins.bottomRight;
rayOrigin += Vector2.up * (i * horizontalRaycastSpacing);
Debug.DrawRay(rayOrigin, Vector2.right * directionX * distance, Color.red);
RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.right * directionX, distance, groundMask);
if (hit)
{
Debug.Log("HIT I=" + i);
float slopeAngle = Vector2.Angle(hit.normal, Vector2.up);
if (i == 0 && slopeAngle <= maxClimbingAngle)
{
Debug.DrawRay(hit.point, hit.normal.normalized*hit.distance);
//velocity.x -= (hit.distance - skinWidth) * directionX;
float tmp = 0;
if (slopeAngle != collisons2D.slopeAngleOld)
{
Debug.Log("before velocity:" + velocity.x);
//tmp = velocity.x;
Debug.Log("distanceToSlopeStart:" + tmp);
//velocity.x = (hit.distance-skinWidth) * directionX;
//Debug.DrawRay(rb2d.position, velocity, Color.green);
//transform.Translate(new Vector2(directionX * tmp, 0));
//Debug.Log("after velocity:" + velocity.x);
//Debug.Log("HITPOINTX" + hit.point.x);
//Debug.Break();
//slopeAngle -= 5;
}
ClimbingSlope(ref velocity, slopeAngle);
//velocity.x += (hit.distance - skinWidth) * directionX;
//velocity.x +=tmp;
Debug.Log("VELOCITYX I=0:" + velocity.x);
}
Debug.Log("SLOPEANGLE I=" + i + ":" + slopeAngle);
if (!collisons2D.climbingSlope || slopeAngle > maxClimbingAngle)
{
velocity.x = (hit.distance - skinWidth) * directionX;
Debug.Log("VELOCITYX:" + velocity.x);
distance = hit.distance;
if (collisons2D.climbingSlope)
{
velocity.y = Mathf.Tan(collisons2D.slopeAngle * Mathf.Deg2Rad) * Mathf.Abs(velocity.x);
}
collisons2D.left = directionX == -1;
collisons2D.right = directionX == 1;
}
}
}
Debug.DrawRay(rb2d.position, velocity, Color.blue);
}
private void VerticalCollisions(ref Vector2 velocity)
{
float distance = Mathf.Abs(velocity.y)+skinWidth;
float directionY = Mathf.Sign(velocity.y);
for (int i = 0; i < verticalRaycastsCount; i++)
{
Vector2 rayOrigin = directionY == -1 ? origins.bottomLeft : origins.topLeft;
rayOrigin += Vector2.right * (i * verticalRaycastSpacing);
Debug.DrawRay(rayOrigin , Vector2.up * directionY * distance, Color.red);
RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.up * directionY, distance, groundMask);
if (hit)
{
velocity.y = (hit.distance - skinWidth) * directionY;
distance = hit.distance;
if (collisons2D.climbingSlope)
{
velocity.x = velocity.y / Mathf.Tan(collisons2D.slopeAngle * Mathf.Deg2Rad) * Mathf.Sign(velocity.x);
}
collisons2D.down = directionY == -1;
collisons2D.up = directionY == 1;
}
}
if (collisons2D.climbingSlope)
{
float directionX = Mathf.Sign(velocity.x);
Vector2 rayOrigin = directionX == -1 ? origins.bottomLeft : origins.bottomRight;
Debug.DrawRay(rayOrigin, Vector2.right * directionX * distance, Color.cyan);
RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.right * directionX, distance, groundMask);
if(hit)
{
float slopeAngle = Vector2.Angle(hit.normal, Vector2.up);
if (slopeAngle != collisons2D.slopeAngle)
{
//Debug.Break();
}
}
}
}
protected virtual void ComputeVelocity()
{
}
private void MoveHorizontal(ref Vector2 move)
{
}
private void MoveVertical(ref Vector2 move)
{
}
private void ClimbingSlope(ref Vector2 velocity,float slopeAngle)
{
float moveDistance = Mathf.Abs(velocity.x);
float climbingVelocityY = Mathf.Sin(slopeAngle * Mathf.Deg2Rad) * moveDistance;
if (velocity.y <= climbingVelocityY)
{
velocity.y = climbingVelocityY;
velocity.x = Mathf.Cos(slopeAngle * Mathf.Deg2Rad) * moveDistance * Mathf.Sign(velocity.x);
//Vector2 rayOrigin = Mathf.Sign(velocity.x) == -1 ? origins.bottomLeft : origins.bottomRight;
//RaycastHit2D hit = Physics2D.Raycast(rayOrigin,velocity,)
collisons2D.down = true;
collisons2D.climbingSlope = true;
collisons2D.slopeAngle = slopeAngle;
//velocity.x -= tmp * directionX;
}
Debug.Log("CLIMBINGVELOCITY VELOCITY:" + velocity);
//Debug.Break();
}
public struct Collisions
{
public bool left, right;
public bool up, down;
public float slopeAngle;
public bool climbingSlope;
public float slopeAngleOld;
public void Reset()
{
left = right = false;
up = down = false;
climbingSlope = false;
slopeAngleOld = slopeAngle;
slopeAngle = 0;
}
}
}