- Home /
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 {
}
}
}
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 ();
}
Answer by victorbisaev · Feb 01, 2018 at 11:34 PM
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" :)
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.
Your answer
Follow this Question
Related Questions
Raycast2d not working C# :( 1 Answer
How to find out which object is under a specific pixel 1 Answer
Mouse Over Questions 1 Answer
Checking if object stopped being hit by Raycast while overlapping another object of the same type. 0 Answers
How to achieve a more accurate Mouse to WorldCoordinates & faster updating of object follow? 2 Answers