Search code examples
c#unity-game-enginegame-developmentquaternionsprocedural-generation

Spawning objects parallel to the terrain


Story
so I'm working on making a procedural terrain generator script to spawn rocks on the ground all the big rocks don't care what rotation they are but I have some small rocks that have to be parallel to the terrain or they look weird, part of them floating off the ground other part stuck in the ground the quaternions I don't seem to understand

Problem
i am getting the terrainData.GetInterpolatedNormal and putting it into a vector3 called normals then when i am spawning my rock i rotate it towards ground

Instantiate(SmallRock, new Vector3(point.x, Heights, point.y) transform.rotation = new Quaternion(normals.x,normals.y, normals.z, 90));

my problem lies in the Quaternion(normals.x,normals.y, normals.z, 90) I don't know what to put where like should I only put the normals.x/z there or should I put the normals.y in there too and I don't even know what 90 at the end does, and yes I know that the interpolatednormals returns a 0 to 1 so I tried multiplying it to make it rotate more than 1 but it seems to just not rotate the right way if you can't tell by now I really have no clue how quaternions work but everywhere i search I can't find anything that helps and I didn't really feel like learning about how quaternions work so thanks for saving me time


Solution

  • Quaternions use compound(Imaginary) numbers to represent a sequence of rotations in 3d space.

    When you instantiate a new Quaternion using it's constructor you are providing it with what you think the Quaternion's real and imaginary numbers should be.

    Despite the seemingly familiar x, y, and z names you should not manually modify or provided them, they are not euler angles, cartesian coordinates, or traditional vector components.

    What you're currently passing it is portions of a direction instead of the real and imaginary parts of a Quaternion.

    A normal is an "outwards direction" from a given position. So to get a rotation we need some other direction to compare it to in order to get a rotation.

    Compare your direction with the up direction and you'll get a rotation that you can use.

    Quaternion rotation = Quaternion.FromToRotation(Vector3.up, normalDirection);