Help w/ Simple Object Control.

I need to control an object’s transform based on where I touch the screen.

So below, if I swiped from left edge to right edge, it would move from -65x to 65x. Hoping to freely move in xy.

I believe this can be accomplished with ScreenToWorldPoint or ViewportToWorldPoint.

Any help understanding is greatly appreciated!

What exactly have you tried so far? Be sure to see post #3 for code formatting guidelines.

Also, make sure you understand the behavior you want: does the object move AS you swipe? does it wait until the swipe is done? Does it snap upon motion? Does it move towards the goal point? At what speed? What if the user swipes another direction midway through? All of these things need to be clearly defined before you can make this work.

Thanks for the reply Kurt! To be more specific, I am trying to make a camera pan like it does in the game below. From one side to the other as you swipe. The player also follows the touch input.

I will read post 3, then post some code w/ problems I’ve encountered with other approaches. Thanks

The above example pans a camera based on where a touch is on screen.

However, the following code is a different camera pan approach that didn’t work correctly. It pans a camera based on player position on screen. (gradually faster as player gets closer to screen edge). Feels great, but the player lags behind the camera pan.

So my above question is actually to try an alternative approach, but here is the current code, for what it’s worth.

Player follow mouse script:

using UnityEngine;
using System.Collections;

public class FollowMouse : MonoBehaviour {
 
    public float distance = 2.0f;

 
    // Use this for initialization

    void Start()
    {

    }

    // Update is called once per frame
    void FixedUpdate()
    {
        Vector3 mousePosition = Input.mousePosition;
        mousePosition.z = distance;
        transform.position = Camera.main.ScreenToWorldPoint(mousePosition);

        transform.position = new Vector3
            (
                Mathf.Clamp (transform.position.x, -65f, 65f),
                Mathf.Clamp (transform.position.y, 0.05f, 100f),
                Mathf.Clamp (transform.position.z, -123f, -123f)
            );

    }

}

Camera Pan Script:

using UnityEngine;
using System.Collections;


public class CameraPan4 : MonoBehaviour {

        public Transform target;
        Camera camera;

        // Use this for initialization
        void Start()
        {
            camera = GetComponent<Camera>();
        }
 
 
 
        const int MOUSE_MOVEMENT_DISTANCE_FROM_SCREEN_EDGE = 800; // Bigger number means screen will start moving faster
        const int MOUSE_MOVEMENT_MAX_SCROLL_SPEED = 150;//Increase this to increase max speed overall
        const int BASE_SCROLLSPEED_FACTOR = 50; //Increase this to increase the rate of speed gain - 5-10 is a good range
     
        void LateUpdate ()
         
        {
            Vector3 playerPos = camera.WorldToScreenPoint(target.position);
            float mousePosX = playerPos.x;
            float mousePosY = playerPos.y;
            int boundaryTrigger = MOUSE_MOVEMENT_DISTANCE_FROM_SCREEN_EDGE;
            int scrollSpeed = MOUSE_MOVEMENT_MAX_SCROLL_SPEED;
         
            if(mousePosX < boundaryTrigger)
            {
                scrollSpeed = (int)((BASE_SCROLLSPEED_FACTOR/mousePosX) * MOUSE_MOVEMENT_MAX_SCROLL_SPEED);
                if ((scrollSpeed > MOUSE_MOVEMENT_MAX_SCROLL_SPEED)||(scrollSpeed < 1)) {
                    scrollSpeed = MOUSE_MOVEMENT_MAX_SCROLL_SPEED;
                }
             
                transform.Translate(Vector3.right* - scrollSpeed * Time.deltaTime);
            }
         
            if(mousePosX >= Screen.width- boundaryTrigger)
            {
                scrollSpeed = (int)((BASE_SCROLLSPEED_FACTOR/(Screen.width - mousePosX)) * MOUSE_MOVEMENT_MAX_SCROLL_SPEED);
                if ((scrollSpeed > MOUSE_MOVEMENT_MAX_SCROLL_SPEED)||(scrollSpeed < 1)) {
                    scrollSpeed = MOUSE_MOVEMENT_MAX_SCROLL_SPEED;
                }
             
                transform.Translate (Vector3.right * scrollSpeed * Time.deltaTime);
            }
         
            if(mousePosY < boundaryTrigger)
            {
                scrollSpeed = (int)((BASE_SCROLLSPEED_FACTOR/mousePosY) * MOUSE_MOVEMENT_MAX_SCROLL_SPEED);
                if ((scrollSpeed > MOUSE_MOVEMENT_MAX_SCROLL_SPEED)||(scrollSpeed < 1)) {
                    scrollSpeed = MOUSE_MOVEMENT_MAX_SCROLL_SPEED;
                }
             
                transform.Translate (Vector3.down * scrollSpeed *Time.deltaTime);
            }
         
            if(mousePosY >= Screen.height - boundaryTrigger)
            {
                scrollSpeed = (int)((BASE_SCROLLSPEED_FACTOR/(Screen.height - mousePosY)) * MOUSE_MOVEMENT_MAX_SCROLL_SPEED);
                if ((scrollSpeed > MOUSE_MOVEMENT_MAX_SCROLL_SPEED)||(scrollSpeed < 1)) {
                    scrollSpeed = MOUSE_MOVEMENT_MAX_SCROLL_SPEED;
                }
             
                transform.Translate (Vector3.up *scrollSpeed * Time.deltaTime); 
            }

            transform.position = new Vector3
                (
                    Mathf.Clamp (transform.position.x, -40f, 40f),
                    Mathf.Clamp (transform.position.y, 0.45f, 20f),
                    Mathf.Clamp (transform.position.z, -125f, -125f)
                );
         
    }


}

Excellent! You have defined your problem much more clearly now.

My favorite method for this sort of cam follow is to use (or technially mis-use) the Vector3.Lerp() function.

I do this like so, generally speaking:

Camera theCamera;    // set this!
Vector3 lookAccumulator;
Transform playerTransform;
const float snappiness = 10.0f;    // a good starting value

// put this line in your Start() func somewhere...
lookAccumulator = playerTransform.position;

void LateUpdate()
{
    lookAccumulator = Vector3.Lerp( lookAccumulator,
        playerTransform.position, Time.deltaTime * snappiness);
    theCamera.transform.LookAt( lookAccumulator);
}

Then you can tweak your snappiness variable to customize how snappily it follows the player.

1 Like

@Kurt-Dekker This unfortunately won’t work for this particular situation, but just want to say thanks! :sunglasses: I definitely learned from how you structured that. However, in this case, the camera must pan in xy.

Here is what I’m attempting to accomplish:

  • A camera that pans in xy, following the player, within clamp limits.
  • A player that flies around in xy, staying under the touch input or mouse hover.
  • No arguments between 1 & 2, such as jumpy player lag or misalignment.

If I turn camera pan off, I currently have a player that stays under mouse/touch input. As of today, also rigidbody velocity (no teleport). Works like a charm.

If I turn camera pan on (the script I posted above), the camera pan accelerates as the player reaches the edge. It has a sense of flying, but the player lags behind in a jumpy way.

So my theory is I could just map specific xy transforms.positions of the camera & player to touch points on the screen. Like that sketch above. To have the player fly around with camera pan, but no jumpy lag.

It would take some tweaking to get everything aligned.

I think that’s how Gemini Strike does it though :slight_smile:

SOLVED Player lag!

Ready for this noob mistake?

At some point, for some reason, I removed the player as a child object of the camera…:sweat_smile:

To be fair, this is my first Unity project without a tutorial, and the camera script was following the player.

Now the point at which shots are fired from the player is lagging behind, but this is a huge step in the right direction. Flying around feels awesome!

Thanks for taking the time to assist. Now to get these shots firing from the right place…

The launcher is an empty game object, that is a child of the player, which is (now) a child of the camera. The player is being tracked correctly, but not the launcher. Probably need to add it to that camera script.