完成相机视角背部IK控制

This commit is contained in:
2025-05-18 11:35:02 +08:00
parent ee237ad25a
commit 4a614b6a21
8 changed files with 2836 additions and 4666 deletions

View File

@@ -17,7 +17,7 @@ public class ArmTest : MonoBehaviour
{
if (!targetTransform) return;
// transform.localEulerAngles = target;
targetTransform.localRotation *= Quaternion.Euler(target.x, target.y, target.z);
targetTransform.localRotation = Quaternion.Euler(target.x, target.y, target.z);
//我草拟吗。transform.localEulerAngle = target;
//wo shi da sha bi. ArmTest Monobehaviour
//我草拟大爷的。transofrm.localEulerAngles = target;

View File

@@ -1,18 +1,20 @@
using System;
using ECM2;
using RootMotion.FinalIK;
using UnityEngine;
namespace NBF
{
public class PlayerCharacter : Character
{
public GameObject cameraParent;
private float _cameraPitch;
private FPlayer _player;
private float _defBackSpineZ;
[HideInInspector] public int nextShowSlotIndex = -1;
public GameObject cameraParent;
[Space(15.0f)] public bool invertLook = true;
[Tooltip("视角旋转敏感度")] public Vector2 sensitivity = new Vector2(0.05f, 0.05f);
@@ -23,10 +25,23 @@ namespace NBF
public bool IsSelf;
private Quaternion spineInitialLocalRotation;
public LookAtIK lookAtIK; // 挂在背部上的 LookAtIK 脚本
public float aimDistance = 1.5f; // 目标点离相机多远
private Transform lookTarget; // 实际目标点
[Header("限制角度(单位:度)")] public float maxUpAngle = 20f; // 相机抬头最多20°
public float maxDownAngle = 40f; // 相机低头最多40°
protected override void Start()
{
base.Start();
// 创建一个动态目标点对象,避免你每次动态生成
lookAtIK = GetComponent<LookAtIK>();
_player = GetComponent<FPlayer>();
IsSelf = _player.Data.PlayerID == GameModel.RoleID;
cameraParent = _player.CameraRoot.gameObject;
@@ -35,6 +50,11 @@ namespace NBF
camera = BaseCamera.Main;
}
lookTarget = new GameObject("SpineLookTarget").transform;
lookTarget.SetParent(_player.transform);
spineInitialLocalRotation = _player.BackSpine.localRotation;
_defBackSpineZ = -AnglesChange(_player.BackSpine.localEulerAngles.z);
transform.position = _player.Data.position;
transform.rotation = _player.Data.rotation;
@@ -75,22 +95,22 @@ namespace NBF
private void UpdatePlayerHandView()
{
// var backValue = 0f;
Vector3 cameraForward = cameraTransform.forward;
Vector3 flatForward = Vector3.ProjectOnPlane(cameraForward, Vector3.up).normalized;
var angle = cameraParent.transform.localEulerAngles.x;
angle = (angle > 180f) ? angle - 360f : angle;
angle *= -1;
if (angle > handMaxAngle.x)
{
angle = handMaxAngle.x;
}
else if (angle < handMaxAngle.y)
{
angle = handMaxAngle.y;
}
// 获取相机 pitch 角度(负值是上看,正值是下看)
float pitchAngle = Vector3.SignedAngle(flatForward, cameraForward, cameraTransform.right);
Debug.Log(angle);
_player.BackSpine.localRotation *= Quaternion.Euler(0, 0, angle);
// 限制 pitch 角度
pitchAngle = Mathf.Clamp(pitchAngle, -maxUpAngle, maxDownAngle);
// 重新构造限制后的目标方向
Quaternion limitedPitch = Quaternion.AngleAxis(pitchAngle, cameraTransform.right);
Vector3 limitedDirection = limitedPitch * flatForward;
// 设置目标点
lookTarget.position = cameraTransform.position + limitedDirection * aimDistance;
lookAtIK.solver.target = lookTarget;
}
#endregion
@@ -192,5 +212,23 @@ namespace NBF
}
#endregion
#region
float GetCameraPitch()
{
Vector3 camForward = cameraParent.transform.forward;
camForward.y = 0;
camForward.Normalize();
float pitch = Vector3.SignedAngle(camForward, cameraParent.transform.forward, cameraParent.transform.right);
return pitch;
}
private float AnglesChange(float angle)
{
return (angle > 180f) ? angle - 360f : angle;
}
#endregion
}
}