private void LateUpdate() { if (lastCursorState != grapple.cursorState) { switch (grapple.cursorState) { case GrappleCursorState.LOCKED: seekerImage.sprite = locked; break; case GrappleCursorState.UNLOCKED: seekerImage.sprite = unlocked; break; case GrappleCursorState.OUT_OF_RANGE: seekerImage.sprite = outOfRange; break; } } lastCursorState = grapple.cursorState; }
private void PositionSeeker() { Vector3 sCenter = new Vector3(0.5f, 0.5f); Vector3 point = new Vector3(0, 0); float distance = float.MaxValue; Vector3 sPoint = new Vector3(0.5f, 0.5f); bool edgeFound = false; for (int i = 0; i < edgeCount; ++i) { Vector3 p1 = edgePoints[i * 2 + 0]; Vector3 p2 = edgePoints[i * 2 + 1]; if ((p1 - transform.position).sqrMagnitude > squaredGrappleDistance || (p2 - transform.position).sqrMagnitude > squaredGrappleDistance) { continue; } Vector3 sp1 = cameraComponent.WorldToViewportPoint(p1); Vector3 sp2 = cameraComponent.WorldToViewportPoint(p2); if (sp1.z < 0 || sp2.z < 0) { continue; } if (sp1.x < 0 || sp1.x > 1 || sp1.y < 0 || sp1.y > 1 || sp2.x < 0 || sp2.x > 1 || sp2.y < 0 || sp2.y > 1) { continue; } Vector3 leftBound = (sp1.x < sp2.x) ? sp1 : sp2; Vector3 rightBound = (sp2.x > sp1.x) ? sp2 : sp1; if (sCenter.x < leftBound.x - grappleSnapDistance || sCenter.x > rightBound.x + grappleSnapDistance) { continue; } float x = Mathf.Clamp(sCenter.x, leftBound.x, rightBound.x); float alpha = Mathf.InverseLerp(leftBound.x, rightBound.x, x); float y = Mathf.Lerp(leftBound.y, rightBound.y, alpha); Vector2 pointOnEdge = new Vector2(x, y); Vector2 cursorPoint = new Vector2(sCenter.x, sCenter.y); float tDistance = Vector2.Distance(pointOnEdge, cursorPoint); if (tDistance > grappleSnapDistance) { continue; } if (tDistance > distance && edgeFound) { continue; } Vector3 screenPoint = new Vector3(x, y, 1); Vector3 tpoint = cameraComponent.ViewportToWorldPoint(screenPoint); tpoint -= cameraTransform.position; { float yDist = p1.y - cameraTransform.position.y; if (tpoint.y == 0) { continue; } float ratio = yDist / tpoint.y; tpoint *= Mathf.Abs(ratio); } tpoint += cameraTransform.position; Vector3 tSPoint = new Vector3(x, y); Ray cameraRay = cameraComponent.ViewportPointToRay(tSPoint); RaycastHit hit; if (Physics.Raycast(cameraRay, out hit)) { if (Mathf.Abs(hit.point.sqrMagnitude - tpoint.sqrMagnitude) > 0.1f) { continue; } } point = tpoint; sPoint = tSPoint; edgeFound = true; distance = tDistance; } if (edgeFound) { seekerWorldPoint = point; cursorState = GrappleCursorState.LOCKED; } else { Ray cameraRay = cameraComponent.ViewportPointToRay(sCenter); RaycastHit hit; if (Physics.Raycast(cameraRay, out hit)) { if (hit.distance > grappleDistance) { seekerWorldPoint = Vector3.zero; cursorState = GrappleCursorState.OUT_OF_RANGE; } else { seekerWorldPoint = hit.point; cursorState = GrappleCursorState.UNLOCKED; } } else { seekerWorldPoint = Vector3.zero; cursorState = GrappleCursorState.OUT_OF_RANGE; } } seekerNormalizedPosition = Vector3.Lerp(seekerNormalizedPosition, sPoint, grappleSnapAlpha); Vector3 screenSize = new Vector3(cameraComponent.pixelWidth, cameraComponent.pixelHeight); seekerTransform.position = new Vector3(seekerNormalizedPosition.x * screenSize.x, seekerNormalizedPosition.y * screenSize.y); }