@Asseverate
You need to draw a raycast through the camera itself into the worldspace to accurately put the cursor on screen. You completely have to for 3D and I use it in my 2D games as well, it seems to work better when you don’t want to worry about screen resolution come build time. My example code is in 3D but for 2D you just don’t lock the y
axis.
Implementing this method also gives you the ability to restrict the movement of the cursor to a designated area using the layerMask
parameter. For making it follow your cursor you just use Vector3.MoveTowards
and feed it a movement speed like this:
Physics.Raycast(cameraMain.ScreenPointToRay(Input.mousePosition), out rayCasthit, maxDistanceToRaycast, groundLayer);
float movementSpeed = 30f;
float stepTowardsPointer = MovementSpeed * Time.deltaTime;
Vector3 newPosition = Vector3.MoveTowards(transform.position, rayCasthit.point, stepTowardsPointer);
transform.position = newPosition;
I’d also recommend going a step further and making sure your mouse is in an area it should be able to move to, and making sure if the target trails too far behind the cursor it catches up. Here’s an example from an async-multiplayer game where the second player used the mouse to control a reticle while the first player controlled the primary location of the screen.
[SerializeField]
LayerMask groundLayer;
[SerializeField]
Transform player1Transform;
[SerializeField]
float maxDistanceBetweenPlayers = 50f;
[SerializeField]
float maxCursorUpPercent = .66f;
[SerializeField]
float movementSpeed;
[SerializeField]
float followSpeedIncreaseRange = 20f;
private void Move()
{
RaycastHit rayCasthit;
float maxDistanceToRaycast = 500f;
//raycast from the cursor location on screen
bool isCollidingWithGround = Physics.Raycast(cameraMain.ScreenPointToRay(Input.mousePosition), out rayCasthit, maxDistanceToRaycast, groundLayer);
bool isPlayerWithinMaxDistanceBetweenCharacters = Mathf.Abs(Vector3.Distance(player1Transform.position, transform.position)) <= maxDistanceBetweenPlayers;
bool isCursorCloserToOtherPlayer = Vector3.Distance(player1Transform.position, transform.position) > Vector3.Distance(rayCasthit.point, player1Transform.position);
bool mouseIsInAllowableArea = Input.mousePosition.y <= (maxCursorUpPercent * Screen.height);
bool PlayerCanMove = isCollidingWithGround && (isPlayerWithinMaxDistanceBetweenCharacters || isCursorCloserToOtherPlayer) && mouseIsInAllowableArea;
if (PlayerCanMove)
{
bool isInFollowRange = (Vector3.Distance(transform.position, rayCasthit.point) <= followSpeedIncreaseRange);
float tempMovementSpeed = movementSpeed;
if (!isInFollowRange)
tempMovementSpeed *= 5f;
float stepTowardsPointer = tempMovementSpeed * Time.deltaTime;
Vector3 newPosition = Vector3.MoveTowards(transform.position, rayCasthit.point, stepTowardsPointer);
transform.position = new Vector3(newPosition.x, 0.0f, newPosition.z);
}
}
Hope this helps. I tried commenting where your comment was but I seem to be having some browser issues with the submit button.
Thanks so much. You just solved a problem I've been having for days!
– Neythx dude. that rly helped
– CutaneousJust wanted to drop in and say this code solved my issues of having my projectile instantiate with the wrong rotation. This code works great. Thank you!
– Lumbartransform.LookAt(Vector3(target.position.x , target.position.y , fixedZ));
– ExsertI tried using this code to make a gameobject to "follow" my cursor [48529-code.jpg|48529] But I get this problem where it believe that the position of my gameobject is (0,0) so I have to move my mouse down in the left corner to get the gameobject to rotate. What am I doing wrong? (I have the Camera as a child under my "player" gameobject, does that have anything to do with this?) Please help <3
– Asseverate