Set Transform.up and rotate at the same time
Hi There!
I am writing a script to orient an object based on the surface below. I do this by using 4 Raycasts to find the Vector opposite of the surface, and then setting Transform.up = to that Vector. This part works, however I also need to be able to rotate the object. Setting Transform.up to a certain vector seems to cancel out any rotation I try to perform. It seems like there should be a very simple work around, but I've spent hours with no success.
void FixedUpdate()
{
Physics.Raycast(Ray_BL.position + Vector3.up, Vector3.down, out hitBL);
Physics.Raycast(Ray_BR.position + Vector3.up, Vector3.down, out hitBR);
Physics.Raycast(Ray_FL.position + Vector3.up, Vector3.down, out hitFL);
Physics.Raycast(Ray_FL.position + Vector3.up, Vector3.down, out hitFR);
upDir = (Vector3.Cross(hitBR.point - Vector3.up, hitBL.point - Vector3.up) +
Vector3.Cross(hitBL.point - Vector3.up, hitFL.point - Vector3.up) +
Vector3.Cross(hitFL.point - Vector3.up, hitFR.point - Vector3.up) +
Vector3.Cross(hitFR.point - Vector3.up, hitBR.point - Vector3.up)
).normalized; //Creates a vector3 pointing directly away from the surface
transform.up = upDir; // Turning doesn't work with this
transform.Rotate (Vector3.up, Time.deltaTime * Input.GetAxis ("Horizontal") * turnspeed, Space.World); //turning
}
Update: I believe to have narrowed down the issue. When I set transform.up = upDir
the y-axis of rotation gets reset to 0. So after rotating around the y-axis using transform.Rotate (Vector3.up, Time.deltaTime * Input.GetAxis ("Horizontal") * turnspeed, Space.World);
, during the next update it is just reset.
Did you ever find an answer to this? I'm running into the same thing. I am trying to set transform.up and rotate around the y axis simultaneously using controller input.
Answer by KingOfDranovis · Feb 07 at 04:13 AM
I'm aware that the original post was made in 2019 but seeing as how there's 240 or so people following this question, and @colinalaws making a much more recent reply, I figured I'd put in what I could.
Using the same sort of setup as the original question, with the 4 raycasts being added together and normalized, I got to the same problem of setting the transform.up stopping rotation. It may not be the absolute best way of doing it, and I used mainly Euler angles so I could understand it better, but here's what I came up with.
float localYRot = transform.localRotation.eulerAngles.y;
transform.up = newUp;
Quaternion newLocalRot = Quaternion.Euler(transform.localRotation.eulerAngles.x, localYRot, transform.localRotation.eulerAngles.z);
transform.localRotation = newLocalRot;
I first grab the current rotation's Y Euler angle, storing that value in a float. I then set the transform.up to be equal to the normalized Vector3 made from the raycasts, which I called "newUp". After the transform.up is set, I grab the new X and Z Euler angles, and instead of using the now reset Y value, use the one I grabbed previously. Then all that's left is to set the localRotation of the transform to the new rotation, which I called "newLocalRot". I personally did the turning in a different part of my script, but it should work wherever because the Y value for rotation now doesn't change when the transform.up does. I hope this helps!
Your answer

Follow this Question
Related Questions
Need help getting randomly moving particles to head to the nearest of 4 coordinates. 1 Answer
Helicopter Move Local Position,Local Position 1 Answer
when trying to rotate, the object transforming itself 0 Answers
Moving GameObject a specific distance in the Z direction and back again - regardless of rotation 1 Answer