我如何限制从游戏对象到我的光标绘制的线渲染器的距离?
How would I clamp the distance of a LineRender being drawn from a game object towards my cursor?
我正在创建一个迷你高尔夫游戏,玩家可以点击并拖动来击球。目前,我有一条线显示击球的方向和力量。我不确定如何在保持正确方向的同时限制线渲染的距离(也称为功率)。我还想将线渲染的长度与图片左下角的功率计ui同步。我在下面提供了我的代码:
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;
}
}
您可以使用它,例如在
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.
我正在创建一个迷你高尔夫游戏,玩家可以点击并拖动来击球。目前,我有一条线显示击球的方向和力量。我不确定如何在保持正确方向的同时限制线渲染的距离(也称为功率)。我还想将线渲染的长度与图片左下角的功率计ui同步。我在下面提供了我的代码:
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;
}
}
您可以使用它,例如在
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.