Unity3D 在没有 OnCollisionEnter 的情况下检查碰撞
Unity3D checking collisions without OnCollisionEnter
我在游戏中使用游戏对象作为子弹,但我可能做得不好。我从我的枪管中投射光线,实例化对象并将其移动 Transform.MoveTowards () 到 RaycastHit.point。问题是当我向敌人开枪时,但它在子弹到达之前就移动了,因为子弹永远漂浮在空中。我在那里看到了两个解决方案:我可以检查子弹是否击中了某个东西,但我不知道怎么做,因为给数百颗子弹一个脚本,这个脚本只为 OnCollisionEnter 每帧完成是一个坏主意。第二种方法是每帧改变目标位置,但我不知道如何保存。
我应该怎么做?
public static List <GameObject> bullets = new List <GameObject> ();
public static List <Vector3> targets = new List <Vector3> ();
public override void Shot (Vector3 hitPoint) {
for (int i = 0; i < raysNumber; i++) {
direction = new Vector3 (UnityEngine.Random.Range (-splash, splash), UnityEngine.Random.Range (-splash, splash), 100);
direction = t_barrel.TransformDirection (direction);
if (Physics.Raycast (t_barrel.position, direction, out cele[i], 100, layer)) {
EnemyFPS enemyHealth = cele[i].collider.GetComponent <EnemyFPS> ();
bullets.Add (MonoBehaviour.Instantiate (g_kubik, t_barrel.position, t_barrel.rotation) as GameObject);
targets.Add (cele [i].point);
}
}
public override void MoveBullets () {
if (bullets.Count > 150) {
bullets.RemoveAt (0);
targets.RemoveAt (0);
}
for (int i = 0; i < bullets.Count; i++) {
bullets [i].transform.position = Vector3.MoveTowards (bullets [i].transform.position, targets [i] * 10, 1f);
}
}
每帧调用 MoveBullets。
编辑:我的问题图片:
项目符号:
Vector3 pro;
float speed = 10;
void Start () {
pro = transform.InverseTransformDirection (transform.forward);
}
void Update () {
transform.Translate (pro * speed * Time.deltaTime);
}
void OnTriggerEnter (Collider other) {
Debug.Log ("Collision");
EnemyFPS enemy = other.gameObject.GetComponent <EnemyFPS> ();
if (enemy != null) {
enemy.TakeDamage (5);
other.gameObject.transform.SetParent (other.transform);
}
GetComponent<Collider>().gameObject.GetComponent <Collider> ().enabled = false;
Destroy (gameObject.GetComponent <BulletS> ());
}
射击
t_barrel.LookAt (hitPoint);
MonoBehaviour.Instantiate (g_kubik, t_barrel.position, t_barrel.rotation);
如果你完全按照 Unity3d space 射手教程学习,我相信你所有的疑问都会得到解决。这是它的link。
我的理解和你基本上需要做的是给你的敌人添加一个对撞机,这样当子弹碰到敌人时,就会发生一些事情。比如,敌人死亡或受伤,子弹当然会被摧毁,除非是狙击步枪子弹,有时可以穿透头骨并杀死第一个敌人后面的另一个敌人,但那是更高级的东西。
或者,您可以限制每帧可以产生的子弹数量。
在 unity 中为您的 enemy/target 设置标签。例如,让我们将敌方游戏对象的标签设置为"EnemyObj"。
然后,在项目符号代码中使用以下伪代码:
void OnTriggerEnter (Collider other) {
//Compare the tag of the Collider other object with "EnemyObj" using compare tag method
//If it is true then..
//Do something like decrease health
//Finally call Destroy (gameObject.GetComponent <BulletS> ());
}
您需要做的是在您的 BulletScript
中添加一个名为 direction
的字段,让子弹朝一个方向而不是一个点射击。这就是为什么你的子弹到了那个点而无处可去的原因。
public static List <GameObject> bullets = new List <GameObject> ();
public static List <Vector3> targets = new List <Vector3> ();
public float speed;
public override void Shot (Vector3 hitPoint) {
for (int i = 0; i < raysNumber; i++) {
direction = new Vector3 (UnityEngine.Random.Range (-splash, splash), UnityEngine.Random.Range (-splash, splash), 100);
direction = t_barrel.TransformDirection (direction);
if (Physics.Raycast (t_barrel.position, direction, out cele[i], 100, layer)) {
EnemyFPS enemyHealth = cele[i].collider.GetComponent <EnemyFPS> ();
BulletScript bullet = Instantiate (g_kubik, t_barrel.position, t_barrel.rotation) as BulletScript;
bullet.direction = (cele [i].point - t_barrel.position).normalized;
bullets.Add (bullet);
}
}
public override void MoveBullets () {
if (bullets.Count > 150) {
bullets.RemoveAt (0);
targets.RemoveAt (0);
}
for (int i = 0; i < bullets.Count; i++) {
bullets [i].transform.position += bullets [i].direction * speed * Time.deltaTime;
}
}
我在游戏中使用游戏对象作为子弹,但我可能做得不好。我从我的枪管中投射光线,实例化对象并将其移动 Transform.MoveTowards () 到 RaycastHit.point。问题是当我向敌人开枪时,但它在子弹到达之前就移动了,因为子弹永远漂浮在空中。我在那里看到了两个解决方案:我可以检查子弹是否击中了某个东西,但我不知道怎么做,因为给数百颗子弹一个脚本,这个脚本只为 OnCollisionEnter 每帧完成是一个坏主意。第二种方法是每帧改变目标位置,但我不知道如何保存。 我应该怎么做?
public static List <GameObject> bullets = new List <GameObject> ();
public static List <Vector3> targets = new List <Vector3> ();
public override void Shot (Vector3 hitPoint) {
for (int i = 0; i < raysNumber; i++) {
direction = new Vector3 (UnityEngine.Random.Range (-splash, splash), UnityEngine.Random.Range (-splash, splash), 100);
direction = t_barrel.TransformDirection (direction);
if (Physics.Raycast (t_barrel.position, direction, out cele[i], 100, layer)) {
EnemyFPS enemyHealth = cele[i].collider.GetComponent <EnemyFPS> ();
bullets.Add (MonoBehaviour.Instantiate (g_kubik, t_barrel.position, t_barrel.rotation) as GameObject);
targets.Add (cele [i].point);
}
}
public override void MoveBullets () {
if (bullets.Count > 150) {
bullets.RemoveAt (0);
targets.RemoveAt (0);
}
for (int i = 0; i < bullets.Count; i++) {
bullets [i].transform.position = Vector3.MoveTowards (bullets [i].transform.position, targets [i] * 10, 1f);
}
}
每帧调用 MoveBullets。
编辑:我的问题图片:
项目符号:
Vector3 pro;
float speed = 10;
void Start () {
pro = transform.InverseTransformDirection (transform.forward);
}
void Update () {
transform.Translate (pro * speed * Time.deltaTime);
}
void OnTriggerEnter (Collider other) {
Debug.Log ("Collision");
EnemyFPS enemy = other.gameObject.GetComponent <EnemyFPS> ();
if (enemy != null) {
enemy.TakeDamage (5);
other.gameObject.transform.SetParent (other.transform);
}
GetComponent<Collider>().gameObject.GetComponent <Collider> ().enabled = false;
Destroy (gameObject.GetComponent <BulletS> ());
}
射击
t_barrel.LookAt (hitPoint);
MonoBehaviour.Instantiate (g_kubik, t_barrel.position, t_barrel.rotation);
如果你完全按照 Unity3d space 射手教程学习,我相信你所有的疑问都会得到解决。这是它的link。
我的理解和你基本上需要做的是给你的敌人添加一个对撞机,这样当子弹碰到敌人时,就会发生一些事情。比如,敌人死亡或受伤,子弹当然会被摧毁,除非是狙击步枪子弹,有时可以穿透头骨并杀死第一个敌人后面的另一个敌人,但那是更高级的东西。
或者,您可以限制每帧可以产生的子弹数量。
在 unity 中为您的 enemy/target 设置标签。例如,让我们将敌方游戏对象的标签设置为"EnemyObj"。 然后,在项目符号代码中使用以下伪代码:
void OnTriggerEnter (Collider other) {
//Compare the tag of the Collider other object with "EnemyObj" using compare tag method
//If it is true then..
//Do something like decrease health
//Finally call Destroy (gameObject.GetComponent <BulletS> ());
}
您需要做的是在您的 BulletScript
中添加一个名为 direction
的字段,让子弹朝一个方向而不是一个点射击。这就是为什么你的子弹到了那个点而无处可去的原因。
public static List <GameObject> bullets = new List <GameObject> ();
public static List <Vector3> targets = new List <Vector3> ();
public float speed;
public override void Shot (Vector3 hitPoint) {
for (int i = 0; i < raysNumber; i++) {
direction = new Vector3 (UnityEngine.Random.Range (-splash, splash), UnityEngine.Random.Range (-splash, splash), 100);
direction = t_barrel.TransformDirection (direction);
if (Physics.Raycast (t_barrel.position, direction, out cele[i], 100, layer)) {
EnemyFPS enemyHealth = cele[i].collider.GetComponent <EnemyFPS> ();
BulletScript bullet = Instantiate (g_kubik, t_barrel.position, t_barrel.rotation) as BulletScript;
bullet.direction = (cele [i].point - t_barrel.position).normalized;
bullets.Add (bullet);
}
}
public override void MoveBullets () {
if (bullets.Count > 150) {
bullets.RemoveAt (0);
targets.RemoveAt (0);
}
for (int i = 0; i < bullets.Count; i++) {
bullets [i].transform.position += bullets [i].direction * speed * Time.deltaTime;
}
}