Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 被毁子弹赢了';t在大约3秒钟后进行克隆和拍摄_C#_Unity3d - Fatal编程技术网

C# 被毁子弹赢了';t在大约3秒钟后进行克隆和拍摄

C# 被毁子弹赢了';t在大约3秒钟后进行克隆和拍摄,c#,unity3d,C#,Unity3d,我制作了一个脚本,射出一颗子弹并在3秒钟后销毁它,但是它在射出后销毁了原始子弹,这使得unity无法复制它来射出另一颗子弹,一个好的解决方案可能是复制子弹并射出副本,但我不知道怎么做 这是枪的剧本 using System.Collections; using System.Collections.Generic; using UnityEngine; public class GunShootingScript : MonoBehaviour { public ParticleSystem

我制作了一个脚本,射出一颗子弹并在3秒钟后销毁它,但是它在射出后销毁了原始子弹,这使得unity无法复制它来射出另一颗子弹,一个好的解决方案可能是复制子弹并射出副本,但我不知道怎么做

这是枪的剧本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GunShootingScript : MonoBehaviour
{
public ParticleSystem MuzzleFlash;
public float damage = 10f;
public float range = 100f;
public GameObject bulletPrefab;
public float bulletLife = 3f;

public Camera playerCamera;
private void Update()
{
    if(Input.GetKeyDown(KeyCode.Mouse0))
    {
        Destroy(bulletPrefab, bulletLife);
        Shoot();
    }
}
void Shoot()
{
    MuzzleFlash.Play();
    Instantiate(bulletPrefab, playerCamera.transform.position, playerCamera.transform.rotation);
    RaycastHit hit;
    if(Physics.Raycast(playerCamera.transform.position, playerCamera.transform.forward, out hit, range))
    {
        TakeDamage target = hit.transform.GetComponent<TakeDamage>();
        if(target != null)
        {
            target.GiveDamage(damage);
        }

    }

}
}

据我所见,你摧毁了BulletPrefable,但你从来没有为它指定过对象。您可以拥有一个单独的游戏对象,并在shot方法内部实例化时执行此操作。试试这个:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GunShootingScript : MonoBehaviour
{
public ParticleSystem MuzzleFlash;
public float damage = 10f;
public float range = 100f;
public GameObject bulletPrefab;
public float bulletLife = 3f;
private GameObject bulletShot // This is what I added

public Camera playerCamera;
private void Update()
{
    if(Input.GetKeyDown(KeyCode.Mouse0))
    {
        Destroy(bulletShot); // Removed the timer from here
        Shoot();
    }
}
void Shoot()
{
    MuzzleFlash.Play();
    bulletShot = Instantiate(bulletPrefab, playerCamera.transform.position, playerCamera.transform.rotation); // Assigned the bullet to the separate GameObject
    RaycastHit hit;
    if(Physics.Raycast(playerCamera.transform.position, playerCamera.transform.forward, out hit, range))
    {
        TakeDamage target = hit.transform.GetComponent<TakeDamage>();
        if(target != null)
        {
            target.GiveDamage(damage);
        }

    }

}
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
公共类枪杀脚本:MonoBehavior
{
公众参与制度;
公众浮子损坏=10f;
公共浮动范围=100f;
公共游戏对象公告;
公众寿命=3f;
私人游戏对象bulletShot//这是我添加的
公共摄像机;
私有void更新()
{
if(Input.GetKeyDown(KeyCode.Mouse0))
{
销毁(子弹);//从此处删除计时器
射击();
}
}
空射()
{
口吻闪光。播放();
bulletShot=实例化(BulletPrefact、playerCamera.transform.position、playerCamera.transform.rotation);//将子弹分配给单独的游戏对象
雷卡斯特击中;
if(物理光线投射(playerCamera.transform.position,playerCamera.transform.forward,out-hit,range))
{
TakeDamage target=hit.transform.GetComponent();
如果(目标!=null)
{
目标。造成伤害(伤害);
}
}
}
}
这样,当你试图摧毁它时,实际上会有东西被摧毁。然而,这将产生一个新问题。当你再次射击时,先前实例化的对象将立即被销毁。您可以通过创建列表并在其中添加项目符号来修复此问题。然而,这是没有效率的。既然要从头开始,我建议您使用对象池。那是什么?很高兴你这么问

YouTube上有一段Jason Weimann关于对象池的精彩视频。你可能想试一试,它很旧,但绝对不是过时的。

您可能需要保留对子弹的引用,以便能够在3秒后通过协同程序进行销毁,稍后它将如下所示:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GunShootingScript : MonoBehaviour
{
public ParticleSystem MuzzleFlash;
public float damage = 10f;
public float range = 100f;
public GameObject bulletPrefab;
public float bulletLife = 3f;

private Queue<GameObject> myQ = new Queue<GameObject>(); //queue to keep track of the shot bullet and handle the delayed destroy
private IEnumerator coroutine;

void Start() {
    coroutine = DelayedDestroy(3f);
}
public Camera playerCamera;
private void Update()
{
    if(Input.GetKeyDown(KeyCode.Mouse0))
    {
        //Destroy(bulletPrefab, bulletLife); Commented to avoid immediate destruction
        Shoot();
    }
}
void Shoot()
{
    MuzzleFlash.Play();
    myQ.Enqueue(Instantiate(bulletPrefab, playerCamera.transform.position, playerCamera.transform.rotation));
    RaycastHit hit;
    if(Physics.Raycast(playerCamera.transform.position, playerCamera.transform.forward, out hit, range))
    {
        TakeDamage target = hit.transform.GetComponent<TakeDamage>();
        if(target != null)
        {
            target.GiveDamage(damage);
        }

    }
    StartCoroutine(coroutine);

}

private IEnumerator DelayedDestroy(float waitTime) {
    yield return new WaitForSeconds(waitTime);
    GameObject nullcheck = myQ.Dequeue();
    if (nullcheck != null) { //in case the queue is empty
        Destroy(nullcheck );
    }
    
}
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
公共类枪杀脚本:MonoBehavior
{
公众参与制度;
公众浮子损坏=10f;
公共浮动范围=100f;
公共游戏对象公告;
公众寿命=3f;
private Queue myQ=new Queue();//用于跟踪子弹并处理延迟销毁的队列
私人IEnumerator合作项目;
void Start(){
协同程序=延迟的终止时间(3f);
}
公共摄像机;
私有void更新()
{
if(Input.GetKeyDown(KeyCode.Mouse0))
{
//销毁(BulletPrefact,bulletLife);注释以避免立即销毁
射击();
}
}
空射()
{
口吻闪光。播放();
排队(实例化(BulletPrefact、playerCamera.transform.position、playerCamera.transform.rotation));
雷卡斯特击中;
if(物理光线投射(playerCamera.transform.position,playerCamera.transform.forward,out-hit,range))
{
TakeDamage target=hit.transform.GetComponent();
如果(目标!=null)
{
目标。造成伤害(伤害);
}
}
启动程序(协同程序);
}
私有IEnumerator DelayedDestroy(浮动等待时间){
返回新的WaitForSeconds(waitTime);
GameObject nullcheck=myQ.Dequeue();
如果(nullcheck!=null){//队列为空
销毁(空检);
}
}
}
没有调试,这是给你的想法。您可以检查数据结构和

检查池以实现您正在做得更好的功能:)

Shoot();销毁(Bullet预制、Bullet寿命);先开枪,摧毁奥金子弹
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GunShootingScript : MonoBehaviour
{
public ParticleSystem MuzzleFlash;
public float damage = 10f;
public float range = 100f;
public GameObject bulletPrefab;
public float bulletLife = 3f;

private Queue<GameObject> myQ = new Queue<GameObject>(); //queue to keep track of the shot bullet and handle the delayed destroy
private IEnumerator coroutine;

void Start() {
    coroutine = DelayedDestroy(3f);
}
public Camera playerCamera;
private void Update()
{
    if(Input.GetKeyDown(KeyCode.Mouse0))
    {
        //Destroy(bulletPrefab, bulletLife); Commented to avoid immediate destruction
        Shoot();
    }
}
void Shoot()
{
    MuzzleFlash.Play();
    myQ.Enqueue(Instantiate(bulletPrefab, playerCamera.transform.position, playerCamera.transform.rotation));
    RaycastHit hit;
    if(Physics.Raycast(playerCamera.transform.position, playerCamera.transform.forward, out hit, range))
    {
        TakeDamage target = hit.transform.GetComponent<TakeDamage>();
        if(target != null)
        {
            target.GiveDamage(damage);
        }

    }
    StartCoroutine(coroutine);

}

private IEnumerator DelayedDestroy(float waitTime) {
    yield return new WaitForSeconds(waitTime);
    GameObject nullcheck = myQ.Dequeue();
    if (nullcheck != null) { //in case the queue is empty
        Destroy(nullcheck );
    }
    
}
}