如何解决如何对子弹进行击退 unity2D
我怎样才能做到当子弹击中一个物体时它会击退它并摧毁自己/消失?
我做了一些研究,但我找不到答案。我发现进行击退的唯一方法是让子弹正常击中物体,并以其质量给予击退,但子弹保持漂浮。
武器代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Weapon : MonoBehavIoUr
{
public Transform firePoint;
public float fireRate = 15f;
public GameObject bulletPrefab;
public Transform MuzzleFlashPrefab;
public AudioSource sfx;
private float nextTimetoFire = 0f;
[HideInInspector] public audio currentGunData;
void Update()
{
if (Input.GetButton("Fire1") && Time.time >= nextTimetoFire)
{
nextTimetoFire = Time.time + 1f/fireRate;
Shoot();
//sound
sfx.Stop();
sfx.clip = currentGunData.gunshotSound;
sfx.pitch = 1 - currentGunData.pitchRandomization + Random.Range(-currentGunData.pitchRandomization,currentGunData.pitchRandomization);
sfx.Play();
}
}
void Shoot()
{
Instantiate(bulletPrefab,firePoint.position,firePoint.rotation);
Transform clone = Instantiate (MuzzleFlashPrefab,firePoint.rotation) as Transform;
clone.parent = firePoint;
float size = Random.Range (0.02f,0.025f);
clone.localScale = new Vector3 (size,size,size);
Destroy (clone.gameObject,0.056f);
}
}
项目符号
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class bulet : MonoBehavIoUr
{
public float speed = 40f;
public Rigidbody2D rb;
// Start is called before the first frame update
void Start()
{
rb.veLocity = transform.right * speed;
}
}
我正在拍摄的对象
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class stickmancontroler : MonoBehavIoUr
{
public _Muscle[] muscles;
// Update is called once per frame
private void Update()
{
foreach (_Muscle muscle in muscles)
{
muscle.ActivateMuscle();
}
}
}
[System.Serializable]
public class _Muscle
{
public Rigidbody2D bone;
public float restRotation;
public float force;
public void ActivateMuscle()
{
bone.MoveRotation(Mathf.LerpAngle(bone.rotation,restRotation,force * Time.deltaTime));
}
}
我的击退尝试
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehavIoUr
{
public float knockbackaPower = 100;
public float knockbackDuration = 1;
private static Player instance;
private Rigidbody2D rb;
private void Awake()
{
instance = this;
}
void Start()
{
}
void Update()
{
}
void OnTriggerEnter2D (Collider2D col)
{
if(col.gameObject.name == "bulet")
{
Debug.Log("hti");
}
}
private void OnCollisionEnter2D(Collision2D other)
{
if(other.gameObject.tag == "bullet")
{
StartCoroutine(Knockback(knockbackDuration,knockbackaPower,this.transform));
}
}
public IEnumerator Knockback(float knockbackDuration,float knockbackaPower,Transform obj)
{
float timer = 0;
while (knockbackDuration > timer)
{
timer += Time.deltaTime;
Vector2 direction = (obj.transform.position - this.transform.position).normalized;
Debug.Log(rb);
rb.AddForce(-direction * knockbackaPower);
}
yield return 0;
}
}
解决方法
只有在子弹不再与物体碰撞后,您才能使用 OnCollisionExit2D() 销毁子弹。这样你就可以让子弹正常击中物体并用它的质量击退它。
,如果你最后只yield
,你的协程有什么用?如果您想将 while
循环分布在多个帧上,您必须在其中yield return null;
!
并且您可以在开始击退的那一刻简单地调用 Destroy(other.gameObject);
,这样子弹在击中某物时立即被摧毁。只需预先缓存它的位置/击退方向,而不是预先重复计算每次迭代。
private void OnCollisionEnter2D(Collision2D other)
{
// In general rather use CompareTag instead of string ==
// it is slightly faster and avoids typos since it would throw an error instead of silently fail
if(other.gameObject.ComapareTag("bullet"))
{
// Here you want to pass in the OTHER transform (the one of the bullet)
// and NOT your own one!
StartCoroutine(Knockback(knockbackDuration,knockbackaPower,other.transform));
}
}
private IEnumerator Knockback(float knockbackDuration,float knockbackaPower,Transform bullet)
{
var direction = (bullet.transform.position - transform.position).normalized;
// As soon as you have all relevant values destroy the bullet immediately after a hit
Destroy(bullet);
var timer = 0f;
while (timer < knockbackDuration)
{
rb.AddForce(-direction * knockbackaPower);
// You need to yield INSIDE the while loop
// otherwise it is fully performed within one single frame
timer += Time.deltaTime;
yield return null;
}
}
现在,如果不是让 onbects 碰撞(这应该已经在不需要协程的情况下造成一些击退),你实际上可以将其设为 触发器,而是实际计算来自 theass 和子弹的撞击速度
private IEnumerator OnTriggerEnter2D(Collider2D other)
{
if(!other.CompareTag("bullet") || !other.TryGetComponent<Rigidbody2D>(out var bulletRb)) yield break;
// Calculate the knock force caused by the bullet's mass and velocity
var speedSqr = bullerRb.velcotiy.sqrMagnitude;
var direction = bullerRb.velcotiy.normalized;
var force = 0.5f * bulletRb.mass * speedSqr * direction;
Destroy(other.gameObject);
rb.AddForce(force,ForceMode.Impulse);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。