2D Mouse Aiming - Grappling Hook?

Hi guys. I’m trying to get 2D mouse aiming working, so I can make a grappling hook, and I’m having a few issues.

The red line that you can see is from point 0,0,0 to the player. The blue line is from the origin, to what is supposed to be the mouse cursor. The green line is a raycast, from the player through the mouse, and is supposed to collide with solid objects (which, admittedly, is what it’s doing.)

However, as you can see from the actual active part of the screenshot, where the raycast is going, and where the mouse is pointing, is two different things. I can’t work out why. I’m guessing it has to do with how I’m grabbing the mouse data, though.

I’ll also post my grapple.js, so maybe someone can work out what the heck I’m doing wrong.

Also, forgive me if there’s already an answer somewhere on this, I couldn’t find it. :stuck_out_tongue:

private var hit : RaycastHit;
var testBox : GameObject;
private var lastPosition : Vector3;  // Where the mouse position was last
private var mouseRel : Vector3;

function Start()
{
    lastPosition = Input.mousePosition;
    mouseRel = Vector3.zero;
}

function Update () {
	var mousePos = Input.mousePosition;
	
    // If the mouse has moved since the last update
    if (mousePos != lastPosition) {
        lastPosition = mousePos;
       
        mPosX = mousePos.x;
        mPosY = mousePos.y;
        
        mouseRel = Vector3(mPosX, mPosY, 0);
    }
    
    Physics.Raycast (transform.position, mouseRel, hit);
    
    if (Input.GetMouseButtonDown(0)) {
		//Physics.Raycast (transform.position, mouseRel, hit);
		Instantiate(testBox, mouseRel, Quaternion.identity);
	}
	
	DebugDrawLine(transform.position, hit.point, Color.green);
	DebugDrawLine(Vector3.zero, mouseRel, Color.blue);
	DebugDrawLine(Vector3.zero, transform.position, Color.red);
}

function DebugDrawLine(playerPos: Vector3, mousePos: Vector3, lineCol: Color) {
		Debug.DrawLine (playerPos, mousePos, lineCol);
}

I’m slowly working it out.

private var hit : RaycastHit;
private var lastPosition : Vector3;  // Where the mouse position was last
private var mouseRel : Vector3;
private var isGrappling = false;

public var playerObj : CharacterController;
public var grappleVelocity = 5.0;

function Start()
{
    lastPosition = Input.mousePosition;
    mouseRel = Vector3.zero;
    //hit.length = 1;
}

function Update () {

	GrabMousePos();
     
    if (Input.GetMouseButtonDown(0)  !isGrappling) {
		doGrapple();
	} 
	else if (isGrappling  Input.GetMouseButtonDown(0))
	{
		isGrappling = false;
	}
	else if (isGrappling)
	{
		//checkLineOfSight();
		DebugDrawLine(playerObj.transform.position, hit.point, Color.yellow);
	}
	
    //debug lines; remember to delete
    var testhit : RaycastHit;
    var testVector = mouseRel - playerObj.transform.position;//Vector3( mouseRel.x - playerObj.transform.position.x, mouseRel.y - playerObj.transform.position.y, mouseRel.z - playerObj.transform.position.z);
    
    	//Disable Raycasts for collider in parent object, so we don't shoot ourselves
	for(c in playerObj.transform.root.GetComponentsInChildren(Collider))
		c.gameObject.layer=2;
    
    Physics.Raycast (playerObj.transform.position, testVector, testhit);
    
    	//Enable raycasts again
	for(c in playerObj.transform.root.GetComponentsInChildren(Collider))
		c.gameObject.layer=0;
    
    DebugDrawLine(playerObj.transform.position, testhit.point, Color.green);		

	DebugDrawLine(Vector3(0,0,5), mouseRel, Color.blue);
	
	DebugDrawLine(mouseRel, transform.position, Color.red);
}

function GrabMousePos()
{
	var ray = camera.ScreenPointToRay (Input.mousePosition); 
	
	var checkHit : RaycastHit;
	
	if (Physics.Raycast (ray, checkHit, Mathf.Infinity)) 
    {
    	mouseRel = checkHit.point;
    	//mouseRel.z = 5;
    }
	
	/*
	var mousePos = Input.mousePosition;
	
    // If the mouse has moved since the last update
    if (mousePos != lastPosition) {
        lastPosition = mousePos;
        // Get mouse X and Y position as a percentage of screen width and height
        mPosX = mousePos.x;// / Screen.width;
        mPosY = mousePos.y;// / Screen.height;
        
        //Debug.Log(mPosX);
        //Debug.Log(mPosY);
        //Debug.Log("---");
        
        mouseRel = Vector3(mPosX, mPosY, 0);
    }*/
}

function doGrapple()
{
	//Disable Raycasts for collider in parent object, so we don't shoot ourselves
	for(c in playerObj.transform.root.GetComponentsInChildren(Collider))
		c.gameObject.layer=2;
	
	//Physics.Raycast (transform.position, mouseRel, hit);
	// temp raycast to bypass stupid mouse aiming - note: it's hitting the character model
	Physics.Raycast(playerObj.transform.position, Vector3(0,1,0), hit);

	
	//Enable raycasts again
	for(c in playerObj.transform.root.GetComponentsInChildren(Collider))
		c.gameObject.layer=0;
		
	isGrappling = true;
}

function checkLineOfSight()
{
	// check if you have line of sight to the last hit point
	// no? add new hit point from end of array
	// draw the lines
	//var testhit : RaycastHit;
	//Physics.Raycast (transform.position, hit.point[hit.length - 1], testhit);
}

function DebugDrawLine(playerPos: Vector3, mousePos: Vector3, lineCol: Color) {
		Debug.DrawLine (playerPos, mousePos, lineCol);
}

This gets me this:

There’s actually an invisible plane “behind” the level for the cursor to collide against, so I can grab a point anywhere, not just where there is a solid object.

Now I just need to work out the point along the red line that is the working plane (z = 5), and I’ve got it.

I haven’t looked at your stuff in depth at all, but are you aware of this function?

You should be able to pass something using Input.mousePosition to it.

Cheers,
-Jon

Oh god.

facepalm

I even looked at that, and discounted it.

Trust me to do it that hard way.

This seems to do the job:

function GrabMousePos()
{
	gx = Input.mousePosition.x;
	gy = Input.mousePosition.y;
	gz = Mathf.Abs(transform.position.z);
	mouseRel = camera.ScreenToWorldPoint (Vector3 (gx, gy, gz));
}

Thanks.

No worries. It definitely says something positive about ones character I think to put your head down and dig through a problem for a solution.

Glad it’s working.

Cheers,
-Jon