예제 #1
0
        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);
        }
예제 #2
0
 private void SetSightMove(SightStatusParam param)
 {
     if (null == EnableSightMove)
     {
         return;
     }
     EnableSightMove.Invoke(!param.IsIntoSight && param.SightProgress >= 1);
 }
예제 #3
0
        // 腰射与肩射的切换,与肩射呼吸动作
        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;
            }
        }