我做了一个从我的相机到点击对象点的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);
}
}
答案 0 :(得分:3)
您可能希望使用ray.direction属性而不是(0,1500,0)作为力的方向。
添加力应该发生在FixedUpdate中,并且只有在Ray遇到某些东西时才会发生。你现在拥有它可能不是最好的地方。
当然,请确保子弹首先在相机的位置进行实例化。
Ray.direction为您提供光线对象的vector3方向。如果你需要它所达到的距离,你也可以使用ray.distance。
编辑:我现在就在我的电脑旁边,所以这里有一个更详细的答案与你的评论有关。
我创建了一个预制子弹。这只是一个带有刚体的球体,附有我的“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;
}
}