private void HandFollow(float handPitch) { if (CompareUtility.IsApproximatelyEqual(handPitch, 0f)) { return; } var leftHandToLeftClav = //手到肩的距离 Vector3.Dot(_leftWeaponLocator.position - _leftClavicleP3.position, _characterP3.transform.forward); var leftHandToRightClav = Vector3.Dot(_leftWeaponLocator.position - _rightClavicleP3.position, _characterP3.transform.forward); //左肩在右肩之前,旋转角不一致。 左手到左肩距离表示为LL,左手到右肩距离为LR,右肩旋转角theta //左肩旋转角 A = arctan( LR*sin(theta) / (LL-(1-LR*cos(theta))) ) //左臂旋转后会有轻微穿模,应向前伸展到LR*sin(theta)/sinA长度,暂忽略 var leftClavAngle = Mathf.Rad2Deg * Mathf.Atan( (leftHandToRightClav * Mathf.Sin(handPitch * Mathf.Deg2Rad)) / (leftHandToLeftClav - (1 - Mathf.Cos(handPitch * Mathf.Deg2Rad)) * leftHandToRightClav)); var r = BoneRigging.ConvertRotation(_characterP3.transform, _rightClavicleP3, Quaternion.AngleAxis(handPitch, Vector3.right)); if (float.IsNaN(r.x) || float.IsNaN(r.y) || float.IsNaN(r.z) || float.IsNaN(r.w) || float.IsInfinity(r.x) || float.IsInfinity(r.y) || float.IsInfinity(r.z) || float.IsInfinity(r.w) || float.IsNaN(_rightClavicleP3.rotation.x) || float.IsNaN(_rightClavicleP3.rotation.y) || float.IsNaN(_rightClavicleP3.rotation.z) || float.IsNaN(_rightClavicleP3.rotation.w) || float.IsInfinity(_rightClavicleP3.rotation.x) || float.IsInfinity(_rightClavicleP3.rotation.y) || float.IsInfinity(_rightClavicleP3.rotation.z) || float.IsInfinity(_rightClavicleP3.rotation.w)) { _logger.ErrorFormat( "rightClavicleP3RotationIsNaNOrInfinity: rotation :{0} r :{1} HandPitch : {2} characterPos : {3} characterRot : {4}", _rightClavicleP3.rotation, r, handPitch, _characterP3.transform.position, _characterP3.transform.rotation); return; } _rightClavicleP3.rotation = _rightClavicleP3.rotation * r; r = BoneRigging.ConvertRotation(_characterP3.transform, _leftClavicleP3, Quaternion.AngleAxis(leftClavAngle, Vector3.right)); _leftClavicleP3.rotation = _leftClavicleP3.rotation * r; //baseWeaponLocator跟随右肩旋转 _baseLocatorP3.transform.RotateAround(_rightClavicleP3.transform.position, _characterP3.transform.right, handPitch); }
private void HeadFollowYaw(float headYaw) { if (CompareUtility.IsApproximatelyEqual(headYaw, 0f)) { return; } float yawHead = (headYaw > _horizontalHeadRotMax) ? _horizontalHeadRotMax : headYaw; yawHead = (yawHead < _horizontalHeadRotMin) ? _horizontalHeadRotMin : yawHead; var r = BoneRigging.ConvertRotation(_characterP3.transform, _neckP3, Quaternion.AngleAxis(yawHead * _neckRotVerticalIndex, Vector3.up)); _neckP3.rotation = _neckP3.rotation * r; r = BoneRigging.ConvertRotation(_characterP3.transform, _headP3, Quaternion.AngleAxis(yawHead * (1 - _neckRotVerticalIndex), Vector3.up)); _headP3.rotation = _headP3.rotation * r; }
private void HeadFollowPitch(float headPitch) { if (CompareUtility.IsApproximatelyEqual(headPitch, 0f)) { return; } float pitchHead = (headPitch > _verticalHeadRotMax) ? _verticalHeadRotMax : headPitch; pitchHead = (pitchHead < _verticalHeadRotMin) ? _verticalHeadRotMin : pitchHead; var r = BoneRigging.ConvertRotation(_characterP3.transform, _neckP3, Quaternion.AngleAxis(pitchHead * _neckRotHorizontalIndex, Vector3.right)); _neckP3.rotation = _neckP3.rotation * r; r = BoneRigging.ConvertRotation(_characterP3.transform, _headP3, Quaternion.AngleAxis(pitchHead * (1 - _neckRotHorizontalIndex), Vector3.right)); _headP3.rotation = _headP3.rotation * r; }