我有一些对象,我已经从blender 导入,因为我试图制作一个基于 destruct 的游戏,其中一个对象一旦命中将被停用,并替换为它的破碎/可折叠的对应对象.我遇到的问题是,当脚本停用‘Together’对象并激活‘Breaked’对象时,它应该具有完全相同的变换位置.然而,一旦"坏"的物体被激活,它就会处于错误的位置.在Unity中判断对象时,它们位于相同的位置,但对象的变换位置不同:
下面是我的脚本,我取自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);
}
}
因此,当玩游戏时,脚本由碰撞触发,"破碎"对象与"在一起"对象不在同一变换位置:
我try 过的东西:
-
更改场景的工具手柄位置;从中心到枢轴,然后再回来
-
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:
-
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).