How do I correctly calculate the rotation angle so that the object dodges the player? It means that whichever side the player comes from, the object must turn away from the player depending on its direction. I want the effect like in the video but without Joint, only rotation angle:
CodePudding user response:
- calculate the direction Vector from player to the object.
- calculate the axis of rotation by calculating the cross product of the direction Vector and the world up. Doing so creates a vector that is orthogonal to both, which is what we need.
- calculate the angle by how much to rotate. This is done by clamping the distance (magnitude of direction) from 0 to the maximum effect distance and dividing it by the effect distance. Doing so creates a value from 0 to 1. However we need a value from 1 to 0, so there is no effect when the player is far away from the object and the maximum when close. To do so you simply subtract the initial value from 1. By multiplying the result with the max angle we calculate an angle in the range of 0 to maxAngle.
- Finally we calculate the object rotation by multiplying the initial rotation with the rotation around the axis.
[SerializeField] Transform player;
[SerializeField] float effectMaxDistance=1;
[SerializeField] float maxAngle=50;
Quaternion initialRotation;
void Start(){
initialRotation = transfrom.rotation;
}
void Update(){
Vector3 dir = player.position - transform.position;
Vector3 axis = Vector3.Cross(dir, Vector3.up);
float angle = (1-(Mathf.Clamp(dir.magnitude, 0 effectMaxDistance) / effectMaxDistance)) * maxAngle;
transform.rotation = initialRotation * Quaternion.AngleAxis(angle, axis);
}
Note that cross products and Quaternion multiplications are not commutative and need to be done in this exact order!