向量3.比较鼠标和游戏对象距离的距离

人气:724 发布:2022-10-16 标签: c# unity3d game-engine vector

问题描述

我有一些鼠标输入,我将其转换为Vector3。 现在,我使用这个输入并计算了鼠标输入和游戏对象位置之间的距离。 该方法返回一个浮点数作为我的距离,我将其与MaxDistance浮点数进行比较。 因此,当我的输入距离小于或等于我的最大距离时,它应该会摧毁我的游戏对象。 但当我运行我的游戏时,什么都不起作用。 我还尝试增加MaxDistance的值,但也无济于事。

以下是我的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Tropfen : MonoBehaviour
{
public float speed = 10.0f;
Rigidbody2D rb;
AudioSource source;
[SerializeField] AudioClip[] soundClips;
[SerializeField] GameObject particleEffect;
[SerializeField] float maxDistance = 20f;

void Start()
{
    rb = GetComponent<Rigidbody2D>();
    rb.velocity = new Vector2(0, -speed * Time.deltaTime);
    source = GetComponent<AudioSource>();
    source.clip = soundClips[Random.Range(0, soundClips.Length)];
}

// Update is called once per frame
void Update()
{
    Vector3 screenPos = Input.mousePosition;
    Camera.main.ScreenToWorldPoint(screenPos);

    float TropfenTouchDistance = Vector3.Distance(screenPos, gameObject.transform.position);

    if ( TropfenTouchDistance <= maxDistance)
    {
        TropfenDestruction();
    }
}

private void TropfenDestruction()
{
    Destroy(gameObject);
    AudioSource.PlayClipAtPoint(source.clip, transform.position);
    GameObject effect = Instantiate(particleEffect, transform.position, Quaternion.identity) as 
    GameObject;
    Destroy(effect, 2f);
    FindObjectOfType<Gameplay>().IncreaseScore(1);
}
}

推荐答案

您的screenPos仍在屏幕像素空间中,因为您没有使用ScreenToWorldPoint

的输出
var screenPos = Input.mousePosition;
var worldPos = Camera.main.ScreenToWorldPoint(screenPos);

// It's redundant going through the gameObject here btw
var TropfenTouchDistance = Vector3.Distance(worldPos, transform.position);

if ( TropfenTouchDistance <= maxDistance)
{
    TropfenDestruction();
}

无论如何请注意,ScreenToWorldPoint还需要Z组件

屏幕空间位置(通常为鼠标x,y),加上深度的z位置(例如,相机剪裁平面)。

指示该点距离给定Camera应投影到世界的距离。

为了克服这个问题,您可以使用数学Plane,这样您就可以在Plane.Raycast

中使用ScreenPointToRay准确地将一个点投影到对象旁边
// In general store the camera reference as Camera.main is very expensive!
[SerializeField] private Camera _camera;


private void Update()
{
    if(!_camera) _camera = Camera.main;

    var plane = new Plane(_camera.transform.forward, transform.position);
    var ray = _camera.ScreenPointToRay(Input.mousePosition);
    if(plane.Raycast(ray, out var hitDistance))
    {  
        var worldPoint = ray.GetPoint(hitDistance);
        var TropfenTouchDistance = Vector3.Distance(worldPos, transform.position);

        if ( TropfenTouchDistance <= maxDistance)
        {
            TropfenDestruction();
        }
    }
}

545