Why does limiting my gameobjects movement to camera frame prevent movement?

Viewed 52

I am trying to limit my game object's movement to just the camera view. I am was able to move my parent game object with:

Vector3 movement = new Vector3(inputX, inputY, 0);
movement *= (Time.deltaTime * speed * smoothTime);
gameObject.GetComponent<Rigidbody>().MovePosition(transform.position + movement);

However, my player game object appears to stop moving after adding the code below it:

Vector3 pos = Camera.main.WorldToViewportPoint(transform.position);
pos.x = Mathf.Clamp01(pos.x);
pos.y = Mathf.Clamp01(pos.y);
transform.position = Camera.main.ViewportToWorldPoint(pos);        

I tried modifying the code to combine the statements but I am confused about the logic which led to my game object jittering on the camera position:

movement = Camera.main.WorldToViewportPoint(new Vector3(inputX, inputY, transform.position.z));
movement.x = Mathf.Clamp01(movement.x);
movement.y = Mathf.Clamp01(movement.y);
movement *= (Time.deltaTime * speed * smoothTime);
transform.position = Camera.main.ViewportToWorldPoint(movement);
gameObject.GetComponent<Rigidbody>().MovePosition(transform.position + movement);

I was thinking that I need to restrict the movement directly and clamp my x and y positions. I don't know what I am missing.

1 Answers

The issue here is that when you are calling WorldToViewportPoint(), you should pass to it a world Position. However, you are passing a Vector3(inputX, inputY ...), and persumable inputX and inputY are not world coordinates.

Vector3 movement = new Vector3(inputX, inputY, 0);
movement *= (Time.deltaTime * speed * smoothTime);

// Calculate the 'to-be' final position
Vector3 position = transform.position + movement;

// Clamp that position
Vector3 screenCoordinates = Camera.main.WorldToViewportPoint(position);
screenCoordinates.x = Mathf.Clamp01(screenCoordinates.x);
screenCoordinates.y = Mathf.Clamp01(screenCoordinates.y);

position = Camera.main.ViewportToWorldPoint(screenCoordinates);

// then finally set it
gameObject.GetComponent<Rigidbody>().MovePosition(position);

Lastly, you probably want to cache your Camera.main and your GetComponent<Rigidbody> since these are expensive calls to do every frame.

Related