Why turnSpeedMouse error? - c#

Why is this code doesn't work? I fixed the quotes, but I get an error message in the console:
Te script from here: https://medium.com/#verochan/how-to-make-a-360%C2%BA-image-viewer-with-unity3d-b1aa9f99cabb
How can I fix this?
Thank you very much in advance!
float horizontal;
float vertical;
Transform container;
void LateUpdate ()
{
//Using mouse
horizontal = Input.GetAxis(“Mouse X”);
vertical= Input.GetAxis(“Mouse Y”);
//This is made in order to avoid rotation on Z, just by typing 0 on Zcoord isn’t enough
//so the container is rotated around Y and the camera around X separately
container.Rotate(new Vector3(0, horizontal*(-1), 0f)*Time.deltaTime*turnSpeedMouse);
transform.Rotate(new Vector3(vertical, 0, 0)*Time.deltaTime*turnSpeedMouse);
}

The tutorial forgot to declare the turnSpeedMouse variable and this is very likely a float.
public float turnSpeedMouse = 50f;
The whole code should look like this:
public float turnSpeedMouse = 50f;
float horizontal;
float vertical;
Transform container;
void LateUpdate ()
{
//Using mouse
horizontal = Input.GetAxis(“Mouse X”);
vertical= Input.GetAxis(“Mouse Y”);
//This is made in order to avoid rotation on Z, just by typing 0 on Zcoord isn’t enough
//so the container is rotated around Y and the camera around X separately
container.Rotate(new Vector3(0, horizontal*(-1), 0f)*Time.deltaTime*turnSpeedMouse);
transform.Rotate(new Vector3(vertical, 0, 0)*Time.deltaTime*turnSpeedMouse);
}

Related

Unity messes up X-axis rotation

I have a very simple script that I wish to rotate something on the X-axis, and I'd expect the other two axes to stay put(they flip between 0 and 180), and only X to change.
Below you can see the code intended to do just that.
public class TestScript : MonoBehaviour
{
private void Start()
{
transform.eulerAngles = Vector3.zero;
Debug.Log($"start rotation: {transform.eulerAngles}");
}
private void Update()
{
float time = (Time.time - 1f) * 10f;
if (time < 0f || time > 1f)
{
return;
}
Vector3 rotation = transform.eulerAngles;
float x = Mathf.Lerp(170f, 0, time);
rotation.x = x;
transform.eulerAngles = rotation;
Debug.Log($"rotation: {transform.eulerAngles}, x: {x}");
}
}
The output from the console. You can clearly see that the rotation does not go from 170 to 0, but from 0 to 90 and then back to 0.
Now, I'm pretty sure this has something to do with quaternions and their identity, but not sure how can this be avoided
PS: The same idea but for Y and Z works just fine.
OP:
I have a very simple script that I wish to rotate something on the X-axis, and I'd expect the other two axes to stay put(they flip between 0 and 180), and only X to change.
You can clearly see that the rotation does not go from 170 to 0, but from 0 to 90 and then back to 0. Now, I'm pretty sure this has something to do with quaternions
Well the real culprit is Euler angles.
If we take a look at your code:
Vector3 rotation = transform.eulerAngles;
float x = Mathf.Lerp(170f, 0, time);
rotation.x = x;
transform.eulerAngles = rotation;
Debug.Log($"rotation: {transform.eulerAngles}, x: {x}");
...we can see you are performing rotations via transform.eulerAngles. The thing about 3D rotations is that you should avoid using Euler due to their limitations and problems (gimbal lock anyone) and use quaternions instead. The latter is the source of truth.
Unity (my emphasis):
When you read the .eulerAngles property, Unity converts the Quaternion's internal representation of the rotation to Euler angles. Because, there is more than one way to represent any given rotation using Euler angles, the values you read back out may be quite different from the values you assigned. This can cause confusion if you are trying to gradually increment the values to produce animation.
...which is exactly what is happening with your code.
Consider this:
Notice anything about the 23.5 and the 156.5?
23.5 + 156.5 = 180
In other words both will lead to the same rotation as per "there is more than one way to represent any given rotation".
An arguable simpler approach is:
public class RotateWithTime : MonoBehaviour
{
[SerializeField,Tooltip("Rotation rate in degrees/second")]
private Vector3 rotationSpeed; // e.g. (30,0,0) for 30 deg/sec X-only
private void Reset()
{
rotationSpeed = Vector3.zero;
}
// Update is called once per frame
void Update()
{
var amount = rotationSpeed * Time.deltaTime;
transform.Rotate(amount);
}
}
And a version without Vector3s:
public class RotateWithTimeNoV3 : MonoBehaviour
{
[SerializeField,Tooltip("Rotation rate in degrees/second")]
private float rotationSpeedX; // e.g. 30 for 30 deg/sec X-only
private void Reset()
{
rotationSpeedX = 0f;
}
// Update is called once per frame
void Update()
{
var amount = rotationSpeedX * Time.deltaTime;
transform.Rotate(amount, 0f, 0f);
}
}
In order to avoid this question becoming a chameleon question due to the lack of info in the initial question, I have asked a new one and will be closing this one. You can find it here

My characters won't strafe or move left to right

I even checked my project settings about horizontal and vertical. It is correct and it is set to WASD, but my character wont move or strafe from left to right.
I put my character set to animation though like he just walk straight with a lil curve here and there but that wont conflict with this script right?
public class Player : MonoBehaviour {
[SerializeField] float controlSpeed = 10f;
void Update()
{
float horizontalThrow = Input.GetAxis("Horizontal");
float VerticalThrow = Input.GetAxis("Vertical");
Debug.Log(horizontalThrow);
Debug.Log(VerticalThrow);
float xoffSet = horizontalThrow * Time.deltaTime * controlSpeed;
float newXpos = transform.localPosition.x + xoffSet;
transform.localPosition = new Vector3(newXpos, transform.localPosition.y, transform.localPosition.z);
}
}
try
transform.localPosition += new Vector3(xoffSet, transform.localPosition.y, transform.localPosition.z);, that is just adding the offset directly to the existing position of your player instead of computing the final value with newXPos. that seems a bit unnecessary.
Also, In your animator component on the player, make sure Apply Root Motion is not checked. applying root motion on an animator whilst trying to also move it externally generally causes issues like these, because their positions are being overridden by each other, causing conflict.

Unity ScreenToWorldPoint returning behind camera

In unity, I am using ScreenToWorldPoint to move my object with my mouse, but the DrawRay from my transform to the ScreenPoint returns behind my camera for some reason. I've tried testing and finding out the reason but I just have no idea; here is my code:
using UnityEngine;
using System.Collections;
public class ScreenToWorldPointTest : MonoBehaviour {
public GameObject obj;
public Vector3 objDist;
public Vector3 objDistFwd;
public float moveSpeed = .1f;
void Start() {
obj = GameObject.Find("ChessKnightWhite");
}
void Update() {
Vector3 objPos = obj.transform.position;
objDist = objPos - transform.position;
objDistFwd = new Vector3(objDist.x * transform.forward.x, objDist.y * transform.forward.y, objDist.z * transform.forward.z);
Vector3 screenPoint = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, objDistFwd.magnitude)
Vector3 move = Vector3.lerp(screenPoint, transform.position, moveSpeed);
Debug.DrawRay(transform.position, screenPoint, Color.Green);
if(Input.GetMouseButton(0)) {
obj.transform.position = move - new Vector3(0, .5f, 0);
}
}
}
and usually, this works fine; the ray ends at the object (well, not at the object if it's being moved, but if it (the mouse) is still it would be at the object) and the object moves whenever and wherever I want it to, keeping the same distance from me (forwardly, where it's not the same distance but, say, the transform is normal (0, 0, 1), it will stay at 1 on the z-axis). But sometimes (observed at camera/player is at 0, 15, -10 -- with a rotation of 60 on the x -- and the object is at 0, 1, 0) the ray is behind me! and what's even weirder, is instead of going to where the Ray ends, it stays a little bit in front of the camera?! I thought, "maybe the z on ScreenToWorldPoint is negative?", but it cant be, because the x, z, and y are squared and added together to get magnitude. and printing it out even confirms this, but for some reason, it changes when I move the mouse sometimes. I have no idea what's causing this, so any insight would be very helpful (please also, if you can, include an explanation or any information as to why this might happen).
so after a while I realized that Pluto was right, I needed to use dot product instead of the magnitude of (xa * xb, ya * yb, za * zb). Sorry Pluto, thanks for your help and your patience with me

Unity2D: Have multiple objects rotate around the SAME center but starting from offset positions

I want my three floating 2D platforms in my game to rotate around the SAME center. I have achieved this as so:
public GameObject Object;
public float RotateSpeed;
public float Radius;
private Vector2 _centre;
private float _angle;
private void Start()
{
_centre = transform.position;
}
private void Update()
{
_angle += RotateSpeed * Time.deltaTime;
var offset = new Vector2(Mathf.Sin(_angle), Mathf.Cos(_angle)) * Radius;
Object.transform.position = _centre + offset;
}
It works just fine, however - only for ONE plattform. If I add more platforms to the mix, they either all start from the same position in within our imaginary circle around the center OR, if I offset them, they all rotate with a different center (if the offset is x=2, then the center also is offset by 2). How do I make say 3 plattforms circle around the same center but starting on 3 different starting points ON the circle? (Like 0°, 180°, 270°) or so? (Currently, all 3 start at 0)
Thank you
EDIT:
This is how I would like ti to rotate. The 4 rectangles are the plattforms. They all are to rotate around the imaginary center. They are all the same speed so the never get closer to one another. Also, they all stay upright. The blue lines and red lines are also imaginary. There is no object in the center. Hope this helps
Define the variable: private float _angle; as public: public float _angle;.
After this, go to the inspector by clicking on the object the script is attached to and look for a variable named "angle". Change this variable to different angles for each platform.
It is because the Vector2 _centre is being instantiated as the initial position of the object, try to get the transform of a pivot instead of getting the transform of the object itself
public float RotateSpeed;
public float Radius;
public Transform _centre; // in the inspector input the pivot transform
public float _angle; // set it in the inspector
// private float _angle; use this with the code in the start method
private void Start()
{
/*
_angle = Mathf.asin((pivot.position.x - transform.position.x)/Radius);
*/
}
private void Update()
{
_angle += RotateSpeed * Time.deltaTime;
var offset = new Vector2(Mathf.Sin(_angle) * Radius, Mathf.Cos(_angle)) * Radius;
transform.position = _centre + offset;
}
Make sure to place your platform in a coherent position around the pivot of rotation.

Untiy Make an object rotate along axis its moving on

I want to make an object (let's say a cube), rotate at a steady rate on the same axis that's it's moving on. So if it changes direction from X to Z then the rotation would lerp from X axis into the Z axis and then continue rotating on Z axis.
How would I achieve this? Here's what I have at the moment, the cube just rotates on the z axis back and forth within a certain degrees.
public float Angle;
public float Period;
void Update()
{
Animate();
}
void Animate()
{
_time = _time + Time.deltaTime;
float phase = Mathf.Sin(_time / Period);
transform.localRotation = Quaternion.Euler(new Vector3(0f, 0f, phase * Angle));
}
Just use
RotateAround
Note generally NEVER use Quaternion for any reason.
there are 1000s of questions on using RotateAround so just google. In your case it sounds like you'll be changing (lerping, whatever) the axis of rotation itself.

Categories

Resources