【问题标题】:Instantiate and Fire Object, when OnTriggerEnter or OnCollisionEnter在 OnTriggerEnter 或 OnCollisionEnter 时实例化并触发对象
【发布时间】:2017-06-02 10:37:45
【问题描述】:

我想要一颗从敌人身上发射的子弹,从我的玩家护盾上弹回来。

我已经设置了我的角色,敌人会每隔一段时间向我开火。 然后我可以激活我的玩家护盾(打开 BoxCollider)并按下按钮。

所以当子弹 (IsTrigger) 与我的玩家护盾 (IsNotTrigger) 发生碰撞时,我想移除这个子弹,然后从护盾中实例化一个新子弹,朝着敌人的方向。 我在销毁 Bullet 时也遇到了问题。

当 OnTriggerEvent 或 OnColliderEvent 发生(都尝试过)时,我的 Shield 会出现数百颗子弹。如何只允许向敌人发射一颗子弹?

下面是我的脚本的一部分,它位于我的 Players Shield 的 GameObject 中。 理想情况下,我想在子弹与物体碰撞后将其销毁。

void OnTriggerEnter(Collider col) {
    if (col.tag == "Weapon") {

        attack();
    }
}

private void attack() {

    if (!GameManager.instance.GameOver) {

    bulletReturnClone = Instantiate(bulletReturn, transform.position, transform.rotation) as GameObject;
    bulletReturnClone.GetComponent<Rigidbody>().velocity = transform.forward * 25f;

【问题讨论】:

  • 你的 bulletReturn 预制件有“武器”标签吗?
  • 是的,它有一个“武器”标签
  • 你的新子弹可能会触发新子弹的安装,所以会出现很多子弹。
  • 是的,这是有道理的。也许我的子弹在我的盒子对撞机中被实例化了。所以我的 fireLoctation 需要在这个盒子碰撞器之外。
  • 让我们知道它是否能解决您的问题。

标签: c# unity3d instantiation


【解决方案1】:

斯特拉坎,

这不是我解决问题的方式,但我会坚持您想要的解决方案,然后分享一些改进的想法。

void OnTriggerEnter(Collider col) {
if (col.tag == "Weapon") {

    attack(col);
    }
}

private void attack(Collider col) {

if (!GameManager.instance.GameOver) {

bulletReturnClone = Instantiate(bulletReturn,  transform.position, transform.rotation) as GameObject;
bulletReturnClone.GetComponent<Rigidbody>().velocity = transform.forward * 25f;
// the following line of code should remove the bullet from the shield collider in order to prevent any future problems like spawning multiple bullets or instantly destroying the newly created bullet
bulletReturnClone.GetComponent<Transform>().position *= bulletReturnClone.GetComponent<Rigidbody>().velocity; 
Destroy(col.gameObject);
    }
}

如果您的触发器(子弹)被标记为武器,则此代码应通过销毁子弹并实例化一个新子弹并修改其速度来实现您将子弹反射到盾牌指向的方向的故意目标。它有效,但它是一种草率的开发。如果您从不同的角度处理问题会更好 - 子弹而不是盾牌。

让我们假装你是子弹。你所做的就是朝着你被击中的方向飞行。一旦与地形发生碰撞,您就会停止/消失。如果这个地形是一个盾牌,你不会停止/消失,而是改变你的方向(你会被反射)。 所以……长话短说……应该有触发对撞机的是子弹而不是盾牌。子弹脚本的 OnTriggerEnter(Collider col) 会破坏它,但如果 col.tag == "Shield" 子弹只会改变它的方向,而没有所有无用的实例化和转换。 我懒得写第二个解决方案的代码。如果你明白我的意思,你应该可以很容易地写下来。通过尝试和错误学习也有助于您发展(请原谅我的懒惰)。

【讨论】:

  • 非常感谢您的回答,这很有意义。反映对象而不是实例化一个新对象要容易得多。根据您的最后一段,我已接受您的回答。再次感谢。
【解决方案2】:

我不确定你为什么要让子弹消失并以新的速度重生?

根据盾牌几何形状,您可以查找恢复系数,从而将子弹的动能反映为真实的速度。

请注意,根据不同的碰撞原语,数学的复杂性将与盾牌几何的复杂性成正比。

  • 球-球
  • 球面
  • 球形地形(地形可以代表任何不平坦的表面)

或者你想用某种“冲锋”机制来收集子弹,以便在不同的时间释放它们?

【讨论】:

  • 您好thanatorr,感谢您的回复。我最初是想反射子弹,但我认为销毁和实例化一个新子弹会更容易。想象一下,如果敌人直接在我的玩家面前并射出一颗子弹。我想用我的盾牌(盒子对撞机)将子弹反射回敌人。因此,当子弹 (OnTriggerEvent) 与 Shield 发生碰撞时。然后我可以销毁子弹,然后从盾牌位置实例化一颗新子弹并将其发送回敌人位置。
  • 在良好的实践方面还不错,尤其是对于游戏程序员来说,您可能会在做类似的事情时用掉太多的处理周期。但是,如果我们只想“让它工作”,可能会在盾牌上实现一个子弹列表,然后在event_tick()if (list.Count &gt; 0) 上发射子弹。不幸的是,我不知道确切的语法,因为我对虚幻引擎有很多经验。但如果你还在苦苦挣扎,我会尝试检查一下。
  • 感谢thanatorr的帮助。我决定从 BoxCollider 反射对象。这比重复实例化对象要容易得多。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多