与另一个对象处于相同位置的对象具有不同的转换位置

Object in the same position as another object has a different transform position

提问人:George Rees 提问时间:11/16/2023 最后编辑:George Rees 更新时间:11/16/2023 访问量:54

问:

我有一些从搅拌机导入的对象,因为我试图制作一个基于破坏的游戏,其中一旦被击中的对象将被停用并替换为其损坏/可折叠的对应物。我遇到的问题是,当脚本停用“together”对象并激活“损坏”对象时,它应该具有完全相同的转换位置。然而,一旦“破碎”的物体被激活,它就处于错误的位置。在 Unity 中检查对象时,它们处于相同的位置,但对象的变换位置不同:

Sphere cell A transform position

Broken sphere cell A transform position

下面是我从这里获取的脚本,我只是修改了它,以便当“Snowball”对象命中时,它将触发“一起”和“损坏”对象之间的交换。

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

public class Destruction : MonoBehaviour {

[Header("Game Objects")]
[Space(2)]
[Tooltip("The broken gameObject")]
public GameObject brokenObj; // Set to igloo_broken_a object
[Tooltip("The unbroken gameObject")]
public GameObject togetherObj; // Set to Sphere_cell_A objcet
//private Rigidbody togetherObjRb;

[Space(7)]
[Header("State")]
[Space(2)]
[Tooltip("Whether the object is unbroken")]
public bool together = true;
[Tooltip("Whether the object starts broken")]
public bool startBroken = false;

[Space(7)]
[Header("Breaking on Collision")]
[Space(2)]
[Tooltip("Whether the object breaks when it collides with something")]
public bool breakOnCollision = true;
[Tooltip("The minimum relative velocity to break the object")]
public float velocityToBreak = 1; // Velocity required to break object

[Space(7)]
[Header("Breaking when nothing underneath")]
[Space(2)]
[Tooltip("Whether the object breaks when there's nothing underneath supporting it")]
public bool breakOnNoSupports = false;
[Tooltip("The length of the raycast used to check for supports underneath")]
public float raycastLength = 1f;

[Space(7)]
[Header("Sound On Break")]
[Space(2)]
[Tooltip("Whether the object makes a sound when it breaks")]
public bool soundOnBreak = false;
[Tooltip("An array of sounds for the object to make when it breaks (A random one will be selected)")]
public AudioClip[] clips;

[Space(7)]
[Header("Particles On Break")]
[Space(2)]
[Tooltip("Whether the object makes particles when it breaks")]
public bool particlesOnBreak = false;

//Private vars
private AudioSource src;
private ParticleSystem psys;
   /* [SerializeField] private float offsetX =41.807335f;
[SerializeField] private float offsetY = 10.52f;
[SerializeField] private float offsetZ = 28.67086f;
   */

void Start () {
    //Make sure the right object is active
    togetherObj.SetActive(!startBroken);
    brokenObj.SetActive(startBroken);
    together = !startBroken;
    //togetherObjRb = togetherObj.GetComponent<Rigidbody>();
   // togetherObjRb.useGravity = false;
    if (soundOnBreak)
        SetupSound();
    if (particlesOnBreak)
        SetupParticles();

}

void SetupSound() {
    //Get the audio source or create one
    src = brokenObj.GetComponent<AudioSource>();
    if (src == null)
        src = brokenObj.AddComponent<AudioSource>();

    //Add a random audio clip to it
    src.clip = clips[Random.Range(0, clips.Length-1)];
}

void SetupParticles() {
    // Get the particle system or create one
    psys = brokenObj.GetComponent<ParticleSystem>();
    if (psys == null)
        psys = brokenObj.AddComponent<ParticleSystem>();

    //This doesn't seem to do anything b/c the gameobject is not active
    psys.Stop();
}

void Update () {
    /* Broken object should follow unbroken one to prevent them from
     * being in the wrong place when they switch */
    brokenObj.transform.position = togetherObj.transform.position;
    //brokenObj.transform.position = new Vector3(togetherObj.transform.position.x-offsetX , togetherObj.transform.position.y-offsetY,togetherObj.transform.position.z+offsetZ);
    Debug.Log("Broken transform: "+brokenObj.transform.position);
    Debug.Log("Together transform: "+togetherObj.transform.position);

    //Make sure the right object is active
    togetherObj.SetActive(together);
    brokenObj.SetActive(!together);

    if (breakOnNoSupports)
        CheckForSupports();
}

void CheckForSupports () {
    //Check downwards for supports
    if (!Physics.Raycast(transform.position, Vector3.down, raycastLength))
        Break();
}

void OnCollisionEnter(Collision collision) {
    if (!breakOnCollision)
        return;
    //Only break if relative velocity is high enough
    //if (collision.relativeVelocity.magnitude > velocityToBreak && collision.gameObject.name != "Cylinder" && collision.gameObject.CompareTag("Snowball")){
    if (collision.relativeVelocity.magnitude > velocityToBreak && collision.gameObject.name != "Cylinder"){
        //togetherObj.SetActive(false);
        Break();
    }
   
}

public void Break () {
    together = false;

    //Play the sound
    if (soundOnBreak)
        src.Play();
    //Show particles
    if (particlesOnBreak)
        psys.Play();
}

public void BreakWithExplosiveForce(float force, float radius = 3) {
    Break();

    //Add the explosive force to each rigidbody
    foreach (Rigidbody rigid in brokenObj.GetComponentsInChildren<Rigidbody>())
        rigid.AddExplosionForce(force, transform.position, radius);
}

}

因此,在玩游戏时,脚本由碰撞触发,“broken”对象与“together”对象处于不同的转换位置:

Broken object not in the same position as the together

我尝试过的事情:

  1. 更改场景“工具手柄位置;从中心到枢轴,然后再返回

  2. 在“损坏”对象转换位置添加偏移量,我认为如果我足够摆弄它,这将起作用,但我认为它甚至没有必要。 3.我还回顾了我在 blender 中使用的对象的来源,看起来它们是相同的:together object blender origin broken object blender origin

  3. 我使用与上述示例中的对象不同的“损坏”对象进行了额外的测试,并且这个对象在正确的位置被激活,因此它一定与对象本身有关,但是在Blender上检查我可以看到原点与“在一起”对象相同(参见上图以获取orgins)。enter image description here

C# unity-游戏引擎 blender

评论

0赞 derHugo 11/16/2023
Inspector 中的值是局部位置 => 相对于相应父对象的空间 => 您的对象是否在不同的父对象下?此外,您还选择了 (Geometric) 作为光标位置。你能把它改成吗?CenterPivot

答:

1赞 Priyansh Yadav 11/16/2023 #1

从层次结构窗口中可以清楚地看出,这两个对象要么位于同一父对象的根对象,要么位于同一父对象的子对象,因此由于世界位置或局部位置而出现问题的可能性很小。

既然你说网格是从搅拌机导入的,那么这似乎是网格的“几何起源”问题。就像我在搅拌机中设计了这两个立方体一样,一个在中心有原点,另一个在顶点之一。

Cube with origin at centre

Cube with origin at one of the vertices

因此,当我将它们导入 Unity 时,尽管它们出现在场景中的相同位置,但它们的原点位置是不同的,就像您的情况一样。

通过将中心选项更改为枢轴,您将能够看到模型的真实原点位置。

Position of cube with origin at a vertex

Position of cube with origin at centre

此外,从 Blender 导出模型时,上轴和前轴配置似乎存在一些问题,这从变换线的方向和图像中模型的旋转中可以看出。

顺便说一句,请忽略 100 的比例,我为 UE5 制作一些模型后忘记在 blender 中重置比例。

评论

0赞 George Rees 11/16/2023
感谢您的回复。我刚刚检查了一下,似乎我从 blender 导入的对象似乎具有相同的来源
0赞 Priyansh Yadav 11/16/2023
那么可能是由于旋转不匹配,你看到沿 x 轴有大约 90 度的差异
0赞 George Rees 11/16/2023
不幸的是,更改旋转并没有将其放在与一起对象相同的位置。我开始认为我应该在搅拌机中再次制作损坏的对象并重新导入它们,看看这是否能解决问题。
0赞 George Rees 11/16/2023 #2

该问题是由于 blender 中的对象来源造成的。进入搅拌机,然后按 ALT+G 然后单独导出每个破损的碎片后,对象的中心点被校正。Previous object central point

New central point

现在转换工作正常,它实际上在以下情况下执行了销毁行为:

Destruction in correct location