I am trying to create camera behavior where camera moving slightly forward the player along his movement direction to extend the visible area.
For camera movement, I use an empty object which moves as the player object by Input.GetAxis()
and clamps in some borders around the player for the later to stay in camera area.
But I don't want to simply snap camera to the target object. I want the camera to smoothly lerp forward in player's movement direction and if there is no movement anymore - smoothly lerp back to the player object.
Problem is - I can't detect presence or absence of movement of the empty target object. I thought of using this method https://answers.unity.com/questions/907078/how-to-detect-movement.html if(Mathf.Abs(rigidbody2D.velocity.y) < 0.001)
It didn't work at first because I moved my target point with transform.Translate(). When I tried rigidbody2D.Addforce()
and it didn't work neither. I noticed that applied force actualy isn't reducing per time it stays the same. Then I tried rigidbody2D.MovePosition()
and it also isn't working also velocity on every axis stays 0 and clamp isn't working with this method. Here is the code:
public class TargetPointBehaviour : MonoBehaviour{
[Tooltip("Used as origin point for camera movement.")]
[SerializeField]
private GameObject playerObject; //Used as origin point for camera movement
private Transform playerTransform; //players transform
private Vector2 playerPosition; // x, y player position
private Rigidbody2D targetPointRB2D; //rigidbody2D of target point object
//========================================================================================================
[Tooltip("Value to offset the camera from the player")]
[SerializeField]
private float offsetFromThePlayer; //value to determine how far target to interpolation will be
void Start()
{
playerTransform = playerObject.GetComponent<Transform>();
targetPointRB2D = GetComponent<Rigidbody2D>(); // assigning RigidBody2D component to variable
}
void FixedUpdate()
{
MoveTargetPoint();
ClampMovement();
MoveTargetPointToPlayerPosition();
}
private void MoveTargetPoint() // moves targetPoint object by player controls
{
GetComponent<Rigidbody2D>().MovePosition((new Vector2(Input.GetAxis("Horizontal") * 100,
Input.GetAxis("Vertical") * 100))); // moves object by player controls
}
private void ClampMovement() //moves target point in defined borders GetComponent<Rigidbody2D>().AddForce
{
transform.position = new Vector2(Mathf.Clamp(transform.position.x, playerTransform.position.x - offsetFromThePlayer, playerTransform.position.x + offsetFromThePlayer),
Mathf.Clamp(transform.position.y, playerTransform.position.y - offsetFromThePlayer,
playerTransform.position.y + offsetFromThePlayer)); //constraints movement by offsetFromThePlayer value
}
//checks if movement of targetPoint stops and when returns it to player object coordinates
private void MoveTargetPointToPlayerPosition()
{
Debug.Log("Velocity Y: " + targetPointRB2D.velocity.y + ". Velocity X: " + targetPointRB2D.velocity.x);
if (Mathf.Abs(targetPointRB2D.velocity.y) < 0.01f && Mathf.Abs(targetPointRB2D.velocity.x) < 0.01f)
{
StartCoroutine(DelayBeforereturningToPlayerObject());
transform.Translate(playerTransform.position.x, playerTransform.position.y, 0);
}
}
private IEnumerator DelayBeforereturningToPlayerObject() //delay for some time befor target returns to player object
{
yield return new WaitForSeconds(0.1f);
}}
I didn't implemented actual camera movement yet cause don't see the point while the target for the camera isn't working. But maybe there is a more efficient way to implement what I want?