沿Raycast移动对象

时间:2017-11-19 09:15:40

标签: c# unity3d unity5

我做了一个从我的相机到点击对象点的Raycast。但是,我试图使一个物体(在这种情况下是子弹)沿着光线的路径飞行。目前,无论你点击的物体在哪里因为矢量3而从相机直接向前飞行。我怎么能让它跟随雷?

C#

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 个答案:

答案 0 :(得分: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拖到相应的字段中。务必将预制件从文件夹中拖出,而不是从SCENE中拖出。因为这将使用预制,而不是场景中的对象。

现在点击左右,你会看到子弹在飞!请注意,使用较小的力量可以测试,然后在以后增加。

要摆脱的主要问题是分裂你的逻辑。脚本应该只负责一件事。例如,你的敌人也可能发射子弹。您现在可以为这些项目符号重用bulletController脚本。另外,假设你有不同大小或形状的子弹,你可以将子弹头控制器脚本拖到你为子弹制作的不同预制件上。这不会影响您的侦听器脚本,该脚本仍会在您单击的位置创建项目符号。

答案 1 :(得分: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;
    }
}