trying to rotate object both in sinusoidal and circular form along 3 axis
using UnityEngine;
public class time_behaviour : MonoBehaviour
{
float time;
public float rate;
public float x_axis_amplitude;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
time =Time.time;
float x_rotation = x_axis_amplitude*Mathf.Asin(Mathf.Pow(Mathf.Sin(time*rate),2))*Mathf.Rad2Deg;
float y_rotation = 2*(Mathf.Acos(Mathf.Cos(time*rate))*Mathf.Rad2Deg);
transform.localRotation = Quaternion.Euler(x_rotation,y_rotation,0);
Debug.Log(transform.rotation.eulerAngles);
}
}
here is the code
as you can see i am trying to revolve object in sin form along x axis and circularly along y axis
i got desired outcome for x axis but for y axis the rotation keep flipping after 360 degree ,
Is there anyway that after 360 degree it dont flip its motion and rotate forever
I have tried doing transform.Rotate() but it dont rotate uniformly,it just keeps object stationary at that angle
Related
For a school assignment I am trying to make a tank point and shoot game, where I need align the tank to the plane normal using raycasting. But when I do this the Y axis rotaton gets locked and I can't rotate it any more.
The idea is that if a plane is angled, the tank is sticking to it and the transform.up is defined by the plane normal and the tank is able to go up and down the plane and also rotate on it.
This is the code.
public class PlayerController : MonoBehaviour
{
public GameObject player;
public float movementSpeed;
public float rotationSpeed;
RaycastHit hitinfo;
public float hoverHeight = 0.7f;
float offsetdistance;
//public Vector2 moveVal;
public Vector2 moveVal;
public Vector3 Dir;
public float moveSpeed;
//get OnMovie input and put it in a vector to be used later on
void OnMove(InputValue value)
{
moveVal = value.Get<Vector2>();
}
void Update()
{
//moves player
PlayerHover();
player.transform.Translate(new Vector3(0, 0, moveVal.y) * moveSpeed * Time.deltaTime);
player.transform.Rotate(0, moveVal.x * rotationSpeed * Time.deltaTime, 0, Space.Self);
}
void PlayerHover()
{
if (Physics.Raycast(transform.position, -Vector3.up, out hitinfo, 20f))
{
offsetdistance = hoverHeight - hitinfo.distance;
transform.up = hitinfo.normal;
transform.position = new Vector3(transform.position.x, transform.position.y + offsetdistance, transform.position.z);
}
}
You are probably using the wrong overload of transform.Rotate, you should probably be using:
public void Rotate(Vector3 axis, float angle, Space relativeTo = Space.Self);
Where the axis parameter should be the plane normal. Assuming you want to rotate around the plane normal
If you want to set the rotation directly you might need to use SetPositionAndRotation, you should be able to get the quaternion from LookDirection using the plane normal for the forward parameter, but you may need to play around with the axes or apply a 90-degree rotation to get the desired axis to point in the right direction.
In general if you want to rotate an object so that one axis matches up to some other axis you can:
Calculate the angle between the axes, i.e. compute the dot-product and apply the ACos function. Or use any built in methods.
Calculate an orthogonal vector by taking the cross-product between the two vectors
Use this axis and angle in the Rotate function above to produce the desired rotation. Or any other functions that produce a rotation that take an axis and angle.
Use the up-direction of your tank and the plane normal as input axes for the algorithm above if you want to rotate your tank to be orientated to the plane.
I'm working on a game and in this game the trees are 2d , because of this i want them to rotate around the player (i used this script)
{
public Transform target;
void FixedUpdate()
{
transform.LookAt(target);
}
}
but when i get to close to the quad it goes above me so
How can i limit the quad's rotation on X?
Your problem is simply that you can change A to rotate around B.
Method 1: B does not move, and A hangs the script to implement transform's RotateAround(vector3 point, vector3 axis, float angle) function
For example A.RotateAround(B.position, Vector3.up, 30*Time.deltaTime); //A rotates around the y-axis of B.
Method 2: A does not move, A acts as a sub-object of B, and B hangs the script to achieve rotation, and then rotates with A, similar to simulating rotation around the central celestial body.
For example: B.Rotate (Vector3.up, 30*Time.deltaTime, Space.Self); //B rotates around its own up direction, thus rotating with A.
Common methods of rotation:
(1) Rotate around the coordinate axis
public void Rotate (Vector3 eulerAngles, Space relativeTo = Space.Self);
or
public void Rotate (float xAngle, float yAngle, float zAngleSpace, relativeTo = Space.Self);
Where relativeTo = Space.Self means to rotate around its own coordinate system, and ralativeTo = Space.World means to rotate around the world coordinate system.
(2) Rotate a certain vector
public void Rotate(Vector3 axis, float angle, Space relativeTo);
where axis is the direction of the rotation axis, angle is the rotation angle, relativeTo is the reference coordinate system, and the default is Space.self. The function of this method is to rotate the GameObject object by angle degrees around the axis in the relativeTo coordinate system.
(3) Rotate around the pivot point
public void RotateAround(Vector3 point, Vector3 axis, float angel);
The function is to rotate the GameObject by an angle degree around the axis of the point.
I am trying to rotate my gameObject in all axes (x,y,z) with mouse drag function. The gameObject should be rotated smoothly on release. With some adjustments I have achieved to rotate it in y-direction when mouse drags Left-Right. However I am finding it really complicated to rotate in the other 2 axes. Can someone explain how do I achieve this?
using System.Collections.Generic;
using System.Collections;
using UnityEngine.EventSystems;
using UnityEngine;
public class RotateModel : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler {
public float rotationSpeed;
public float rotationDamping;
private float _rotationVelocity;
private float _preRotationVelocity;
private float _preRotationVelocityY;
private float _rotationVelocityY;
private bool _dragged;
public void OnBeginDrag (PointerEventData eventData) {
_dragged = true;
}
public void OnDrag (PointerEventData eventData) {
_preRotationVelocity = eventData.delta.x * rotationSpeed;
_rotationVelocity = Mathf.Clamp (_preRotationVelocity, -8f, 8f);
this.transform.Rotate (Vector3.up, -_rotationVelocity, Space.World);
}
public void OnEndDrag (PointerEventData eventData) {
_dragged = false;
}
private void Update () {
if (!_dragged && !Mathf.Approximately (_rotationVelocity, 0)) {
float deltaVelocity = Mathf.Min (
Mathf.Sign (_rotationVelocity) * Time.deltaTime * rotationDamping,
Mathf.Sign (_rotationVelocity) * _rotationVelocity
);
_rotationVelocity -= deltaVelocity;
this.transform.Rotate (Vector3.up, -_rotationVelocity, Space.World);
}
}
}
There are multiple ways to rotate objects in 3D. So the first step should be to determine what model you want to use. Also consider if you need to allow rotation around all three axes, and if you can provide tools to align rotation to other objects. Another point is if you want to rotate around the objects local axes, or the world axes, or allow switching between the two. Some examples of rotation models:
Separate axes
Use a key or button to determine what axis you should rotate around. This is probably the easiest alternative to implement, just switch Vector3.up for other vectors depending on the pressed key or button.
Rotation widgets
Render 3D circles around your object for each axis you want to rotate around. When the user clicks on the circle you would rotate around that axis. I personally prefer this model, but it might be the most difficult to implement. This blender example shows this style.
Virtual trackball
As the name suggest this essentially simulates a virtual trackball, and allow for rotation in all three dimensions at the same time. This article about 3d rotation explains the functioning, and links to a paper with more details. I personally find that this can be complicated to use, since all axes are affected and you cannot rotate around each axis in turn.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TargetBehaviour : MonoBehaviour
{
// Add this script to Cube(2)
[Header("Add your turret")]
public GameObject Turret;//to get the position in worldspace to which this gameObject will rotate around.
[Header("The axis by which it will rotate around")]
public Vector3 axis;//by which axis it will rotate. x,y or z.
[Header("Angle covered per update")]
public float angle; //or the speed of rotation.
public float upperLimit, lowerLimit, delay;// upperLimit & lowerLimit: heighest & lowest height;
private float height, prevHeight, time;//height:height it is trying to reach(randomly generated); prevHeight:stores last value of height;delay in radomness;
// Update is called once per frame
void Update()
{
//Gets the position of your 'Turret' and rotates this gameObject around it by the 'axis' provided at speed 'angle' in degrees per update
transform.RotateAround(Turret.transform.position, axis, angle);
time += Time.deltaTime;
//Sets value of 'height' randomly within 'upperLimit' & 'lowerLimit' after delay
if (time > delay)
{
prevHeight = height;
height = Random.Range(lowerLimit, upperLimit);
time = 0;
}
//Mathf.Lerp changes height from 'prevHeight' to 'height' gradually (smooth transition)
transform.position = new Vector3(transform.position.x, Mathf.Lerp(prevHeight, height, time), transform.position.z);
}
}
In general it's working the problem is for example if I set the axis x,y,z to 1,1,1 on the variable: axis
And Angle set to 1 Upper limit to 50 Lower limit to 2 and delay to 2.
Then the object is making a circle around the other object but sometimes when the object is getting higher the most he get higher the object making a bigger circle and then when the object is getting lower the circle is smaller.
How can I make it to keep the circle radius static ?
The main goal is to move the object in circles around another object in random highs limits for example 2 and 50 but I want to keep the same radius all the time. Now the radius is changing by depending on the height.
As you are constantly moving the object upwards, if you want the radius of rotation to remain constant then the axis of rotation must veertical ie - Vector3.up or new Vector3(0, 1, 0)
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.