Anyway to make my mouse position or my cursor more accurate than this?

I’m trying to make it to where when you press left or right mouse buttons, the player will punch. Right now I’m just trying to get it to where his hands will move forward towards the mouse, but the mouse seems to be offset so when I click either left or right mouse, the hands are different distances away from the player. Here is the issue:

. Here is my player punching script.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class playerPunch : MonoBehaviour
{
    public GameObject leftHand;
    public GameObject rightHand;

    public float punchDistance = 100f;

    // Update is called once per frame
    void Update()
    {
        Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);

        if (Input.GetButtonDown("Fire1"))
        {
            mousePos.z = leftHand.transform.position.z;
            leftHand.transform.position = Vector3.MoveTowards(leftHand.transform.position, mousePos, punchDistance * Time.deltaTime);
        }

        if (Input.GetButtonDown("Fire2"))
        {
            mousePos.z = rightHand.transform.position.z;
            rightHand.transform.position = Vector3.MoveTowards(rightHand.transform.position, mousePos, punchDistance * Time.deltaTime);
        }
    }
}

And here is my player movement script.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class playerMovement : MonoBehaviour
{
    public float speed = 10.0f;
    public GameObject player;
    public Rigidbody2D rb;

    Vector2 mousePos;

    // Start is called before the first frame update
    void Start()
    {
      
    }

    // Update is called once per frame
    void Update()
    {
        Rigidbody2D rigidbody2D = GetComponent<Rigidbody2D>();
        rigidbody2D.constraints = RigidbodyConstraints2D.FreezeRotation;

        // Move up and down
        if (Input.GetKey(KeyCode.W))
        {
            rigidbody2D.velocity = new Vector2(rigidbody2D.velocity.x, +speed);
        }
        else
        {
            if (Input.GetKey(KeyCode.S))
            {
                rigidbody2D.velocity = new Vector2(rigidbody2D.velocity.x, -speed);
            }
            else
            {
                rigidbody2D.velocity = new Vector2(rigidbody2D.velocity.x, 0);
                rigidbody2D.constraints = RigidbodyConstraints2D.FreezePositionY | RigidbodyConstraints2D.FreezeRotation;
            }
        }

        // Move left and right
        if (Input.GetKey(KeyCode.D))
        {
            rigidbody2D.velocity = new Vector2(+speed, rigidbody2D.velocity.y);
        }
        else
        {
            if (Input.GetKey(KeyCode.A))
            {
                rigidbody2D.velocity = new Vector2(-speed, rigidbody2D.velocity.y);
            }
            else
            {
                rigidbody2D.velocity = new Vector2(0, rigidbody2D.velocity.y);
                rigidbody2D.constraints = RigidbodyConstraints2D.FreezePositionX | RigidbodyConstraints2D.FreezeRotation;
            }
        }
    }

    void FixedUpdate()
    {
        Vector2 playerPos = player.transform.position;
        mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);

        Vector2 lookDir = mousePos - playerPos;
        float angle = Mathf.Atan2(lookDir.y, lookDir.x) * Mathf.Rad2Deg + 90f;
        rb.rotation = angle;
    }
}

Ok so I removed the " * Time.deltatime" part from my punching code and it eliminated some of the issue for me (at least I think that was the issue), but when I have the custom cursor, it does the same issue as in the first video.

In your code, you are moving the left and right hand TOWARDS the destination position, not TO it. That line of code is only happening once when, you click.

So what’s happening is, the fist is moving to the point for 1 update loop, but that’s not what MoveTowards is for. It needs to run multiple updates so it can reach its destination (for your use case). If you want to see what I mean, lower the punchDistance variable (actually, it shouldn’t be called punchDistance, it should be called punchSpeed).

Since its only running once, instead of

leftHand.transform.position = Vector3.MoveTowards(leftHand.transform.position, mousePos, punchDistance * Time.deltaTime);

You want

leftHand.transform.position = mousePos;

(make sure to do this for both hands)

If you actually want to make it move at some speed to the position instead of just jumping instantly, you need to modify your code. See if you can figure that out with the information I gave.

Well wouldn’t that move the hand directly to the cursor? If so, then your hand could stretch as far as you wanted, and I don’t want that. I want something like what surviv.io does. I’m trying to recreate that so that I can learn.

I just tried it and I died instantly lol. I just replicated the game. Keep in mind, there are many ways to do this. It was a little out of the scope of what you were trying to do, so PLEASE use this as a learning experience, it’ll make you better. I even added some duplicate code for you as an exercise to fix. Here is your new playerPunch class (You should capitalize player btw.)

Heck, if you can find another way to do it. It’ll only make you a better programmer.

using System.Collections;
using UnityEngine;
public class playerPunch : MonoBehaviour {

    private const float PUNCH_DISTANCE = 3f;
    private const float PUNCH_SPEED = 7f;
    private const float PUNCH_TOLERANCE = .1f;
    private const float PUNCH_TIME = .15f;
 
    public GameObject leftHand;
    public GameObject rightHand;

    private Vector2 leftHandOrigin, rightHandOrigin, punchSpot;

    private enum PunchState {
        PUNCHING, RETURNING, NONE
    }

    private PunchState leftHandState, rightHandState;

    private void Start() {

        // Calculate where the 'punchSpot' should be (at distance away from player)
        punchSpot = Vector2.down * PUNCH_DISTANCE;
    
        leftHandOrigin = leftHand.transform.localPosition;
        rightHandOrigin = rightHand.transform.localPosition;

        leftHandState = PunchState.NONE;
        rightHandState = PunchState.NONE;
    }
 
    private void Update() {

        // There are many ways to do this, but here's one
        // **** TODO: There's duplicate code all over, can you make it better? ****
    
        // Left hand initial punch
        if (Input.GetButtonDown("Fire1") && leftHandState == PunchState.NONE) {
            leftHandState = PunchState.PUNCHING;
            StartCoroutine(LeftHandTimer());
        }

        // Left hand punching
        else {
            leftHand.transform.localPosition = Vector2.MoveTowards(
                leftHand.transform.localPosition, leftHandState == PunchState.PUNCHING ? punchSpot : leftHandOrigin ,
                Time.deltaTime * PUNCH_SPEED);

            if (leftHandState == PunchState.RETURNING && leftHand.transform.localPosition.y > leftHandOrigin.y - PUNCH_TOLERANCE) {
                leftHand.transform.localPosition = leftHandOrigin;
                leftHandState = PunchState.NONE;
            }
        }
    
        // Right hand initial punch
        if (Input.GetButtonDown("Fire2") && rightHandState == PunchState.NONE) {
            rightHandState = PunchState.PUNCHING;
            StartCoroutine(RightHandTimer());
        }

        // Right hand punching
        else {
            rightHand.transform.localPosition = Vector2.MoveTowards(
                rightHand.transform.localPosition, rightHandState == PunchState.PUNCHING ? punchSpot : rightHandOrigin ,
                Time.deltaTime * PUNCH_SPEED);

            if (rightHandState == PunchState.RETURNING && rightHand.transform.localPosition.y > rightHandOrigin.y - PUNCH_TOLERANCE) {
                rightHand.transform.localPosition = rightHandOrigin;
                rightHandState = PunchState.NONE;
            }
        }
    }

    // Coroutine for left hand
    private IEnumerator LeftHandTimer() {
        yield return new WaitForSeconds(PUNCH_TIME);
        leftHandState = PunchState.RETURNING;
    }
 
    // Coroutine for right hand
    private IEnumerator RightHandTimer() {
        yield return new WaitForSeconds(PUNCH_TIME);
        rightHandState = PunchState.RETURNING;
    }
}

Ok, so it was more complex than I thought? I don’t understand a lot of that, but isn’t there a simpler way of doing this? You brought to my attention the fact that I needed a starting point and an ending point for the punch. I didn’t think of that, but is there not an easier way to make it move from the start to the end while also not moving on the mouse?

Of course, you could use an animation that you simply run when the button is fired and you will get the desired effect, and have barely any code at all. Part of the reason I wanted you to see it was so that you could see an example of what you might have to do to make it work programmatically, like you were doing.

Here’s a video on 2d animating in unity:

I could have animated it, but I feel like that would have been harder for some reason, although I’m not too sure. Even if I did do that, I would still have to program a way for people or objects to take damage. I assume that I would establish a point where if the object touched the point and the left mouse button was pressed, it would take damage. Thanks for all the help, and I hope you don’t mind if I take the script you wrote.

Good news! You can actually use a 2D collider on the fists to detect if it hit something via a trigger that will move with the animation, so that would work perfectly fine. Realistically, since what you want to do is pretty static, an animation makes way more sense. I just prefer to code (coding can lead to fun stuff, like making the punches more dynamic. Doesn’t mean it will be simple though).

Of course! I hope you get something out of it.