How to Limit Input.mousePosition or Raycast

Hey Unity,

I’ve been implementing mouse interaction into a grid-based game. Currently I am using a combination of Physics.Raycast with ScreenToRay and then Lerping the selectors position.

I’ve attached a short GIF showing that the sensitivity makes it so it’s almost impossible to select the tile you want.
I am wondering if anyone has encountered this before and/or if anyone has any advice or suggestions on how to achieve a smoother more precise selector.

Here’s a snippet from my scripts

RAYCAST

Ray ray = GameCore.currentCam.ScreenPointToRay (Input.mousePosition);
		Debug.DrawLine (ray.origin, ray.GetPoint(100f),Color.red);
		if (Input_Enabled) {

					
		int layerMask = 1 << 8;

		if (Physics.Raycast (ray, out hit, 50f, layerMask)) {
				if (hit.collider.gameObject.GetComponentInParent<GameTile_Controller> () != null){
							if (lastTile != null) {
								if (hit.collider.gameObject == lastTile)
									return;
								
							}
							timeStamp = Time.time + cooldown;
							lastTile = hit.collider.gameObject;
							GameCoreInstructions.instance.Current_Selector.GetComponent<System_SelectorController> ().currentTargetTile = hit.collider.gameObject;
							GameCoreInstructions.instance.Current_Selector.GetComponent<System_SelectorController> ().StartLerping ();
						} else {

						}
					}
				}

107225-ezgifcom-optimize-1.gif

LERP

if (isLerping) {


			float timeSinceStarted = Time.time - _timeStartedLerping;
			float percentageComplete = timeSinceStarted / timeTakenDuringLerp;
			//Perform the actual lerping.  Notice that the first two parameters will always be the same
			//throughout a single lerp-processs (ie. they won't change until we hit the space-bar again
			//to start another lerp)
			transform.position = Vector3.Lerp (transform.position, newPos, percentageComplete);

			if(percentageComplete >= 1f)
			{
				transform.position = newPos;
				StopLerping ();
			}


		}


public void StartLerping(){
		_timeStartedLerping = Time.time;
		isLerping = true;
		if(Current_Tile != null)
			Current_Tile.GetComponent<GameTile_Controller> ().isSelectorOnTile = false;

		// Go to NEW Location
		Current_x = (int)currentTargetTile.transform.position.x;
		Current_y = (int)currentTargetTile.transform.position.z;
		newPos = new Vector3 ((float)Current_x, 0.2f, (float)Current_y);
	}

	void StopLerping(){
		isLerping = false;
	//	Debug.Log ("finished lerp");
		Move_Update ();
		GameCoreInstructions.instance.audioSource.clip = GameCoreInstructions.instance.clips [1];
		GameCoreInstructions.instance.audioSource.Play ();
	

	}

It looks like when thee mouse moves out the central tile, then the Lerping is activated and it moves the world. But then it means, that next tile becomes a target of the Raycast so the movement continue and “support itself” :slight_smile:

Possible solution - make a “safe” area in the center of the screen. Which means Lerping is not activated if the mouse in the central area (not in just a central tile) of the screen, say, if 0.25 * screenWidth < x < 0.75 * screenWidth then Lerping is not activated. It allows safe and convenient selection of tiles.

More advanced idea - make the speed of scrolling depends on the distance between current mouse position and the screen center: float speed = Mathf.Abs(mouseX - screenWidth/2) / speedCoeff; when mouse is close to the center then almost no scrolling happened, but if the mouse is moved toward the screen border, then speed of the scrolling increases. You can choose the value of “speedCoeff” to tune the speed so you feel comfortable to play your game.