Вы могли использовать Plane.Raycast
using UnityEngine;
public class GetRaycast : MonoBehaviour
{
Camera camera;
public Transform PlaneTransform;
public Transform Player;
// Start is called before the first frame update
private void Start()
{
camera = Camera.main;
}
// Update is called once per frame
private void Update()
{
if (!Input.GetMouseButtonDown(0)) return;
// you just need any 3 points inside of the plane and provide them
// in clockwise order (so the normal points upwards)
// for the raycast this actually wouldn't matter
var plane = new Plane(PlaneTransform.position, PlaneTransform.position + PlaneTransform.forward, PlaneTransform.position + PlaneTransform.right);
// get ray for mouseposition
var ray = camera.ScreenPointToRay(Input.mousePosition);
// enter will be the distance between the ray origin and the hit plane
if (!plane.Raycast(ray, out var enter)) return;
// GetPoint returns the position along the raycast in
// the given distance from the ray origin
Player.position = ray.GetPoint(enter) + Vector3.up * 0.1f;
}
}
Однако, огромный недостаток этого метода заключается в том, что сгенерированный plane
равен бесконечен , поэтому обнаружение радиопередачи не заканчивается на границах фактической плоскости, так что вы пришлось бы снова зажать это «вручную».
Вы могли бы сделать это в этом простом примере, когда плоскость в мире плоская, как
public class GetRaycast : MonoBehaviour
{
Camera camera;
public MeshFilter PlaneTransform;
public Transform Player;
// Start is called before the first frame update
private void Start()
{
camera = Camera.main;
}
// Update is called once per frame
private void Update()
{
if (!Input.GetMouseButtonDown(0)) return;
// you just need any 3 points inside of the plane and provide them
// in clockwise order (so the normal points upwards)
// for the raycast this actually wouldn't matter
var plane = new Plane(PlaneTransform.transform.position, PlaneTransform.transform.position + PlaneTransform.transform.forward, PlaneTransform.transform.position + PlaneTransform.transform.right);
// get ray for mouseposition
var ray = camera.ScreenPointToRay(Input.mousePosition);
// enter will be the distance between the ray origin and the hit plane
if (!plane.Raycast(ray, out var enter)) return;
// GetPoint returns the position along the raycast in
// the given distance from the ray origin
var hitPosition = ray.GetPoint(enter);
// check if hitposition is within the Plane mesh
// mesh.bounds returns the bounding box of the mesh but
// unscaled. lossyScale is the overall scale in the scene
// also taking all parent scales into account
if (hitPosition.x < PlaneTransform.mesh.bounds.min.x * PlaneTransform.transform.lossyScale.x
|| hitPosition.x > PlaneTransform.mesh.bounds.max.x * PlaneTransform.transform.lossyScale.x
|| hitPosition.z < PlaneTransform.mesh.bounds.min.z * PlaneTransform.transform.lossyScale.z
|| hitPosition.z > PlaneTransform.mesh.bounds.max.z * PlaneTransform.transform.lossyScale.z)
{
return;
}
Player.position = hitPosition + Vector3.up * 0.1f;
}
}
Теперь игрок должен установить новую позицию только в том случае, если щелчок был внутри Плоскости.
![enter image description here](https://i.stack.imgur.com/nYx6V.gif)
Изначально я думал, что вы деактивировали физический пакет , который является экспериментальным и больше касается столкновений твердого тела и массы. И не относится к Physics.Raycast
, который является частью UnityEngine
.
После вашего комментария я понимаю, что вы на самом деле деактивируйте встроенный Physics
.
В противном случае вы все равно сможете просто использовать Physics.Raycast
, например,
using UnityEngine;
public class GetRaycast : MonoBehaviour
{
Camera camera;
public Transform Player;
// Start is called before the first frame update
private void Start()
{
camera = Camera.main;
}
// Update is called once per frame
private void Update()
{
if (!Input.GetMouseButtonDown(0)) return;
if (!Physics.Raycast(camera.ScreenPointToRay(Input.mousePosition), out var hit)) return;
// I just make it float a little to avoid mesh overlaps
Player.position = hit.point + Vector3.up * 0.1f;
}
}