你的问题很简单:
您正在检查玩家位置和射线方向之间的距离!
当然这完全没有意义,因为它基本上等于Camera.main.transform.forward。如果你使用像位置这样的归一化方向,它基本上会是 Unity 原点周围距离为 1 的东西。而你的玩家可以定位在任何地方。你想检查玩家和hitInfo.point之间的距离!
// If possible already reference this in the Inspector
[SerializeField] private Camera _camera;
private void Awake ()
{
// As fallback get the camera ONCE on runtime, "Camera.main" is expensive!
//see https://docs.unity3d.com/ScriptReference/Camera-main.html
if(!_camera) _camera = Camera.main;
}
private void Update()
{
var ray = _camera.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(ray, out hitInfo)
{
// Get the position where exactly you hit something
var hitPoint = hitInfo.point;
// Regardless of what we hit eliminate any difference in the Y axis
hitPoint.y = 0;
// also map the player position on the XZ plane (erase any Y axis height)
var playerPosition = transform.position;
playerPosition.y = 0;
// Now you get the correct distance between both points in the XZ plane
var distance = Vector3.Distance(hitPoint, playerPosition);
Debug.Log($"Distance: {distance}", this);
}
}
在您的情况下,我将使用光线和 Playboard 的交点 - 假设 Unity XZ Plane。
然后获取映射到 XZ 平面上的玩家位置与 XZ 平面中的射线命中点之间的距离。
这样做的好处是这是纯数学的,不需要任何对撞机,并且如果有不同的对撞机挡路,也不会破坏。
类似
// If possible already reference this in the Inspector
[SerializeField] private Camera _camera;
// First parameter is the global UP axis -> we get the flat floor in XZ axis
// For the second parameter you could e.g. change the Y component if there needs
// to be a ground height different to 0
// see https://docs.unity3d.com/ScriptReference/Plane-ctor.html
private Plane _xzPlane = new Plane(Vector3.up, Vector3.zero);
private void Awake ()
{
// As fallback get the camera ONCE on runtime, "Camera.main" is expensive!
//see https://docs.unity3d.com/ScriptReference/Camera-main.html
if(!_camera) _camera = Camera.main;
}
private void Update()
{
var ray = _camera.ScreenPointToRay(Input.mousePosition);
// Directly use a raycasts on the XZ plane -> pure mathematical doesn't need any collider/physics
// see https://docs.unity3d.com/ScriptReference/Plane.Raycast.html
if(plane.Raycast(ray, out hitDistance)
{
// get the position where we hit the XZ plane
// see https://docs.unity3d.com/ScriptReference/Ray.GetPoint.html
var xzHitPoint = ray.GetPoint(hitDistance);
// map the player position on the XZ plane (erase any Y axis height)
// see https://docs.unity3d.com/ScriptReference/Plane.ClosestPointOnPlane.html
var xzPlayerPosition = plane.ClosestPointOnPlane(transform.position);
// Now you get the correct distance between both points in the XZ plane
var distance = Vector3.Distance(xzHitPoint, xzPlayerPosition);
Debug.Log($"Distance: {distance}", this);
}
}
API 链接在代码 cmets 中。