完成相机视角背部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

@@ -1,139 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &6109725415137145466
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2876901077084542335}
- component: {fileID: 3944192941116947467}
- component: {fileID: 6812351252165310732}
- component: {fileID: 4030617700739101234}
m_Layer: 9
m_Name: Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2876901077084542335
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6109725415137145466}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!20 &3944192941116947467
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6109725415137145466}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_Iso: 200
m_ShutterSpeed: 0.005
m_Aperture: 16
m_FocusDistance: 10
m_FocalLength: 50
m_BladeCount: 5
m_Curvature: {x: 2, y: 11}
m_BarrelClipping: 0.25
m_Anamorphism: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.1
far clip plane: 1000
field of view: 50
orthographic: 0
orthographic size: 5
m_Depth: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 1
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!81 &6812351252165310732
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6109725415137145466}
m_Enabled: 1
--- !u!114 &4030617700739101234
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6109725415137145466}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3}
m_Name:
m_EditorClassIdentifier:
m_RenderShadows: 1
m_RequiresDepthTextureOption: 2
m_RequiresOpaqueTextureOption: 2
m_CameraType: 0
m_Cameras: []
m_RendererIndex: -1
m_VolumeLayerMask:
serializedVersion: 2
m_Bits: 1
m_VolumeTrigger: {fileID: 0}
m_VolumeFrameworkUpdateModeOption: 2
m_RenderPostProcessing: 0
m_Antialiasing: 0
m_AntialiasingQuality: 2
m_StopNaN: 0
m_Dithering: 0
m_ClearDepth: 1
m_AllowXRRendering: 1
m_AllowHDROutput: 1
m_UseScreenCoordOverride: 0
m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0}
m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0}
m_RequiresDepthTexture: 0
m_RequiresColorTexture: 0
m_Version: 2
m_TaaSettings:
m_Quality: 3
m_FrameInfluence: 0.1
m_JitterScale: 1
m_MipBias: 0
m_VarianceClampScale: 0.9
m_ContrastAdaptiveSharpening: 0

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 9879c25cc7687534cb82313410af20ec
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 152c1923c5f87664ab3d9c516e11a179
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

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
}
}