0
\$\begingroup\$

I've got a 3D mobile game with the player centered in the middle of the screen, and a camera looking down on top of the player. The player is controller by an on-screen joystick. Currently when the joystick is touched to move the player, the camera instantly moves along with the player. This is okay, but what I want to have happen is to allow the player to move in a small circular area freely without the camera moving. Once the player reaches the edge of the pre-defined area, I'd like the camera to start moving with the player again. If the player starts moving back towards the camera location (x,y) then I'd like the camera to stop moving and allow the player to roam freely again.

I've got this sort of working with the following code using LateUpdate, but as I move the player near the edge of the max distance from the camera the movements get jumpy.

public class CameraController {
    const float MAX_DISTANCE = 5f;

    void LateUpdate()
    {
        if (Joystick.IsTouched)
        {
            // This properly shows the distance the player is from the camera
            float distance = GetPlayerDistance();

            if (distance > MAX_DISTANCE) 
            {
                // Move camera the same way the player is being moved.                   
                // This works and moves the camera and player properly in sync.

                // This causes jerky and unsmooth movement when the distance 
                // is close (above/below/equal) to the max in subsequent frames.
            }
        }
        else if (transform.position.x != player.position.x || transform.position.y != player.position.y)
        {
            // Lerp the camera position back to be directly above the player 
            // when the joystick is let go and the camera and players' x or 
            // y position don't match. This works great.
        }
    }
}

I am having trouble figuring out how to get this working properly. I can't seem to come up with a way to determine when the player should be allowed to move freely after they have already hit the max distance from the camera. When it first starts, the player can move freely fine, and when letting go of the joystick, the camera animates back properly. The issue arises once the max distance is hit.

I've also tried parenting the player to the camera to have them move in sync when the threshold is hit, but I am unable to determine when to un-parent them because the ship can't move freely to get closer to the camera. Any thoughts on this approach? It works perfect except I can't figure out when to un-parent the two game objects.

Thanks in advance for any help/thoughts!

\$\endgroup\$
  • \$\begingroup\$ Unparent when the player stops moving, re parent when player moves again. Or just Lerp the camera to player when (distance > MAX_DISTANCE) should stop jerkiness \$\endgroup\$ – Reuben Crimp Aug 28 '17 at 14:15
  • \$\begingroup\$ Okay, so for the parenting I believe I have tried exactly that and it does work well. My only issue at that point is I can't figure out when to unparent because the player is always at or above the max distance from the camera once I parent it haha. \$\endgroup\$ – DRiFTy Aug 28 '17 at 14:16
  • \$\begingroup\$ Thanks, I'll also try to Lerp the camera instead of setting the values to see if that helps the jerkiness in the code above. \$\endgroup\$ – DRiFTy Aug 28 '17 at 14:18
  • \$\begingroup\$ like when the player release they key, unparent immediately. "The player is always at or above the max distance" What if the camera behaviour was such that it made sure that the player is just below the max distance, so when they stopped moving they'd already be legal. And the distance wouldn't fluctuate between too far, and too close. Because it's maintaining the right distance. Like (MAX_DISTANCE - PlayerMaxSpeed)... \$\endgroup\$ – Reuben Crimp Aug 28 '17 at 14:47
  • \$\begingroup\$ Hmm I see what you're saying, but because this is using an onscreen virtual joystick they can change direction without releasing... So say they are moving the player forward and the camera latches on to the movement after max distance, then they start moving the player backwards, the camera will stay attached to the movement even though they are trying to move back towards the original position because the max distance threshold is still satisfied. I'm unsure how/when to figure out if the camera should un-latch at this point. Let me know if I'm not making sense or misunderstanding you. \$\endgroup\$ – DRiFTy Aug 28 '17 at 14:53
1
\$\begingroup\$

I don't know if it's really what you are looking for, but try this script I've made :

using UnityEngine;
using System.Collections;

public class CameraController : MonoBehaviour {
    const float MAX_DISTANCE = 5f;

    public Transform target; // Specify the player
    public float speed = 1 ;
    private Vector3 destination;
    private Vector3 projection;

    void Start () {
        destination = transform.position;
        projection = target.position;
    }

    void LateUpdate () {
        if ((target.position - projection).magnitude > MAX_DISTANCE )
        {
            projection = Vector3.MoveTowards(projection, target.position, Time.deltaTime * speed);
            destination = projection;
            destination.y = transform.position.y;
            transform.position = destination;
        }
    }
}

Here, I've supposed the camera is looking straight down, and the player moves on the XZ plane only.

The script makes the camera follow the player when the latter is outside a circle of MAX_DISTANCE radius. The center of the circle is the center of the screen. While the player stays inside this circle, the camera does not move.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.