#c# #unity3d
#c# #unity3d
Вопрос:
По сути, я использую систему Ik в Unity, и я хочу, чтобы мой пистолет был нацелен на мышь. Проблема в том, что я могу контролировать только положение кости IK, из которой не вылетит пуля, есть объект Gun, который является дочерним элементом кости IK, и он вращается вместе с ним. Что я хочу сделать, так это расположить IK таким образом, чтобы точка огня (где вылетит пуля) всегда была повернута к мыши.
Вот изображение, чтобы лучше визуализировать проблему
Комментарии:
1. У вас есть gameobject или что-нибудь в
firePoint
? Из диаграммы видно, что есть один atfirePoint
с его локальным правым (красная ось), указывающим из пистолета. Это правильно?2. Да, игровой объект называется firePoint, но я не могу контролировать его положение, только ik-кость. и это дочерний элемент пистолета.
3. И, просто чтобы подтвердить — правильное направление указывает на направление стрельбы? Это очень необычно для 3D-игры, и вопрос на самом деле не указывает, является ли это 2d или 3d-игрой.
4. Да, он находится в 2D, и его правильное направление вращается вместе с пистолетом. и пистолет сам вращается в зависимости от ik.
5. Итак, если пистолет направлен влево — он все равно стреляет в локальном правильном направлении? Добавляю ответ сейчас.
Ответ №1:
Объяснение в комментариях
// currentFirePoint and currentIKPoint are the transform of the fire Point and the
// world position of IK Point at some given moment.
// aimOrign and mousePosInWorldSpace are world space positions of the aim Origin and
// mouse position that produce the desired IK point.
Vector3 GetNewIKPoint(Transform currentFirePoint, Vector3 currentIKPoint,
Vector3 aimOrigin, Vector3 mousePosInWorldSpace)
{
float firePointRange = aimOriginToCurrentFP.magnitude;
//Find the local position of IK in Fire Point space
Vector3 curFirePointToIK = currentIKPoint - currentFirePoint;
Vector3 localFirePointToIK = currentFirePoint.InverseTransformVector(
curFirePointToIK);
// Stuff above this point could be done once and cached,
// assuming things like the offset or fire point range don't change.
// Determine where the new fire point will be
Vector3 newFireDirection = (mousePosInWorldSpace - aimOrigin).normalized;
Vector3 newFirePoint = firePointRange * newFireDirection;
// Find rotation such that local right = newFireDirection
// and local up is closer to Vector3.up than Vector3.down
// find local forward
Vector3 newFPLocalForward = Vector3.Cross(newFireDirection, Vector3.up);
// find local up
Vector3 newFPLocalUp = Vector3.Cross(newFPLocalForward, newFireDirection);
Quaternion newFPRotation = Quaternion.LookRotation(newFPLocalForward,
newFPLocalUp);
// Apply that rotation to the local position of IK to find the world space offset.
Vector3 newFirePointToIK = newFPRotation * localFirePointToIK;
// Add to fire point to get world space position
return newFirePoint newFirePointToIK;
}
Эта же логика может быть применена и к пространству 3D, но не забудьте newFPRotation
соответствующим образом изменить вычисление.