【问题标题】:Unity2D shot object turns with character but shouldn'tUnity2D 拍摄对象随角色转动但不应该
【发布时间】:2020-03-16 16:08:37
【问题描述】:

我正在努力学习 Unity。我的目标是建造一个小行星克隆体。

目前,我的角色能够向鼠标位置飞行、射击和旋转。然而,子弹会以某种方式受到玩家转动的影响。

这里是一些示例代码:

player.cs

    private void Shoot()
    {
        Instantiate(Bullet, transform);
    }

    private void FaceMouseDirection()
    {
        Vector2 direction = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
        float angle = Mathf.Atan2(direction.x, direction.y) * Mathf.Rad2Deg;
        Quaternion rotation = Quaternion.AngleAxis(angle, Vector3.back);
        transform.rotation = Quaternion.Slerp(transform.rotation, rotation, turningSpeed * Time.deltaTime);
    }

bullet.cs

    private GameObject parent;
    private Vector3 Force;

    // Use this for initialization
    void Start () 
    {
        parent = GameObject.Find("Player");
        Force = parent.transform.up * bulletSpeed;
    }

    void FixedUpdate()
    {
        transform.Translate(Force * Time.fixedDeltaTime);
    }
}

【问题讨论】:

  • 当一个游戏对象是另一个对象的子对象时,它使用父对象变换。它自己的变换变得相对于父级。只是不要设置父母,你很高兴

标签: c# unity3d game-development


【解决方案1】:

子弹被设置为玩家的孩子。子对象与其父对象保持相同的旋转。

在子弹的Start() 中,您需要在设置力后从子弹中移除父项。

在我的脑海中,你应该能够做到这一点

transform.parent = null;

【讨论】:

  • 非常感谢,它就是这样工作的。子弹飞得很奇怪,因为它们不是单独飞在绿轴上的。但我想那是题外话。
【解决方案2】:

首先,不要让子弹成为玩家的孩子。 (不要使用Instantiate(Bullet, transform);

其次,将子弹的旋转和位置设置为与子弹实例化时的玩家相同。 (请使用Instantiate(Bullet, transform.position, transform.rotation);

第三,不要将子弹的移动基于玩家的变换。只需使用它自己的变换。 (请使用Force = transform.up * bulletSpeed; 而不是Force = parent.transform.up * bulletSpeed

player.cs

    private void Shoot()
    {
        GameObject bullet = Instantiate(Bullet, transform.position, transform.rotation);
    }

    private void FaceMouseDirection()
    {
        Vector2 direction = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
        float angle = Mathf.Atan2(direction.x, direction.y) * Mathf.Rad2Deg;
        Quaternion rotation = Quaternion.AngleAxis(angle, Vector3.back);
        transform.rotation = Quaternion.Slerp(transform.rotation, rotation, turningSpeed * Time.deltaTime);
    }

bullet.cs

    private Vector3 Force;

    // Use this for initialization
    void Start () 
    {

        Force = -transform.right * bulletSpeed;
    }

    void FixedUpdate()
    {
        transform.Translate(Force * Time.fixedDeltaTime);
    }
}

第四,您应该考虑为您的子弹使用一种称为object pooling 的技术,因为实例化和销毁许多几乎重复的游戏对象通常效率不高。

注意:如果您在项目符号上使用 RigidbodyRigidbody2D,您应该使用 rb.MovePosition(transform.position + Force * Time.deltaTime);Time.deltaTimeFixedUpdate 中的 Time.fixedDeltaTime 相同),因为它会正确插入在调用 FixedUpdate 之间呈现的帧。

【讨论】:

  • 非常感谢分享!你有什么想法,为什么我的子弹飞行被抵消了?当玩家向北看时,子弹飞到那里。但是当玩家向东看时,子弹飞向了南方……
  • @NullOrNotNull 因为子弹的旋转方式使得它们的本地向上不是它们行进的正确方向。从您的评论来看,听起来他们真的应该沿着当地的左方向行驶,但是如果没有显示他们的当地轴和他们打算旅行的方向的屏幕截图,很难确定。无论如何,我编辑了我的答案的bullet.cs 部分。如果这对您有任何改变,请告诉我。
  • 实际上对于子弹,我只需将其设置为 rb.velocity = -transform.right * bulletSpeed; 一次,而不使用 UpdateFixedUpdate :)
  • @derHugo 是的,这可能更好:)
【解决方案3】:

这可能是因为您将子弹实例化为对象变换的子对象。 然后,当对象旋转时,子弹也会旋转。

您想在世界/根目录中实例化它们,或者如果您想在层次结构中对它们进行分组,也可以在 (0,0,0) 处的静态对象中实例化它们。

Object.Instantiate(bullet).transform.position = base.transform.position

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-08
    • 1970-01-01
    • 2021-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    相关资源
    最近更新 更多