Please help! I’m not sure what else to do… I’ve spent all day trying to make this work. I tried Cinemachine as well but the behaviour is identical.
I’m building a 2D platformer game, where the player jumps up towards platforms and then lands on them.
My platforms have a Box Collider 2D and my character has a Rigidbody2D with Gravity Scale set to 7 and a box collider 2D as well.
Everything is working well, including the jumping mechanic, but starts breaking when I try to implement a camera to follow the player movement.
Below is my simple code which I attach to the camera and then I drag the player game object to the Target field. When I press play, the object falls down to a Y position of -896, where it collides with a platform and the console logs “isGrounded: True”, however if I check the Main Camera position, the Y value keeps going infinitely beyond -896 and the Z axis keeps going up to very high positive numbers (e.g 200k) (this is a 2D game with no Z axis movement).
In scene view, the Canvas/Main Camera keep falling down. If I set the RigidBody2D gravity scale to zero the camera stops falling, but so does the player game object.
using UnityEngine;
public class CameraFollow : MonoBehaviour
{
public Transform target; // The object the camera will follow
public Vector3 offset = new Vector3(0, 0, -10); // Offset to keep the camera at a distance
public float smoothSpeed = 0.125f; // Speed of the camera's smooth movement
void LateUpdate()
{
if (target != null)
{
// Calculate desired position based on the target's position and the offset
Vector3 desiredPosition = target.position + offset;
// Smoothly move to the desired position
Vector3 smoothedPosition = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed);
// Apply the smoothed position
transform.position = smoothedPosition;
}
}
}
Pasting my playermovement script below as well in case this helps with the deep dive:
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float maxJumpForce = 100f;
public float joystickRadius = 20f; // Radius to detect click/touch area around the frog
public float dragThresholdX = 0.5f; // Threshold for determining left, right, or center drag
public Animator animator;
private Vector2 dragStartPosition;
private bool isDragging = false;
private Rigidbody2D rb;
// Ground check variables
public LayerMask groundLayer;
public Transform groundCheck;
public float groundCheckRadius = 0.1f;
private bool isGrounded;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
// Detect touch/click near the frog
if (Input.GetMouseButtonDown(0))
{
Vector2 touchPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
touchPosition = new Vector2(touchPosition.x, touchPosition.y); // Ignore Z-axis
Vector2 frogPosition = new Vector2(transform.position.x, transform.position.y); // Ignore Z-axis
float distance = Vector2.Distance(touchPosition, frogPosition);
Debug.Log("Touch position: " + touchPosition + ", Frog position: " + frogPosition);
Debug.Log("Distance: " + distance + ", Joystick radius: " + joystickRadius);
if (distance <= joystickRadius)
{
isDragging = true;
dragStartPosition = touchPosition;
animator.SetBool("isDragging", true);
Debug.Log("Drag started at: " + dragStartPosition);
}
else
{
Debug.Log("Touch is outside of joystick radius");
}
}
// Handle dragging and set animations (stay in Update for responsiveness)
if (Input.GetMouseButton(0) && isDragging)
{
Vector2 currentDragPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
currentDragPosition = new Vector2(currentDragPosition.x, currentDragPosition.y); // Ignore Z-axis
// Log the current drag position whenever it changes
Debug.Log("Current Drag Position: " + currentDragPosition);
Vector2 dragVector = currentDragPosition - dragStartPosition;
// Drag direction based on X-offset
if (Mathf.Abs(dragVector.x) < dragThresholdX) // Drag near center
{
animator.SetFloat("dragDirection", 0); // Center drag animation
}
else if (dragVector.x < -dragThresholdX) // Drag left
{
animator.SetFloat("dragDirection", -1); // Drag left animation for jump up-left
}
else if (dragVector.x > dragThresholdX) // Drag right
{
animator.SetFloat("dragDirection", 1); // Drag right animation for jump up-right
}
}
// Release and jump (this remains in Update to handle input)
if (Input.GetMouseButtonUp(0) && isDragging && isGrounded)
{
Vector2 releasePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
releasePosition = new Vector2(releasePosition.x, releasePosition.y); // Ignore Z-axis
// Calculate drag vector from release position and initial drag start position
Vector2 dragVector = releasePosition - dragStartPosition;
Debug.Log("Release Position: " + releasePosition);
Debug.Log("Drag Vector: " + dragVector);
// Calculate jump force based on drag distance
float jumpForce = Mathf.Clamp(dragVector.magnitude, 0, maxJumpForce);
// Apply multiplier to add more power to the jump (e.g., 1.5x the calculated force)
jumpForce *= 5.0f; // This multiplier increases the jump force
// Log the jump force
Debug.Log("Jump Force: " + jumpForce);
// Check if jump force is valid
if (jumpForce > 0)
{
// Log jump direction and force
Vector2 jumpDirection = -dragVector.normalized;
Debug.Log("Jump direction: " + jumpDirection + ", Jump force: " + jumpForce);
// Apply jump force
rb.AddForce(jumpDirection * jumpForce, ForceMode2D.Impulse);
// Update jump direction animations
if (jumpDirection.x > 0) // Jump up-right
{
animator.SetFloat("jumpDirection", 1);
}
else if (jumpDirection.x < 0) // Jump up-left
{
animator.SetFloat("jumpDirection", -1);
}
else // Jump straight up
{
animator.SetFloat("jumpDirection", 0);
}
// Reset drag state and animations
isDragging = false;
animator.SetBool("isDragging", false);
}
else
{
// If the drag vector is too small, log a message
Debug.Log("Jump force too low or invalid.");
}
}
}
void FixedUpdate()
{
// Ground check in FixedUpdate
isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer);
// Update grounded animation state only when it changes
if (isGrounded != animator.GetBool("isGrounded"))
{
Debug.Log("Grounded state changed: " + isGrounded);
animator.SetBool("isGrounded", isGrounded);
}
// Optionally: Handle horizontal movement here (if needed for further adjustments)
// Example: rb.velocity = new Vector2(horizontalVelocity, rb.velocity.y);
}
void OnDrawGizmos()
{
// Visualize ground check radius
if (groundCheck != null)
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(groundCheck.position, groundCheckRadius);
}
}
}