沿着射线移动物体

3
我已经制作了一个从我的摄像机到点击对象点的射线。然而,我正在尝试让一个物体(在这种情况下是一颗子弹)沿着射线路径飞行。目前它会因为向量3而直线向前从摄像机飞出,无论你在对象上的哪个位置点击。如何让它遵循射线路径?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RaycastShot : MonoBehaviour {

public Camera camera;
private Ray ray;
private RaycastHit hit;
public GameObject bullet;
private GameObject createBullet;
private Collider collider;

void Update () {
    if (Input.GetMouseButtonDown (0)) {
        ray = camera.ScreenPointToRay (Input.mousePosition);

        createBullet = Instantiate (bullet, camera.transform.position, bullet.transform.rotation);
        createBullet.AddComponent<Rigidbody>();
        createBullet.GetComponent<Rigidbody>().AddRelativeForce (new Vector3(0, 1500, 0));
        createBullet.GetComponent<Rigidbody>().useGravity = false;
        collider = createBullet.GetComponent<Collider> ();
        Destroy (collider);

        if (Physics.Raycast (ray, out hit)) {

        }
    }
    Debug.DrawLine (ray.origin, hit.point, Color.red);
}
}
2个回答

3

您需要使用ray.direction属性而不是(0,1500,0)作为力的方向。

添加力应该在FixedUpdate中发生,并且只有在Ray击中物体时才应该发生。您现在的位置可能不是最佳位置。

当然,首先确保子弹在摄像机位置实例化。

Ray.direction给出了射线对象的vector3方向。如果您需要它撞击的距离,则还可以使用ray.distance。

编辑:我现在靠近我的计算机,所以这里是与您的评论相关的更详细的答案。

首先:这是我设置测试项目的方式:

enter image description here

我创建了一个预制弹丸。这只是一个带有刚体的球体,并附有我的“BulletController”脚本。预制件的目的是避免所有必须添加组件的行。出于测试目的,我将rigibody设置为忽略重力,其质量为0.1。

接下来,我创建了BulletController脚本,它将附加到子弹预制件上。

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

public class BulletController : MonoBehaviour {

    Rigidbody rb;
    public float bulletForce;
    bool firstTime = false;
    Vector3 direction;

    // Use this for initialization
    void Start () {
        rb = GetComponent<Rigidbody> ();
    }


    public void SetDirection (Vector3 dir) {
        direction = dir;
        firstTime = true;
    }

    void OnCollisionEnter () {
        //code for when bullet hits something
    }

    void FixedUpdate () {
        if (firstTime) {
            rb.AddForce (direction * bulletForce);
            firstTime = false;
        }
    }   
}

这个脚本负责控制子弹。以后将要创建子弹的脚本并不关心它们之后会发生什么,因为它的工作只是创建子弹。这个BulletController脚本负责处理一旦创建出来的子弹。

主要部分是SetDirection方法,它告诉子弹应该朝哪个方向移动。它还在它的FixedUpdate方法中添加了一个单次的力,将子弹推向你刚刚设置的方向。FixedUpdate用于物理变化,例如添加力。不要使用Update来做这种事情。它将力与你设置的名为"bulletForce"的力相乘。

最后一个是BulletListener脚本,它只是附加到场景中的一个空游戏对象上。这个脚本负责监听鼠标点击,并朝它们创建子弹。

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

public class BulletListener : MonoBehaviour {

    public Camera mainCamera;
    public BulletController bulletPrefab;

    void Update () {
        if (Input.GetMouseButtonDown (0)) {

            //create ray from camera to mousePosition
            Ray ray = mainCamera.ScreenPointToRay (Input.mousePosition);

            //Create bullet from the prefab
            BulletController newBullet = Instantiate (bulletPrefab.gameObject).GetComponent<BulletController> ();

            //Make the new bullet start at camera
            newBullet.transform.position = mainCamera.transform.position;

            //set bullet direction
            newBullet.SetDirection (ray.direction);

        }

    }
}

在这个空游戏对象的检查器中,我添加了这个脚本,然后将相机和bulletPrefab拖到相应的字段中。请确保从文件夹中拖动预制件,而不是从场景中拖动物体,因为这将使用预制件,而不是场景中的对象。
现在点击一下,你会看到子弹飞行!注意使用较低的力量来测试,然后稍后再增加它。
从中可以得出的主要要点是要分离逻辑。一个脚本只负责一件事情。例如,您的敌人也可能发射子弹。现在,您可以重复使用bulletController脚本来控制这些子弹。另外,假设您有不同大小或形状的子弹,您只需将bulletcontroller脚本拖到为子弹创建的不同预制件上即可。这不会影响仍将在单击处创建子弹的监听器脚本。

我正在尝试使用ray.direction,但不太确定如何引用它。createBullet.GetComponent<Rigidbody>().AddRelativeForce (ray.direction); - Liam Smith
非常完美地运作。非常感谢您。真的非常感激。 - Liam Smith

2

如果您有终点,则可以使用MoveTowards沿着矢量移动:

Vector3 target = hit.point;
StartCoroutine(MoveAlong(target));


private IEnumerator MoveAlong(Vector3 target){
    while(this.transform.position != target){
         this.transform.position = MoveTowards(this.transform.position, target, step);
         yield return null;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接