代码之家  ›  专栏  ›  技术社区  ›  Liam Smith

沿光线投射移动对象

  •  2
  • Liam Smith  · 技术社区  · 7 年前

    我做了一个光线投射,从我的相机到点击的对象点。然而,我试图使一个对象(在本例中是一个子弹)沿着光线的路径飞行。此时,由于矢量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 回复  |  直到 7 年前
        1
  •  3
  •   Adam B    7 年前

    你会想使用ray。方向属性,而不是(01500,0)作为力的方向。

    附加力应在FixeUpdate中发生,并且仅当光线击中某物时才会发生。你现在拥有它的地方可能不是最好的地方。

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

    射线方向为您提供光线对象的矢量3方向。如果需要它击中的距离,也可以使用ray。距离

    编辑:我现在离我的电脑很近,这里有一个关于你评论的更详细的答案。

    首先:以下是我设置测试项目的方式: enter image description here

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

    接下来,我创建了BulletController脚本,该脚本将附加到bullet预制。

    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方法中添加了一个一次性力,将其推向刚刚设置的方向。FixeUpdate用于物理更改,如添加力。不要使用更新来做这种事情。它将力乘以您设置的力,称为“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);
    
            }
    
        }
    }
    

    在这个空游戏对象的检查器中,我添加了这个脚本,然后将摄像机和BulletPrefact拖到适当的字段中。确保从文件夹而不是场景中拖动预设。因为这将使用预设,而不是场景中的对象。

    现在点击周围,你会看到子弹在飞!请注意,使用较小的力进行测试是很好的,稍后再增加。

    从这件事中我们要做的主要事情是分解你的逻辑。一个脚本应该只负责一件事。例如,你的敌人也可能发射子弹。现在,您也可以对这些项目符号重用bulletController脚本。此外,假设您有不同大小或形状的子弹,您只需将bulletcontroller脚本拖动到为子弹制作的不同预制件上。这不会影响您的侦听器脚本,它仍然会在您单击的位置创建项目符号。

        2
  •  2
  •   Everts    7 年前

    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;
        }
    }