Я создаю игру в мини-гольф, в которой игрок щелкает и перетаскивает мяч, чтобы выстрелить. В настоящее время у меня есть линия, показывающая направление и силу выстрела. Я не совсем уверен, как бы я зафиксировал расстояние (или мощность) рендеринга линии, сохраняя при этом правильное направление. Я также хочу синхронизировать длину рендеринга линии с пользовательским интерфейсом измерителя мощности в левом нижнем углу изображения. Я предоставил свой код ниже:
private void ProcessAim()
{
if (!isAiming || !isIdle) {
return;
}
worldPoint = CastMouseClickRay();
if (!worldPoint.HasValue) {return;}
DrawLine(worldPoint.Value);
}
private void Shoot(Vector3 worldPoint)
{
// Disabling the aiming
isAiming = false;
lineRenderer.enabled = false;
Vector3 horizontalWorldPoint = new Vector3(worldPoint.x, transform.position.y, worldPoint.z);
Vector3 direction = (horizontalWorldPoint - transform.position).normalized;
float strength = Vector3.Distance(transform.position, horizontalWorldPoint);
rb.AddForce(direction * strength * shotPower);
}
private void DrawLine(Vector3 worldPoint)
{
Vector3[] positions = { transform.position, worldPoint };
lineRenderer.SetPositions(positions);
lineRenderer.enabled = true;
}
private Vector3? CastMouseClickRay()
{
// Grabs the x and y coords and the clipPlane of the camera
Vector3 screenMousePosFar = new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.farClipPlane);
Vector3 screenMousePosNear = new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.nearClipPlane);
// Converts to in-game
Vector3 worldMousePosFar = Camera.main.ScreenToWorldPoint(screenMousePosFar);
Vector3 worldMousePosNear = Camera.main.ScreenToWorldPoint(screenMousePosNear);
Vector3 direction = (worldMousePosFar - worldMousePosNear).normalized;
// Casting a ray between the two clipPlanes of the camera at the x and y coords to see if it hit any colliders
RaycastHit hit;
if (Physics.Raycast(worldMousePosNear, worldMousePosFar - worldMousePosNear, out hit, float.PositiveInfinity))
{
return hit.point;
}
else
{
return null;
}
}
Вы ищете Vector3.ClampMagnitude
Вы можете использовать его, например. в
private void DrawLine(Vector3 worldPoint)
{
// get vector from your position towards worldPoint
var delta = worldPoint - transform.position;
// clamp the distance
delta = Vector3.ClampMagnitude(delta, YOUR_DESIRED_MAX_DISTANCE);
// assign back
worldPoint = transform.position + delta;
Vector3[] positions = { transform.position, worldPoint };
lineRenderer.SetPositions(positions);
lineRenderer.enabled = true;
}
Кстати, в CastMouseClickRay
вы должны просто использовать Camera.ScreenPointToRay
// you should cache Camera.main!
private Camera mainCamera;
private Vector3? CastMouseClickRay()
{
// you should cache Camera.main as it is expensive!
if (!mainCamera) mainCamera = Camera.main;
// simple as that you get the mouse ray
var ray = mainCamera.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out var hit))
{
return hit.position;
}
else
{
return null;
}
}
Или если вы действительно хотели сделать то, что говорит ваш комментарий
// Casting a ray between the two clipPlanes of the camera at the x and y coords to see if it hit any colliders
тогда вы бы не использовали Raycast
с бесконечным расстоянием, а скорее Physics.Linecast
if (Physics.Linecast(worldMousePosNear, worldMousePosFar, out var hit))
Returns true if there is any collider intersecting the line between start and end.