Hello guys, good day!
I am trying to create a script that move my player with rigidbody 2d to a specific location selected with the mouse.
So far its not working, the ony movement i can see is when i click anywhere the player moves to the right always.
can you help me ?
See my code:
thanks you in advance
public class ClickToMove2 : MonoBehaviour
{
//private float speed = 1100;
private Vector3 targetPosition;
private Camera mainCamera;
[SerializeField] private float movementSpeed;
Animator Anim;
// Update is called once per frame
private void Start()
{
mainCamera = Camera.main;
Anim = GetComponent<Animator>();
}
void Update()
{
if (Input.GetMouseButton(0))
{
CalculateTargetPosition();
MoveToTarget();
}
}
void CalculateTargetPosition()
{
Vector3 mousePosition = Input.mousePosition;
mousePosition.z = 10;
//Debug.Log("Mouse: " + mousePosition);
Vector3 transformedPosition = mainCamera.ScreenToWorldPoint(mousePosition);
//Debug.Log("Mouse trans: " + transformedPosition);
targetPosition = new Vector3(transformedPosition.x, transformedPosition.y, transformedPosition.z);
//Debug.Log("Mouse target: " + targetPosition);
}
private void MoveToTarget()
{
transform.position = Vector3.MoveTowards(transform.position, targetPosition, Time.deltaTime * movementSpeed);
}
}
Hi,
I think using Vector3.Lerp would probably be a better option.
You would end up with something like that:
public IEnumerator LerpController(Vector2 targetPos, float duration)
{
float time = 0;
Vector3 startPos = transform.position;
while (time < duration)
{
transform.position = Vector3.Lerp(startPos, targetPos, time / duration);
time += Time.deltaTime;
yield return null;
}
transform.position = targetPos;
}
startPos would be the current position of your object and targetPos would be your mouse position.
You can call it like:
Vector2 mousePos = Input.mousePosition;
void OnMouseDown()
{
StartCoroutine(LerpController(mousePos, .3f));
}
Here is some more information:
Hope that helps:)
Thanks a lot for you reply, i will definitely give it a try.
Best regards
Why are you setting the mouseposition to always be 10? This will cause the resulting position to have its z value affected to be 10 every time. Even if this is intended behavior for a 2D game, you should make that a global variable of some kind so its not randomly scattered throughout scripts.
As far as getting intended behavior, why not use Physics.Raycast
? This will allow you to specify further down the road of development which objects you want the player to be able to move to and which you don’t.
I made a few changes to your script - I added a moveupdate
flag that allows a single-click to perpetually update the movement instead of having to hold the mouse button down. I also set targetPosition
to equal the object’s initial position on Awake()
.
public class ClickToMove2 : MonoBehaviour
{
// -- serialized attributes
[SerializeField]
private bool moveupdate = true;
[SerializeField]
private float movementSpeed;
[SerializeField]
private LayerMask hitmask;
[SerializeField]
private float maxdist = 100;
// -- private attributes
private new Camera camera;
private Vector3 targetPosition;
void Awake()
{
targetPosition = transform.position;
}
void Start()
{
camera = Camera.main;
}
void Update()
{
bool holdingmouse = Input.GetMouseButton(0);
if (holdingmouse)
{
CalculateTargetPosition();
if (!moveupdate)
MoveToTarget();
}
if(moveupdate)
MoveToTarget();
}
void CalculateTargetPosition()
{
Ray ray = camera.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out RaycastHit hit, maxdist, hitmask, QueryTriggerInteraction.Ignore))
{
targetPosition = hit.point;
}
}
private void MoveToTarget()
{
transform.position = Vector3.MoveTowards(transform.position, targetPosition, Time.deltaTime * movementSpeed);
}
}
[Edit]: Here is a gif link to see the results of my script: