【问题标题】:Child object not instantiating on parent子对象未在父对象上实例化
【发布时间】:2019-02-25 15:57:00
【问题描述】:

我很难理解 Unity 中的位置概念。

有一个父对象(玩家)。在那个播放器上,我有一个名为“Gun”的子对象。在枪上,我有一个发射子弹的脚本。当我发射子弹时,它会出现在枪的左侧和玩家的左侧。

我尝试在生成时偏移子弹的位置,但是当我转身时,位置不正确(它仍然不在枪的中心)。我也有一种感觉,我尝试过的偏移量是一种 hack,并且我在某个地方错过了一些东西。

我的枪射击脚本代码:

void Update()
{
    if (Input.GetAxisRaw("Fire1") > 0)
    {
        var pos = transform.position;
        print(pos.ToString());
        var proj = Instantiate(projectile, pos, Quaternion.identity);

        proj.transform.rotation = transform.rotation;

    }
}

唯一与子弹接触的是我的 BulletController,子弹上的一个脚本:

void Start()
{
    rb = GetComponent<Rigidbody2D>();
    //rb.AddForce(transform.forward * 100, ForceMode.Impulse);
    rb.velocity = transform.up * 10;

}

附上我的设置截图

【问题讨论】:

  • 你能打印出子弹在产生后以及运动更新时在框架上的位置吗?移动的第一帧可能发生偏移,或者您的子弹预制件未设置为 0, 0, 0
  • @Eliasar 不确定“在它生成后的帧上”是什么意思,但我所做的是在项目符号上添加一个脚本,在更新时打印出它的位置,那就是0,0,0

标签: c# unity3d vector


【解决方案1】:

您想根据枪的朝向将子弹定位到相对偏移,对吗?如果您像现在这样设置位置,那么您将在与枪的朝向无关的世界位置上进行设置。

现在,有两种方法可以做到:

将子弹作为枪的子对象放置在一个相对的本地位置,并立即取消它的父级。不是一个很好的解决方案,更像是一个 hack。

或者使用我创建的以下方法:

/// <summary> Returns a vector which is relative to the facing and position of 'c'. </summary>
public static Vector3 RelativePosition (Transform c, Vector3 target)
{
    return c.right * target.x + c.up * target.y + c.forward * target.z + c.position;
}

/// <summary> Returns a vector which is relative. </summary>
public static Vector3 RelativePosition (Vector3 position, Vector3 forward, Vector3 up, Vector3 right, Vector3 target)
{
    return right * target.x + up * target.y + forward * target.z + position;
}

并补充这一点:

/// <summary> Returns a vector which is relative to the facing of 'c'. </summary>
public static Vector3 RelativePositionZero (Transform c, Vector3 target)
{
    return c.right * target.x + c.up * target.y + c.forward * target.z;
}

/// <summary> Returns a vector which is relative. </summary>
public static Vector3 RelativePositionZero (Vector3 forward, Vector3 up, Vector3 right, Vector3 target)
{
    return right * target.x + up * target.y + forward * target.z;
}

用法:使用RelativePosition方法,提供枪的Transform作为参数和Vector3参数的相对偏移。示例:

        item.position = RelativePosition (Camera.Main.transform, new Vector3 (1.5f, 0f, 4.0f));

这会将“项目”的位置 4 统一距离放在相机前面,并将 1.5 统一距离放在右侧。

提示:RelativePosition 将按原样为您提供最终的世界位置。这就是您用来接收您寻求的相对位置作为世界位置的东西。 RelativePositionZero 将为您提供从 Transform 对象到给定 Vector3 位置的相对偏移量。这可用于确定某物是左还是右、上方或下方、给定 Transform 的前面或后面。

【讨论】:

  • 好的,我认为这让我走上了正轨。我现在盲目地复制并粘贴了您的代码,但没有理解它,它在正确的位置产生了子弹,但是当我转身时它却在窃听。我认为这将帮助我,通过你所说的和你现在的代码,更好地掌握它。感谢到目前为止。当我有更多了解时会回来报告/接受。
  • 对于我已经提出的建议,这似乎有点过头了 ^^ ...您知道顺便说一句,您只需使用 Vector3.Scale 而不是将组件一一相乘吗?不要重新发明轮子;)
  • @WynDiesel '但是当我转身时它会发出声音' 这听起来像你的子弹是你正在旋转的枪的子对象(它们不应该是父对象)。我的建议是你在你的场景中创建一个空的游戏对象,其中包含所有应该没有父对象的对象(比如你的子弹)。当您实例化对象时,将它们添加到那个空的 GameObject。它使您的场景更干净,应该可以解决您的问题。
  • @derHugo - 缩放不起作用。更仔细地观察 - 它将向量从面对和浮动中相乘。没有可以使用的全局“Facing Vector”。您不能只缩放两个向量 - 它由 3 个向量(上、右、前)组成。如果您只有 1 个,那么您仍然不知道其他 2 个。方法体原本是相当长的几行,直到我得到了简洁的一行解决方案。
  • 感谢您的帮助,@Battle。尽管您的回答和评论确实让我了解了更多,并让我深入了解了 Unity 的向量,但它并没有让我找到答案。问题要容易得多。看来我的精灵的位置没有清零,而是关闭了,这就是为什么它一直在错误的位置绘制
【解决方案2】:

感觉我尝试过的偏移量是 hack

我没有看到任何偏移量......你可以这样做,例如

public float offset = 0.5f;


if (Input.GetAxisRaw("Fire1") > 0)
{
    // add the offset here
    var pos = transform.position + transform.up * offset;
    print(pos.ToString());

    var proj = Instantiate(projectile, pos, Quaternion.identity);

    proj.transform.rotation = transform.rotation;
}

transform.position 在与枪相同的位置生成子弹。我添加了transform.up,因为这似乎是您的玩家正在寻找的方向(在 3D 空间中它会是 transform.forward 但在 2D 中它是 transform.uptransform.right 取决于玩家默认的方向)。 offset 就是您希望子弹在给定方向上放置多远,以米/单位为单位。


如果您希望使用Vector3 偏移量来获得更多控制/调试哪个轴是正确的轴,您可以改用

public Vector3 offset;

//...

var proj = Instantiate(projectile, transform.position, Quaternion.identity);

proj.transform.rotation = transform.rotation;

// Now move it to the offset in local space
proj.transform.Translate(offset, Space.Self);

想将它作为孩子生成...因为如果您之后移动或旋转,您的子弹也会与您一起移动和旋转!

【讨论】:

  • 您能否向我解释一下 transform.up 部分?
  • 至于您将其添加为孩子的编辑。 100% 正确。我看到我的子弹现在神奇地在空中转动。
  • 感谢您对 transform.up 的编辑和解释,这是有道理的。我已将其更改为您的建议,但仍然具有相同的效果,即子弹在玩家左侧产生,在 0,0,0
  • 嗯,你确定没有枪的枢轴点吗?没有其他东西可以控制枪和子弹的位置吗?
  • 我用项目符号本身的代码编辑了帖子。没有其他东西触及子弹
【解决方案3】:

问题是我在子弹上实例化了精灵的偏移量,而不是相对于实际游戏对象的 0,0,0。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多