Как бы я зафиксировал расстояние отрисовки LineRender от игрового объекта до моего курсора?

Как бы я зафиксировал расстояние отрисовки LineRender от игрового объекта до моего курсора?

Я создаю игру в мини-гольф, в которой игрок щелкает и перетаскивает мяч, чтобы выстрелить. В настоящее время у меня есть линия, показывающая направление и силу выстрела. Я не совсем уверен, как бы я зафиксировал расстояние (или мощность) рендеринга линии, сохраняя при этом правильное направление. Я также хочу синхронизировать длину рендеринга линии с пользовательским интерфейсом измерителя мощности в левом нижнем углу изображения. Я предоставил свой код ниже:

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;
    }
}
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
18
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы ищете 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.

Другие вопросы по теме