Hello! I have no idea how to implement this thing:
B is a child of A. When angle between A-rotation and B local position is bigger than some needed angle, rotate vector3 of B-position to A-rotation with fixed angle speed. Picture represents 2d case, but it is a 3d problem.
I’m using A.forward to represent the vector that we want to use as the basis for our angles.
If B is greater than some angle from A.forward, then we get the rotation needed to fully rotate B to match A. Then we figure out what percentage of that rotation our maximum degrees per frame actually is (the scaling factor). Then we scale the full rotation by that scaling factor. Then we apply the rotation to B.
public GameObject a;
public GameObject b;
public float someAngleInDegrees = 15f;
public float degreesPerSecond = 5f;
private void Update()
{
Vector3 aToB = b.transform.position - a.transform.position;
float angleAtoB = Vector3.Angle(a.transform.forward, aToB);
if (angleAtoB > someAngleInDegrees)
{
// Get a rotation that will rotate B all the way to A.forward
Quaternion fullRotation = Quaternion.FromToRotation(aToB, a.transform.forward);
// Scale rotation to be no more than degreesPerSecond per second
float scalingFactor = degreesPerSecond / angleAtoB * Time.smoothDeltaTime;
Quaternion scaledRotation = Quaternion.Slerp(Quaternion.identity, fullRotation, scalingFactor);
// Apply rotation to B
Vector3 newAtoB = scaledRotation * aToB;
b.transform.position = a.transform.position + newAtoB;
}
}
Thanks, it will be very useful, but you you didn’t fully understand me: I need to somehow check the angle between A.transform.rotation and your vector3 aToB. In my scene it works like “if field of view of main camera diverge too much from object B, return object B to field of view”
Sure. You can turn a quaternion into a forward rotation by applying the rotation to Vector3.forward. If you have A.transform.rotation, you can convert that into the forward vector needed to use the above algorithm by rotating Vector3.forward by A.transform.rotation.
In other words, a.transform.forward = a.transform.rotation * Vector3.forward. So, if all that you are given is a quaternion representing a.rotation, you can transform that rotation into the needed vector with a.rotation * Vector3.forward.
Also, transform.forward is shorthand for transform.rotation * Vector3.forward. Similarly for transform.up and transform.right.
If you want to use quaternions to determine the angle between a rotation and the directional vector that points towards B, you can do it like so
// aToB could be replaced with b.transform.localPosition if b is a direct child of A, otherwise
// we would need to do some work to get a directional vector from A to B.
Vector3 aToB = b.transform.position - a.transform.position;
Quaternion bRotation = Quaternion.LookRotation(aToB);
float angleAtoB = Quaternion.Angle(a.transform.rotation, bRotation);
if (angleAtoB > someAngleInDegrees)
{
// Get a rotation that will rotate B all the way to A.forward
Quaternion fullRotation = Quaternion.Inverse(bRotation) * a.transform.rotation;
// Scale rotation to be no more than degreesPerSecond per second
float scalingFactor = degreesPerSecond / angleAtoB * Time.smoothDeltaTime;
Quaternion scaledRotation = Quaternion.Slerp(Quaternion.identity, fullRotation, scalingFactor);
// Apply rotation to B
Vector3 newAtoB = scaledRotation * aToB;
b.transform.position = a.transform.position + newAtoB;
}