When i spawn a new objects, one of his connectors should match the position of the old object’s connector and its forward Z direction should be opposite of the old connector.
The problem is that it only matches the Z direction so the attached object sometimes results in a not wanted rotation
This is the code, i tried doing the same thing with transform.right dir but sometimes rotates the object 180 degrees to match the transform.right axes. Someone knows how to fix this?
Are the parent and child supposed to be rotated the same? As in parent rotation matches other parent, then child is just no rotation?
I was trying to work this out as a test, but wasn’t 100% confident that I understood your criteria
I’m not sure if i understand correctly, but i never touch connector (child) rotation, i rotate and translate the whole object (childs included). The connector is an empty game object with its forward pointing out in the direction another object should be attached to.
With node you mean the empty child right?
You mean object.transform.forward = -oldNode.transform.forward maybe?
Because your code rotates the node and not the parent object which is what i need to rotate.
If that’s what you mean then it’s not gonna work, because the parent rotation doesn’t match the connector’s rotation. The object’s forward doesn’t necessarily match the child’s forward.
If you scroll down there’s this image which visualize what i need to do. I couldn’t make the MatchExits() function of the guide work for my case specifically, not sure why though :\
There’s a little bit of confusion, for me, in that your first answer said you never rotate the child object you just rotate the parent, and then you said the object’s rotation doesn’t necessarily match the child’s…
Ya, okay… No problem about the language. You’re doing pretty well
Just that one confusion part, but then you cleaned it up, by repeating what I thought you had said 2 posts ago.
Edit: So, when I re-tested this, it isn’t working well lol. It will only work if the parent rotations are none, to begin with. That can’t be that useful. Oh well… was fun to try.
Hmm… So, I’m going to probably give up on this now. It was fun to try to figure it out lol
Seems simple, but… obviously not so much for me
If you only rotate on the y-axis, I think maybe this will work:
where ‘cube1’ is the old’ and ‘transform’, the new…
This is working for me, if the old cube is rotated only on the y, and its child can be rotated on its own local y, too.
The new one (transform) child can be rotated on the y, also.
1 last update/answer lol.
Okay, now I found something that works, except if the z axis of rotation has been modified, then things are a little off for the position, but I believe the forward still matches the -forward of the child object… oh boy
I’m joining this thread a little late but I thought I would chime in because I actually downloaded that tutorial’s repo last month and checked it out.
I got it working and I think it’s pretty spiffy what he did. I then tried to extend it with some of my own pieces and here is some things to note: the main takeaways from his “3d-procedural-dungeon” scene and extending it is this:
Make each of your own piece examples have NO rotation and NO scaling in their root transform
Make each connecting point an immediate child to that root node.
Now, from there, you can go and put any other geometry you want any other way you want to on separate sub-GameObjects. underneath your root object.
Good luck with procedural stuff! It’s my personal favorite area of game engineering.
Hey thanks for the reply, unfortunately i don’t think his algo would work for my case.
He does:
newPiece = RotateAround(child2.position, Vector3.up, correctiveRotation);
But my map has also pieces that need to be attached vertically and that does not allow it since it only rotates around global Y axis, it cannot rotate a piece so it connects to a connector pointing up or down.
It turns out my previous solution was actually working properly, there’s only a problem when the new child’s forward is exactly like the forward of the old child because the function:
Quaternion rotZ = Quaternion.FromToRotation(newChild.transform.forward, -oldChild.transform.forward);
Can produce two different rotations if the rotation between the directions is exactly 180 degrees.
The solution is to check if the forwards of the two childs are the same (which means the rotation between them is 180°) then rotate the object slightly on the right axis of the child.
Then do the same thing with the right axis of the child, though this time check if the right of the first child is equal to the negated right of the second child, because we want the two children to have opposite forwards but the same rights. Then rotate on the child’s forward axis slightly.
Hello from the future I approached the problem from a different perspective and here’s the solution I came up with:
We want a situation where both “connection points” have the same position and the same rotation in world space. This means that the position and rotation of the “new chunk” in local spaces of both connection points needs to be the same.
As counterintuitive as it may seem, I took the new chunks “forward”, “up” and “position” and did InverseTransformDirction and InverseTransformPoint to get those values in the “child connection point local space”. Then you take those local values and do TransformDirection and TransformPosition on the other connection point to get “world space” values.
Then you simply move the chunk to the given position and set the rotation to Quaternion.LookDirection(worldForward, worldUp).
Since the chunk position and rotation in the child connection point local space didn’t change (the point moved with the chunk) and now the chunk has the same local position and rotation in the other connection point local space - both local points end up in the same position and with the same rotation in world space
var localForward = childPoint.transform.InverseTransformDirection(chunk.transform.forward);
var localUp = childPoint.transform.InverseTransformDirection(chunk.transform.up);
var localPosition = childPoint.transform.InverseTransformPoint(chunk.transform.position);
var worldForward = connectionPoint.transform.TransformDirection(localForward);
var worldUp = connectionPoint.transform.TransformDirection(localUp);
var worldPosition = connectionPoint.transform.TransformPoint(localPosition);
chunk.transform.position = worldPosition;
chunk.transform.rotation = Quaternion.LookRotation(worldForward, worldUp);
This code worked like a charm! If the connection points were to point in the same direction (like mine did) I just changed -oldChild.forward to oldChild.forward.
The code posted by VinylPixels however did not work
VinylPixels code its working but for turn and direction repeat. It works correctly if the directions are different. And the naming is confusing, of course. The version of the code that works correctly for points with symmetric direction looking away from the object.
Renamed/ and support cross spots directions example:
var rightConnectorRotConj = math.conjugate(quaternion.LookRotation(-rightConnector.transform.forward, rightConnector.transform.up));
var localForward = math.rotate(rightConnectorRotConj, rightParent.transform.forward);
var localUp = math.rotate(rightConnectorRotConj, rightParent.transform.up);
var localPosition = math.rotate(rightConnectorRotConj, rightParent.transform.position - rightConnector.transform.position) / rightConnector.transform.localScale;
var worldForward = leftConnector.transform.TransformDirection(localForward);
var worldUp = leftConnector.transform.TransformDirection(localUp);
var worldPosition = leftConnector.transform.TransformPoint(localPosition);
rightParent.transform.position = worldPosition;
rightParent.transform.rotation = Quaternion.LookRotation(worldForward, worldUp);