Scatter object on other object's vertices' Vector3

My goal is to shatter an object over the vertices of another object. My script:

using UnityEngine;
using System.Collections;

public class Verteilen : MonoBehaviour {
    public Transform zuVerteilen;
    public Transform worauf;
    // Use this for initialization
    void Start () {
        Mesh mesh = worauf.GetComponent<MeshFilter>().mesh;
        Vector3[] vertices = mesh.vertices;
        int i = 0;
        Debug.Log(vertices.Length);
        float verg = worauf.transform.localScale.x;
        for(int o = 0; o<vertices.Length;o = o + 1)
        {
            //Debug.Log(vertices[o].x * verg);
            Instantiate(zuVerteilen, new Vector3(vertices[o].x* verg+worauf.position.x, vertices[o].y* verg + worauf.position.y, vertices[o].z* verg + worauf.position.z), Quaternion.identity);
        }
    }

    // Update is called once per frame
    void Update()
    {

    }
}

But those objects are always out of place, no matter if I use

vertices[o].x* verg+worauf.position.x, vertices[o].y* verg + worauf.position.y, vertices[o].z* verg + worauf.position.z
vertices[o].x* verg, vertices[o].y* verg, vertices[o].z* verg

or

vertices[o].x, vertices[o].y, vertices[o].z

What to change?

Is the original object rotated?? Unless the original object’s rotation is Quaternion.identity, you will be out of place as you are only taking into account the x-scale.

You are also using the x-scale for all x,y,z, which may be okay.

If you have a Vector3 v and want to rotate it (around 0,0,0) by the GameObject’s rotation, this should do it:

Vector3 yourCalculatedRotation ... do all the things you do above...
Vector3 rotatedPosition = worauf.rotation * yourCalculatedRotation;

If you want to rotate around another point in space, you have to first adjust the position by that point’s location, and then put your point back.

Thank you.

The original object is rotated.

To be honest, I did not understand you properly but I changed it to this:

using UnityEngine;
using System.Collections;

public class Verteilen : MonoBehaviour {
    public Transform zuVerteilen;
    public Transform worauf;
    void Start () {
        Quaternion original = worauf.transform.rotation;
        Mesh mesh = worauf.GetComponent<MeshFilter>().mesh;
        Vector3[] vertices = mesh.vertices;
        Debug.Log(vertices.Length);
        float verg = worauf.transform.localScale.x;
        for(int o = 0; o<vertices.Length;o = o + 1)
        {
            //Instantiate(zuVerteilen, new Vector3(vertices[o].x* verg+worauf.position.x, vertices[o].y* verg + worauf.position.y, vertices[o].z* verg + worauf.position.z), original);
            //Instantiate(zuVerteilen, new Vector3(vertices[o].x, vertices[o].y, vertices[o].z), original);
            Instantiate(zuVerteilen, new Vector3(vertices[o].x* verg, vertices[o].y* verg, vertices[o].z* verg), original);
        }
        mesh.RecalculateBounds();
    }
   
    void Update()
    {

    }
}

The only thing that seems to be missing now is rotation, even though I used the original quaternion. What now?

Yes, technically you USED it, but that was just to rotate the entire object, not its initial position.

Think of it this way: you need to rotate the actual root position of it with regards to the original object’s position. Imagine if one of the verts was the tip of my right hand and my arm was sticking out to the right. If I was leaning to the right 20 degrees, the actual position in space of that object would be lower. If I was turning 20 degrees to the left, the object at the tip of my finger would be “more forward.”

The final code you want will be more like this:

Instantiate(zuVerteilen, original * new Vector3(vertices[o].x* verg, vertices[o].y* verg, vertices[o].z* verg), original);

Note the extra “original *” operation at the beginning, but this will ONLY work if the original object is centered at (0,0,0)

Otherwise you will have to subtract its position, do the rotation, and add its position back in, as I indicated in the first post.

Hope this helps!

Finally, here for everyone to reuse

using UnityEngine;
using System.Collections;

public class Verteilen : MonoBehaviour {
    public GameObject zuVerteilen;
    public Transform worauf;
    void Start () {
        Quaternion original = worauf.transform.rotation;
        Vector3 drehung = original.eulerAngles;
        Mesh mesh = worauf.GetComponent<MeshFilter>().mesh;
        Vector3[] vertices = mesh.vertices;
        float verg = worauf.transform.localScale.x;
        for(int o = 0; o<vertices.Length;o = o + 1)
        {
            Instantiate(zuVerteilen, original * new Vector3((vertices[o].x * verg) - worauf.transform.position.x, (vertices[o].y * verg) - worauf.transform.position.y, (vertices[o].z * verg) - worauf.transform.position.z), original);
        }
        mesh.RecalculateBounds();
    }
  
    void Update()
    {

    }
}

How would I rotate the scattered objects to be flat on the surface if possible? I did

GameObject go = GameObject.Instantiate(zuVerteilen, original * new Vector3((vertices[o].x * verg) - worauf.transform.position.x, (vertices[o].y * verg) - worauf.transform.position.y, (vertices[o].z * verg) - worauf.transform.position.z), original) as GameObject;
Vector3 temp = new Vector3(go.transform.position.x, go.transform.position.y + hoeher, go.transform.position.z);
go.transform.position = temp;
go.transform.eulerAngles = new Vector3(Mathf.Asin(vertices[o].normalized.z / 1),0,Mathf.Atan2(vertices[o].normalized.y, vertices[o].normalized.x));

Idea was that probably vertices[o].normalized is the vector that is perpendicular to the vertex in regards to which triangle it belongs to. So it points to the perpendicular direction. So I have to calculate the x,y and z into spherical coordinates to get angles and feed eulerangels with it, later compensating the 90° so it’s flat. Did not really work.

hoeher is an offset for y.

vertices[o].normalized is just the unit vector in the direction of the given vector (from zero).

The normal at a vector point is (in Unity) contained in a corresponding Vector3 array called .normals that you can calculate a variety of ways, depending on smoothing or not. If an edge is not smoothed, then it is actually two separate vertices each with their own normal, and each involved in their own faces on either side.