沿光线投射移动对象
Move Object Along Raycast
我制作了一个从我的相机到点击对象点的 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);
}
}
您可能希望使用 ray.direction 属性 而不是 (0,1500,0) 作为力的方向。
加力应该发生在 FixedUpdate 中,并且应该只在 Ray 击中某物时发生。你现在拥有它的地方可能不是最好的地方。
当然,首先要确保子弹在相机位置实例化。
Ray.direction 为您提供射线对象的 vector3 方向。如果你需要它击中的距离,你也可以使用ray.distance。
编辑:我现在在我的电脑旁边,所以这里有一个与您的评论相关的更详细的答案。
首先:这是我设置测试项目的方式:
我创建了一个预制子弹。这只是一个带有刚体的球体,附有我的 "BulletController" 脚本。预制件的要点是避免所有那些必须添加组件的行。出于测试目的,我将刚体设置为忽略重力并将其质量设置为 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 用于添加力等物理变化。不要使用更新来做这种事情。它将力乘以您设置的称为 "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 脚本拖到您为子弹制作的不同预制件上。这不会影响您的侦听器脚本,它仍会在您单击的位置创建项目符号。
如果有终点,则可以使用 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;
}
}
我制作了一个从我的相机到点击对象点的 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);
}
}
您可能希望使用 ray.direction 属性 而不是 (0,1500,0) 作为力的方向。
加力应该发生在 FixedUpdate 中,并且应该只在 Ray 击中某物时发生。你现在拥有它的地方可能不是最好的地方。
当然,首先要确保子弹在相机位置实例化。
Ray.direction 为您提供射线对象的 vector3 方向。如果你需要它击中的距离,你也可以使用ray.distance。
编辑:我现在在我的电脑旁边,所以这里有一个与您的评论相关的更详细的答案。
首先:这是我设置测试项目的方式:
我创建了一个预制子弹。这只是一个带有刚体的球体,附有我的 "BulletController" 脚本。预制件的要点是避免所有那些必须添加组件的行。出于测试目的,我将刚体设置为忽略重力并将其质量设置为 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 用于添加力等物理变化。不要使用更新来做这种事情。它将力乘以您设置的称为 "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 脚本拖到您为子弹制作的不同预制件上。这不会影响您的侦听器脚本,它仍会在您单击的位置创建项目符号。
如果有终点,则可以使用 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;
}
}