#Rotation and flipping
1 messages · Page 1 of 1 (latest)
rename to "quaternions, motherfucker, how do they work!?"
when I turn to go left, Renderer does Flip()
the LookAt object is running the RotationMethod() on Update()
#archived-code-general message
If you're setting the rotation immediately anyway, why not skip storing it as q and just setting it directly onto the transform.rotation?
Not that it fixes things
Wizard on Renderer with the Wizard Head renderer on LookAT
I see what you want now
The GameObject "Renderer" rotates right? and you want to flip the head?
If the head should flip I would use SpriteRenderer.flipX
oh wait yeah i see the problem
🤦♂️
you need to clamp your rotation
https://docs.unity3d.com/ScriptReference/Quaternion.FromToRotation.html
and use this instead of euler
transform.rotation += Quaternion.FromToRotation(transform.rotation, vectorToTarget);
should be something like that without clamping
https://docs.unity3d.com/ScriptReference/Quaternion.AngleAxis.html
you can use this aswell
if you use forward axis then you essentially rotate it exactly like euler in 2d
or if it's easier to imagine, vector is like sticking a pen through the object, then rotating the pen
i think it's using euler on background but i never checked
transform.rotation = Quaternion.FromToRotation(transform.position, vectorToTarget);
this very much doesn't work lol
why are you using position
So what is it that you're trying to do?
errors out using rotation
ah right
flip everything when moving left/right
and have an object follow and look at enemy
it needs to be transform.forward then
Flip what? The head? or the entire object?
just = instead of +=?
I don't think so
head, firepoint(where bullets shoot from) gun also, maybe future things, not sure
ahh shit i don't wanna open VS
Ah okay
otherwise I would just flip sprite renderer
So you're basically trying to modify the x value right?
I flip Y rotation by 180 degrees to essentially flip everything
try to split it up?
then just want to change Z to look at enemy
transform.localRotation = Quaternion.Euler(0, transform.localRotation.y + 180, 0);
You need to use localRotation if the parent is rotated
I think
anyways
the vector screws it up a little
you only need to rotate one side
flipping doesn't counter the rotation and that's why it doesn't work
What do you mean?
so if I want my player thats holding a gun to have both flip to opposite side of player when moving right vs left
what would you change so I don't have to use 180 degrees Y rotation
localRotation does fix the head issue...but now when its "flipped left" it no longer points at the enemy 😦
then you need to compare position of target, whether it's on the left or right
i'm trying to think of solution but it's really counter-intuitive
i guess the way i'd do it is dotproduct of where you're facing and just set head to neutral position instead of trying to rotate
if you're facing left, then you don't really even care about looking at whatever is behind you(right)
while thats true, I'm going to eventually make it so once they find a target they don't stop looking at it until they break line of sight
and if they jump over enemy or enemy them, it needs to swap looking directions
hmm
I think i've got solution though
yeah
for real
I think technically it doesn't matter. For 2D you could just rotate it 90 degrees afterwards
I can't see what is going on tho and I am quite confused now lol
I think you right
i can try to explain lol
if you are facing left and you're targeting left, everything is fine
but if target is on the right, your head flips upside down
while the intended result is that if target is on the right, sprite is flipped and rotation is essentially absolute
although now that i think of it,
since sprite is 2-sided then 3d rotation might've worked too
Definitely
LookAt with world up?
public class LookAtRotation : MonoBehaviour
{
// Update is called once per frame
[SerializeField] Transform target;
[SerializeField] Mover parent;
Quaternion q;
bool left;
void Update()
{
RotationMethod();
}
protected virtual void RotationMethod()
{
if (target == null) return;
//Create a vector to the target
Vector3 vectorToTarget = target.position - transform.position;
//Convert this to an angle
float angle = Mathf.Atan2(vectorToTarget.y, vectorToTarget.x) * Mathf.Rad2Deg;
//Rotate around axis
left = parent.IsFacingLeft();
if (left)
{
q = Quaternion.Euler(0f, 0f, angle + 180f);
}
else
{
q = Quaternion.Euler(0f, 0f, angle);
}
//Instant rotate
//transform.rotation += Quaternion.FromToRotation(transform.forward, vectorToTarget);
transform.localRotation = q;
}
}
finally got it working
thanks everyone 🙂
Okay
if you could store the first transform and not exectute to do something like this I think it would work
but as is I think 3d lookat for 2d just sucks lol
I would do it differently
I would take the transform.LookAt(target) and rotate 90° around the local y-axis
it changes the X and Y for lookat
the X rotation is the value you should use for Z funny enough lol
Hence the "around the local y-axis"
endRot = Quaternion.AngleAxis(90, transform.up) * transform.localRotation.eulerAngles;
Something like that
To rotate it
endRot is a Vector3
So the end product would be something like:
transform.LookAt(target);
transform.localRotation = Quaternion.Euler(Quaternion.AngleAxis(90, transform.up) * transform.localRotation.eulerAngles);```
lookat already rotates, why are you rotating it the second time?
Because it faces the side to the camera in 2D
So it is invisible
You have to rotate it 90°
Since forward is into the screen
And LookAt() sets the forward towards the target
oh right, forward is z in 3d but x in 2d
2nd rotation is a weird workaround though
I don't think so
It's easy and pretty fast
easy and fast is the best way to make bad code
Tell me a single reason why it is a "weird workaround"
is it not?
Why would it be?
you're performing 2 similar operations instead of 1
it's fine with 1 character but it's something done in update and potentially dozens of enemies
The alternative is to do the LookAt manually which makes reading it wayy harder
might be too tiny of an optimization but it still kinda sucks
It's not worth remaking the LookAt method
either way it's fine
Which is the alternative
all that really matters is that the abstraction is there
I'm sorry, but what does "abstraction" mean?
void HeadLooksAtTarget(target)
the rest can be rewritten later
I don't get why you would spend a lot of time fixing something that means next to nothing. If you keep doing that, you will be stuck in the project forever without getting anywhere
That's the reason to 50% of my failed projects
does that mean you finished first project and got stuck forever in 2nd?
No, I lost interest in the project becasue I got nowhere
that's why i don't like goal-oriented people
if you do one method right, you can reuse it later
These are a few of my projects. Many of them got lost because I lost motivation
Nah
You know nothing about me
I have made probably more than 100 projects with the sole purpose of learning a single thing
i can tell you how i don't lose motivation on projects
i just lose motivation on boring parts of the projects, instead of the entire project
that means i can still return back to it later
Like A* Pathfinding, or boids, or chess AI, or evolution simulation, ray marchin, etc.
but the project will progress
That's cool
If I get nowhere I will lose all motivation. As long as I am going at a steady pace everything is good
Then I clean up at the end
It's not a bad thing to make code that can be used for future projects though
I have used the A* pathfinding library I made lots of times, fx. in my latest prject where I made a hexagonal grid. I am sure that there is a "proper" way to make a hexagon grid, but the solution I came up with I can use for any project that requires such a grid
And the A* is versatile to work with any grid
Stuff like that I optimize
Other stuff that is specific to the project I don't really care about
Waste of time
i don't like leaving something half-assed because i might end up reusing it later, and seeing it again will destroy motivation and the momentum since i'll probably start reworking that instead