Как сделать raycast с курсора без использования системы физики? - PullRequest
0 голосов
/ 30 июня 2019

Я собираюсь в WebGL и отключил физическую систему в диспетчере пакетов, чтобы уменьшить размер сборки.Сейчас я нахожусь в положении, в котором я хочу найти место приземления луча, запущенного из курсора.См. Диаграмму:

Diagram

Могу ли я сделать это без системы физики, или мне потребуется включить ее и пару мегабайт, которые она добавляет к текущему размеру сборки 5 Мб?

1 Ответ

2 голосов
/ 01 июля 2019

Вы могли использовать 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


Изначально я думал, что вы деактивировали физический пакет , который является экспериментальным и больше касается столкновений твердого тела и массы. И не относится к 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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...