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

问题描述 投票:0回答:1

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

下面是我从here获取的脚本,我只是修改了它,以便当“雪球”对象击中它时,它会触发“在一起”和破碎的对象之间的交换。

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);
}

}

因此,在玩游戏时并且脚本是由碰撞触发的,“破碎”对象与“在一起”对象的变换位置不同:

我尝试过的事情:

  1. 更改场景“工具手柄位置”;从中心到枢轴,然后再返回
  2. 向“损坏的”对象变换位置添加偏移量,我认为如果我对它进行足够的摆弄,这会起作用,但我认为这甚至没有必要。
c# unity-game-engine blender
1个回答
0
投票

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

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

所以,当我将它们导入Unity时,虽然它们出现在场景中的相同位置,但它们的原点位置不同,就像你的情况一样。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.