private void AlignLocatorRotation(SightStatusParam param, Vector3 dir, Matrix4x4 alignedMatrix) { var dir1 = _sightLocationP1.position - _cameraLocatorP1.position; var dir2 = Vector3.Normalize(dir1 + dir); dir1 = dir1.normalized; var axis = Vector3.Cross(dir1, dir2).normalized; if (CompareUtility.IsApproximatelyEqual(axis, Vector3.zero) || CompareUtility.IsApproximatelyEqual(Vector3.Dot(dir1, dir2), 1, 0)) { return; } var angle = Mathf.Acos(Vector3.Dot(dir1, dir2)) * Mathf.Rad2Deg; if (float.IsNaN(angle)) { return; } if (param.IsFire || _updateBone) { return; } _sightLocationP1.Rotate(axis, -angle); AlignCoordinateSystems(_sightLocationP1, Vector3.Lerp(_sightLocationP1.position, alignedMatrix.ExtractPosition(), Mathf.Clamp01(param.SightProgress)), Quaternion.Slerp(_sightLocationP1.rotation, alignedMatrix.ExtractRotation(), Mathf.Clamp01(param.SightProgress)), _directionLocatorP1); }
private void SetSightMove(SightStatusParam param) { if (null == EnableSightMove) { return; } EnableSightMove.Invoke(!param.IsIntoSight && param.SightProgress >= 1); }
// 腰射与肩射的切换,与肩射呼吸动作 private void SetSightStatus(SightStatusParam param) { if (param.IsSight) { if (_sightLocationP1 == null) { _sightLocationP1 = BoneMount.FindChildBoneFromCache(_characterP1, BoneName.AttachmentSight); if (_sightLocationP1 == null) { _sightLocationP1 = BoneMount.FindChildBoneFromCache(_characterP1, BoneName.WeaponSight); } if (_sightLocationP1 == null) { _logger.ErrorFormat("characterP1:{0} contains no Bone:{1} or {2}", _characterP1.name, BoneName.AttachmentSight, BoneName.WeaponSight); } } var tempPos = _sightLocationP1.localPosition; var tempRot = _sightLocationP1.localRotation; var tempWorldPos = _sightLocationP1.position; // 记录viewPoint与sightLocator的相对位移 if (_updateBone) { _matrix = _viewPointP1.worldToLocalMatrix * _sightLocationP1.localToWorldMatrix; } SetSightMove(param); _updateBone = param.SightProgress < 1; var finalMatrix = _viewPointP1.localToWorldMatrix * _matrix; _sightLocationP1.position = finalMatrix.ExtractPosition(); _sightLocationP1.rotation = finalMatrix.ExtractRotation(); var dir = tempWorldPos - _sightLocationP1.position; //camera local position var alignedPosition = _cameraLocatorP1.localPosition; alignedPosition.z += param.SightOffset; if (CompareUtility.IsApproximatelyEqual(param.SightProgress, 1)) { alignedPosition.x += param.SightHorizontalShift; alignedPosition.y += param.SightVerticalShift; } // 一人称开镜状态下,人物偏移(枪,分辨率相关) alignedPosition += param.FirstPersonSightOffset; // 镜与人眼距离(瞄准镜相关) alignedPosition.z += param.ScopeOffset; var alignedRotation = Quaternion.AngleAxis(/*param.PitchAmplitude*/ -param.SightModelOffset, Vector3.right) * _cameraLocatorP1.localRotation; alignedPosition = alignedRotation * alignedPosition; var alignedMatrix = _cameraLocatorP1.parent.localToWorldMatrix * Matrix4x4.TRS(alignedPosition, alignedRotation, Vector3.one); AlignCoordinateSystems(_sightLocationP1, Vector3.Lerp(_sightLocationP1.position, alignedMatrix.ExtractPosition(), Mathf.Clamp01(param.SightProgress)), Quaternion.Slerp(_sightLocationP1.rotation, alignedMatrix.ExtractRotation(), Mathf.Clamp01(param.SightProgress)), _directionLocatorP1); AlignLocatorRotation(param, dir, alignedMatrix); // 目标:sightlocater的向前方向旋转SightPeekDegree的角度,实现瞄准QE // 做法,把baseLocator先转换到sightLocation关节空间,对sightLocation的局部坐标系沿着自身向前旋转SightPeekDegree的角度,转换到世界坐标系,最后把结果转换到baseLocator父关节的坐标系 var povitMatrix = _sightLocationP1.parent.localToWorldMatrix * Matrix4x4.TRS( _sightLocationP1.localPosition, Quaternion.AngleAxis( CharacterStateConfigManager.Instance.SightPeekDegree * param.PeekAmplitude, -_sightLocationP1.localRotation.Forward()) * _sightLocationP1.localRotation, Vector3.one); AlignCoordinateSystems(_sightLocationP1, povitMatrix.ExtractPosition(), povitMatrix.ExtractRotation(), _directionLocatorP1); _sightLocationP1.localPosition = tempPos; _sightLocationP1.localRotation = tempRot; } else { _sightLocationP1 = null; } }