Skip to content

Instantly share code, notes, and snippets.

@hasantarhan
Created December 29, 2024 12:08
Show Gist options
  • Save hasantarhan/74e9cc071064de756720325cd45b6e98 to your computer and use it in GitHub Desktop.
Save hasantarhan/74e9cc071064de756720325cd45b6e98 to your computer and use it in GitHub Desktop.
Card Rigidbody for Unity UI
using UnityEngine;
public class CardRigidbody : MonoBehaviour
{
public float rotationAmount = 10f;
public float maxRotationAngle = 360f;
public float springStiffness = 100f;
public float springDamping = 10f;
public float mass = 3f;
public float forceMultiplier = 10f;
private Vector3 movementDelta;
private Vector2 currentRotation;
private Vector2 rotationVelocity;
private Vector3 appliedForce;
private Vector3 forcePoint;
private Vector3 lastPosition;
private void Update()
{
CalculatePhysics();
}
private void CalculatePhysics()
{
Vector3 movement = CalculateMotion();
movementDelta = Vector3.Lerp(movementDelta, movement, 25f * Time.unscaledDeltaTime);
Vector2 force = CalculateSpringForce() + CalculateMovementForce(movement) + CalculateAppliedForce();
Vector2 acceleration = force / mass;
UpdateRotation(acceleration);
ApplyRotation();
}
private Vector2 CalculateSpringForce()
{
return new Vector2(
-springStiffness * currentRotation.x - springDamping * rotationVelocity.x,
-springStiffness * currentRotation.y - springDamping * rotationVelocity.y
);
}
private Vector2 CalculateMovementForce(Vector3 movement)
{
return new Vector2(movement.x * rotationAmount, movement.y * rotationAmount);
}
private Vector2 CalculateAppliedForce()
{
if (appliedForce == Vector3.zero)
{
return Vector2.zero;
}
Vector3 torque = Vector3.Cross(forcePoint - transform.position, appliedForce);
Vector2 result = new Vector2(torque.x, -torque.z) * forceMultiplier;
appliedForce = Vector3.zero;
return result;
}
private void UpdateRotation(Vector2 acceleration)
{
rotationVelocity += acceleration * Time.unscaledDeltaTime;
currentRotation += rotationVelocity * Time.unscaledDeltaTime;
currentRotation = Vector2.ClampMagnitude(currentRotation, maxRotationAngle);
}
private void ApplyRotation()
{
transform.rotation = Quaternion.Euler(currentRotation.y, 0f, -currentRotation.x);
}
private Vector3 CalculateMotion()
{
Vector3 motion = (transform.position - lastPosition) / Time.unscaledDeltaTime;
lastPosition = transform.position;
return motion;
}
public void ApplyForce(Vector3 point, Vector3 force)
{
appliedForce = force;
forcePoint = point;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment