我有一些对象,我已经从blender 导入,因为我试图制作一个基于 destruct 的游戏,其中一个对象一旦命中将被停用,并替换为它的破碎/可折叠的对应对象.我遇到的问题是,当脚本停用‘Together’对象并激活‘Breaked’对象时,它应该具有完全相同的变换位置.然而,一旦"坏"的物体被激活,它就会处于错误的位置.在Unity中判断对象时,它们位于相同的位置,但对象的变换位置不同:

Sphere cell A transform position

Broken sphere cell A transform position

下面是我的脚本,我取自here,我只是修改了它,当"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 object not in the same position as the together

我try 过的东西:

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

  2. Adding an offset to the 'broken' objects transform position, this would work i think if i fiddled with it enough but i dont think it should even be necessary. 3.I have also review the origins of the objects im using in blender, and it looks like they are identical: together object blender origin broken object blender origin

  3. I have done additional testing using a different 'broken' object than the one in the above example, and this one is activated in the correct location, so it must be something to do with the object itself, however checking on blender i can see that the origin point is the same as the 'together' object (see above images for orgins). enter image description here

推荐答案

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

既然你说网格是从blender 导入的,这似乎是一个网格的"几何起源"的问题.就像我在blender 中设计的这两个立方体一样,一个在中心有原点,另一个在一个顶点.

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 里重置比例.

Csharp相关问答推荐

ASP.NET Core 8 Cors标题未显示

等待限制选项似乎不适用于频道

MongoDB将JS查询转换为C#的问题

并行令牌更新

如何循环遍历XML文档 node 以使用XSLT存储值

如何注册接口类型,类型<>

为什么SignalR在每个Blazor服务器应用程序启动时最多启动8个服务器?

VS 2022 for ASP.NET Core中缺少自定义项模板

为什么此名称不再被识别?名称不存在于当前上下文中?

使用switch 类型模式时出现奇怪的编译器行为

使用动态键从请求体反序列化JSON

如何在mediatr命令中访问HttpContext而不安装弃用的nuget包

ReadOnlyMemory访问基础索引的替代方案

错误:此版本的Visual Studio无法打开以下项目

如何使用实体框架核心对字符串_agg使用强制转换为varchar(Max)

在.Net 8 Visual Studio 2022中启用本机AOT发布时发布失败

使用SQL Server 2022+时,我是否必须将代码从SqlConnection类对象中迁移出来?

获取应用程序版本信息时出现奇怪信息

在使用xUnit和Mock执行单元测试时,控制器ViewResult返回空的Model集合

我想我必须手动使用res1(字符串形式的PowerShell哈希表)