Dear CommUnity (funny huh?),
I am trying to make a gameobject which is basically a cube, used as a wall, when destroyed it should be replaced by X amount of pieces that should represent the wall’s breaking.
I made this code:
void OnDestroy()
{
float height = this.transform.localScale.y / 4;
int eachRow = pieces / 4;
float width = this.transform.localScale.z / eachRow;
piecePrefab.transform.localScale = new Vector3(
this.transform.localScale.x,
height,
width);
for (int i = 0; i < 4; i++) // passing between rows
{
for (int k = 0; k < eachRow; k++) // each row
{
Instantiate(piecePrefab,
new Vector3(
transform.localPosition.x,
transform.localPosition.y + height * i,
transform.localPosition.z + width * k
), transform.rotation);
}
}
}
By behavior, i realized that unlike 2D graphics, it takes the position from center of mass (?)
Which makes that code work, but it will teleport a couple of units off the original location.
position has nothing to do with “center of mass” (which is an actual “thing” for rigidbodies http://docs.unity3d.com/ScriptReference/Rigidbody-centerOfMass.html). Position is taken from then “origin” of the model, for a primitive cube that’s the center middle, for a given mesh that is set in the modelling package etc.
Instantiate’s second parameter is in world space, you are passing “local” positions. Try something like
Vector3 offset = //... build you're local position offset into this vector
Instantiate(prefab, transform.position + offset, transform.rotation)
I’ve copied your code from here and put it on a test… I’m not getting quite the same, you appear to be getting an offset on two axis rather than just one.
using UnityEngine;
using System.Collections;
public class Testing : MonoBehaviour
{
public GameObject piecePrefab;
public int pieces;
void OnMouseDown()
{
float height = this.transform.localScale.y / 4;
int eachRow = pieces / 4;
float width = this.transform.localScale.z / eachRow;
piecePrefab.transform.localScale = new Vector3(this.transform.localScale.x,height,width);
for (int i = 0; i < 4; i++) // passing between rows
{
for (int k = 0; k < eachRow; k++) // each row
{
Vector3 offsetVector = new Vector3(0, height * i, width * k);
Instantiate(piecePrefab,
transform.position + offsetVector,
transform.rotation);
}
}
}
}
if the origin of the first object is centre middle you’ll need to compensate for this by adding another offset to account for this initial extra height.
Vector3 offsetVector = new Vector3(0, height * i, width * k);
Vector3 heightOffset = new Vector3(0f, -(1.5f*height), 0f);
Instantiate(piecePrefab,
transform.position + offsetVector + heightOffset,
transform.rotation);
you’d not need that heightOffset if the origin was at the middle bottom of the gameobject, but working with primitives is always “fun”