Hello, Im making a simple platformer game and using cinemachine to follow the player. However, the camera jitters a lot if I use it while turning on damping.
here is the scripts and the “NewPlayer” script is on the player.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class NewPlayer : PhysicsObject
{
[Header("Attributes")]
[SerializeField] private float jumpPower = 10;
[SerializeField] private float maxSpeed = 1;
[Header("Inventory")]
public int coinsCollected;
private int maxHealth = 100;
public int health = 100;
[Header("References")]
private Vector2 healthBarOrigSize;
public Dictionary<string, Sprite> inventory = new Dictionary<string, Sprite>(); //Dictionary storing all inventory item strings and values
public Sprite inventoryItemBlank; //The default inventory item slot sprite
//Singleton instantation
private static NewPlayer instance;
public static NewPlayer Instance
{
get
{
if (instance == null) instance = GameObject.FindObjectOfType<NewPlayer>();
return instance;
}
}
private void Awake()
{
if (GameObject.Find("New Player")) Destroy(gameObject);
}
// Start is called before the first frame update
void Start()
{
DontDestroyOnLoad(gameObject);
gameObject.name = "New Player";
UpdateUI();
SetSpawnPosition();
}
// Update is called once per frame
void Update()
{
targetVelocity = new Vector2(Input.GetAxis("Horizontal") * maxSpeed, 0);
//If the player presses "Jump" and we're grounded, set the velocity to a jump power value
if (Input.GetButtonDown("Jump") && grounded)
{
velocity.y = jumpPower;
}
//Check if player health is smaller than or equal to 0.
if (health <= 0)
{
Die();
}
}
//Update UI elements
public void UpdateUI()
{
//If the healthBarOrigSize has not been set yet, match it to the healthBar rectTransform size!
if (healthBarOrigSize == Vector2.zero) healthBarOrigSize = GameManager.Instance.healthBar.rectTransform.sizeDelta;
GameManager.Instance.coinsText.text = coinsCollected.ToString();
GameManager.Instance.healthBar.rectTransform.sizeDelta = new Vector2(healthBarOrigSize.x * ((float)health / (float)maxHealth), GameManager.Instance.healthBar.rectTransform.sizeDelta.y);
}
public void SetSpawnPosition()
{
transform.position = GameObject.Find("Spawnlocation").transform.position;
}
public void Die()
{
SceneManager.LoadScene("Level1");
}
public void AddInventoryItem(string inventoryName, Sprite image = null)
{
inventory.Add(inventoryName, image);
//The blank sprite should now swap with key sprite
GameManager.Instance.inventoryItemImage.sprite = inventory[inventoryName];
}
public void RemoveInventoryItem(string inventoryName)
{
inventory.Remove(inventoryName);
//The blank sprite should now swap with key sprite
GameManager.Instance.inventoryItemImage.sprite = inventoryItemBlank;
}
}
This is the new player script and below is the physics object script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PhysicsObject : MonoBehaviour
{
[Header("Physics Object Attributes")]
public float minGroundNormalY = .65f;
public float gravityModifier = 1f;
protected Vector2 targetVelocity;
protected bool grounded;
protected Vector2 groundNormal;
protected Rigidbody2D rb2d;
protected Vector2 velocity;
protected ContactFilter2D contactFilter;
protected RaycastHit2D[] hitBuffer = new RaycastHit2D[16];
protected List<RaycastHit2D> hitBufferList = new List<RaycastHit2D>(16);
protected const float minMoveDistance = 0.001f;
protected const float shellRadius = 0.01f;
void OnEnable()
{
rb2d = GetComponent<Rigidbody2D>();
}
void Start()
{
contactFilter.useTriggers = false;
contactFilter.SetLayerMask(Physics2D.GetLayerCollisionMask(gameObject.layer));
contactFilter.useLayerMask = true;
}
void Update()
{
targetVelocity = Vector2.zero;
ComputeVelocity();
}
protected virtual void ComputeVelocity()
{
}
void FixedUpdate()
{
velocity += gravityModifier * Physics2D.gravity * Time.deltaTime;
velocity.x = targetVelocity.x;
grounded = false;
Vector2 deltaPosition = velocity * Time.deltaTime;
Vector2 moveAlongGround = new Vector2(groundNormal.y, -groundNormal.x);
Vector2 move = moveAlongGround * deltaPosition.x;
Movement(move, false);
move = Vector2.up * deltaPosition.y;
Movement(move, true);
}
void Movement(Vector2 move, bool yMovement)
{
float distance = move.magnitude;
if (distance > minMoveDistance)
{
int count = rb2d.Cast(move, contactFilter, hitBuffer, distance + shellRadius);
hitBufferList.Clear();
for (int i = 0; i < count; i++)
{
PlatformEffector2D platform = hitBuffer[i].collider.GetComponent<PlatformEffector2D>();
if (!platform || (hitBuffer[i].normal == Vector2.up && velocity.y < 0 && yMovement))
{
hitBufferList.Add(hitBuffer[i]);
}
}
for (int i = 0; i < hitBufferList.Count; i++)
{
Vector2 currentNormal = hitBufferList[i].normal;
if (currentNormal.y > minGroundNormalY)
{
grounded = true;
if (yMovement)
{
groundNormal = currentNormal;
currentNormal.x = 0;
}
}
float projection = Vector2.Dot(velocity, currentNormal);
if (projection < 0)
{
velocity = velocity - projection * currentNormal;
}
float modifiedDistance = hitBufferList[i].distance - shellRadius;
distance = modifiedDistance < distance ? modifiedDistance : distance;
}
}
rb2d.position = rb2d.position + move.normalized * distance;
}
}
And here is the cinemachine script
using Cinemachine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SceneCamera : MonoBehaviour
{
[SerializeField] private CinemachineVirtualCamera cinemachineVirtualCamera;
// Start is called before the first frame update
void Start()
{
cinemachineVirtualCamera.Follow = NewPlayer.Instance.transform;
}
// Update is called once per frame
void Update()
{
}
}