Fix : 카메라 컨트롤 시스템 업데이트
This commit is contained in:
parent
daf834ee7d
commit
24c5145ff4
@ -3,24 +3,22 @@ using Unity.Cinemachine;
|
|||||||
using UnityRawInput;
|
using UnityRawInput;
|
||||||
using UnityEngine.Rendering;
|
using UnityEngine.Rendering;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
[DefaultExecutionOrder(2)]
|
||||||
public class CameraControlSystem : MonoBehaviour
|
public class CameraControlSystem : MonoBehaviour
|
||||||
{
|
{
|
||||||
[Header("FOV Physics Settings")]
|
[Header("FOV Physics Settings")]
|
||||||
[SerializeField] private float[] fovForces = {80f, 200f, 400f}; // 포스 강도
|
[SerializeField] private float fovForce = 400f; // 포스 강도 (고정값) - 2배 증가
|
||||||
[SerializeField] private int currentForceIndex = 1; // 기본값: 200
|
|
||||||
[SerializeField] private float fovDamping = 6f; // 감쇠력
|
[SerializeField] private float fovDamping = 6f; // 감쇠력
|
||||||
[SerializeField] private float fovMaxVelocity = 100f; // 최대 속도
|
[SerializeField] private float fovMaxVelocity = 200f; // 최대 속도 - 2배 증가
|
||||||
[SerializeField] private float minFOV = 0.1f;
|
[SerializeField] private float minFOV = 0.1f;
|
||||||
[SerializeField] private float maxFOV = 60f;
|
[SerializeField] private float maxFOV = 60f;
|
||||||
|
|
||||||
[Header("DOF Physics Settings")]
|
[Header("DOF Physics Settings")]
|
||||||
[SerializeField] private float[] dofForces = {10f, 20f, 50f}; // DOF 포스 강도
|
[SerializeField] private float dofStep = 0.01f; // DOF Focal Length 증가/감소 단위
|
||||||
[SerializeField] private int currentDofForceIndex = 1; // 기본값: 0.5
|
[SerializeField] private float minDOF = 0.01f; // Focal Length 최소값
|
||||||
[SerializeField] private float dofDamping = 6f; // DOF 감쇠력
|
[SerializeField] private float maxDOF = 1f; // Focal Length 최대값
|
||||||
[SerializeField] private float dofMaxVelocity = 5f; // DOF 최대 속도
|
|
||||||
[SerializeField] private float minDOF = 0.1f;
|
|
||||||
[SerializeField] private float maxDOF = 50f;
|
|
||||||
|
|
||||||
[Header("Screenshot Settings")]
|
[Header("Screenshot Settings")]
|
||||||
[SerializeField] private string screenshotPath = "Screenshots";
|
[SerializeField] private string screenshotPath = "Screenshots";
|
||||||
@ -36,15 +34,25 @@ public class CameraControlSystem : MonoBehaviour
|
|||||||
private float targetFOV = 60f; // 목표 FOV
|
private float targetFOV = 60f; // 목표 FOV
|
||||||
private bool isApplyingForce = false; // 현재 포스가 적용 중인지
|
private bool isApplyingForce = false; // 현재 포스가 적용 중인지
|
||||||
|
|
||||||
// DOF 물리 시스템 변수들
|
// DOF 값 변수
|
||||||
private float dofVelocity = 0f; // 현재 DOF 변화 속도
|
private float currentDOFValue = 0.3f; // 현재 DOF Focal Length 값
|
||||||
private float targetDOF = 1f; // 목표 DOF
|
|
||||||
private bool isApplyingDofForce = false; // 현재 DOF 포스가 적용 중인지
|
|
||||||
|
|
||||||
// Beautify Volume Override 참조
|
// Beautify Volume Override 참조
|
||||||
private object beautifyOverride;
|
private object beautifyOverride;
|
||||||
private bool isDOFEnabled = false; // DOF 활성화 상태 (기본값: 꺼짐)
|
private bool isDOFEnabled = false; // DOF 활성화 상태 (기본값: 꺼짐)
|
||||||
|
|
||||||
|
// F13/F14 제어 모드 전환 (true: FOV, false: DOF)
|
||||||
|
private bool isFOVMode = true;
|
||||||
|
|
||||||
|
// F18 더블클릭 감지용
|
||||||
|
private float lastF18ClickTime = 0f;
|
||||||
|
private const float doubleClickThreshold = 0.3f;
|
||||||
|
|
||||||
|
// DOF 타겟팅용
|
||||||
|
private Transform currentDOFTarget = null;
|
||||||
|
private List<Transform> availableDOFTargets = new List<Transform>();
|
||||||
|
private int currentTargetIndex = 0;
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
// 스크린샷 폴더 생성
|
// 스크린샷 폴더 생성
|
||||||
@ -71,6 +79,9 @@ public class CameraControlSystem : MonoBehaviour
|
|||||||
Debug.Log("[CameraControlSystem] Beautify 초기화 시작");
|
Debug.Log("[CameraControlSystem] Beautify 초기화 시작");
|
||||||
InitializeBeautify();
|
InitializeBeautify();
|
||||||
|
|
||||||
|
// DOF 타겟 찾기
|
||||||
|
FindDOFTargets();
|
||||||
|
|
||||||
InitializeRawInput();
|
InitializeRawInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,6 +134,7 @@ public class CameraControlSystem : MonoBehaviour
|
|||||||
HandleFOVControl();
|
HandleFOVControl();
|
||||||
UpdateFOVPhysics();
|
UpdateFOVPhysics();
|
||||||
UpdateDOFPhysics();
|
UpdateDOFPhysics();
|
||||||
|
UpdateDOFTargetTracking();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleRawKeyDown(RawKey key)
|
private void HandleRawKeyDown(RawKey key)
|
||||||
@ -130,13 +142,15 @@ public class CameraControlSystem : MonoBehaviour
|
|||||||
switch (key)
|
switch (key)
|
||||||
{
|
{
|
||||||
case RawKey.F13:
|
case RawKey.F13:
|
||||||
IncreaseFOV();
|
if (isFOVMode) IncreaseFOV();
|
||||||
|
else IncreaseDOF();
|
||||||
break;
|
break;
|
||||||
case RawKey.F14:
|
case RawKey.F14:
|
||||||
DecreaseFOV();
|
if (isFOVMode) DecreaseFOV();
|
||||||
|
else DecreaseDOF();
|
||||||
break;
|
break;
|
||||||
case RawKey.F15:
|
case RawKey.F15:
|
||||||
CycleFOVSpeed();
|
ToggleControlMode();
|
||||||
break;
|
break;
|
||||||
case RawKey.F16:
|
case RawKey.F16:
|
||||||
TakeScreenshot();
|
TakeScreenshot();
|
||||||
@ -145,19 +159,7 @@ public class CameraControlSystem : MonoBehaviour
|
|||||||
ToggleCameraUI();
|
ToggleCameraUI();
|
||||||
break;
|
break;
|
||||||
case RawKey.F18:
|
case RawKey.F18:
|
||||||
ToggleDOF();
|
HandleF18Click();
|
||||||
break;
|
|
||||||
case RawKey.F19:
|
|
||||||
Debug.Log("[CameraControlSystem] F19 키 입력 감지 (RawInput)");
|
|
||||||
CycleDOFSpeed();
|
|
||||||
break;
|
|
||||||
case RawKey.F20:
|
|
||||||
Debug.Log("[CameraControlSystem] F20 키 입력 감지 (RawInput)");
|
|
||||||
IncreaseDOF();
|
|
||||||
break;
|
|
||||||
case RawKey.F21:
|
|
||||||
Debug.Log("[CameraControlSystem] F21 키 입력 감지 (RawInput)");
|
|
||||||
DecreaseDOF();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,15 +169,17 @@ public class CameraControlSystem : MonoBehaviour
|
|||||||
// Unity Input으로도 처리 (RawInput과 병행하여 안정성 확보)
|
// Unity Input으로도 처리 (RawInput과 병행하여 안정성 확보)
|
||||||
if (Input.GetKeyDown(KeyCode.F13))
|
if (Input.GetKeyDown(KeyCode.F13))
|
||||||
{
|
{
|
||||||
IncreaseFOV();
|
if (isFOVMode) IncreaseFOV();
|
||||||
|
else IncreaseDOF();
|
||||||
}
|
}
|
||||||
else if (Input.GetKeyDown(KeyCode.F14))
|
else if (Input.GetKeyDown(KeyCode.F14))
|
||||||
{
|
{
|
||||||
DecreaseFOV();
|
if (isFOVMode) DecreaseFOV();
|
||||||
|
else DecreaseDOF();
|
||||||
}
|
}
|
||||||
else if (Input.GetKeyDown(KeyCode.F15))
|
else if (Input.GetKeyDown(KeyCode.F15))
|
||||||
{
|
{
|
||||||
CycleFOVSpeed();
|
ToggleControlMode();
|
||||||
}
|
}
|
||||||
else if (Input.GetKeyDown(KeyCode.F16))
|
else if (Input.GetKeyDown(KeyCode.F16))
|
||||||
{
|
{
|
||||||
@ -187,24 +191,7 @@ public class CameraControlSystem : MonoBehaviour
|
|||||||
}
|
}
|
||||||
else if (Input.GetKeyDown(KeyCode.F18))
|
else if (Input.GetKeyDown(KeyCode.F18))
|
||||||
{
|
{
|
||||||
ToggleDOF();
|
HandleF18Click();
|
||||||
}
|
|
||||||
|
|
||||||
// DOF 제어 (F19-F21)
|
|
||||||
if (Input.GetKeyDown(KeyCode.F19))
|
|
||||||
{
|
|
||||||
Debug.Log("[CameraControlSystem] F19 키 입력 감지 (Unity Input)");
|
|
||||||
CycleDOFSpeed();
|
|
||||||
}
|
|
||||||
else if (Input.GetKeyDown(KeyCode.F20))
|
|
||||||
{
|
|
||||||
Debug.Log("[CameraControlSystem] F20 키 입력 감지 (Unity Input)");
|
|
||||||
IncreaseDOF();
|
|
||||||
}
|
|
||||||
else if (Input.GetKeyDown(KeyCode.F21))
|
|
||||||
{
|
|
||||||
Debug.Log("[CameraControlSystem] F21 키 입력 감지 (Unity Input)");
|
|
||||||
DecreaseDOF();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,8 +219,7 @@ public class CameraControlSystem : MonoBehaviour
|
|||||||
isApplyingForce = true;
|
isApplyingForce = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
float currentForce = fovForces[currentForceIndex];
|
ApplyFOVForce(fovForce); // 양의 포스 적용
|
||||||
ApplyFOVForce(currentForce); // 양의 포스 적용
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DecreaseFOV()
|
private void DecreaseFOV()
|
||||||
@ -247,13 +233,7 @@ public class CameraControlSystem : MonoBehaviour
|
|||||||
isApplyingForce = true;
|
isApplyingForce = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
float currentForce = fovForces[currentForceIndex];
|
ApplyFOVForce(-fovForce); // 음의 포스 적용
|
||||||
ApplyFOVForce(-currentForce); // 음의 포스 적용
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CycleFOVSpeed()
|
|
||||||
{
|
|
||||||
currentForceIndex = (currentForceIndex + 1) % fovForces.Length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplyFOVForce(float force)
|
private void ApplyFOVForce(float force)
|
||||||
@ -462,8 +442,8 @@ public class CameraControlSystem : MonoBehaviour
|
|||||||
var valueProperty = fieldValue.GetType().GetProperty("value");
|
var valueProperty = fieldValue.GetType().GetProperty("value");
|
||||||
if (valueProperty != null && valueProperty.PropertyType == typeof(float))
|
if (valueProperty != null && valueProperty.PropertyType == typeof(float))
|
||||||
{
|
{
|
||||||
targetDOF = (float)valueProperty.GetValue(fieldValue);
|
currentDOFValue = (float)valueProperty.GetValue(fieldValue);
|
||||||
Debug.Log($"[CameraControlSystem] 초기 DOF 거리: {targetDOF}");
|
Debug.Log($"[CameraControlSystem] 초기 DOF 거리: {currentDOFValue}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -534,135 +514,36 @@ public class CameraControlSystem : MonoBehaviour
|
|||||||
// DOF 제어 메서드들
|
// DOF 제어 메서드들
|
||||||
private void IncreaseDOF()
|
private void IncreaseDOF()
|
||||||
{
|
{
|
||||||
Debug.Log("[CameraControlSystem] IncreaseDOF() 호출됨");
|
if (beautifyOverride == null || !isDOFEnabled) return;
|
||||||
if (beautifyOverride == null)
|
|
||||||
{
|
|
||||||
Debug.LogWarning("[CameraControlSystem] beautifyOverride가 null이어서 IncreaseDOF() 중단됨");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isDOFEnabled)
|
currentDOFValue = Mathf.Clamp(currentDOFValue + dofStep, minDOF, maxDOF);
|
||||||
{
|
SetDOFValue(currentDOFValue);
|
||||||
Debug.Log("[CameraControlSystem] DOF가 비활성화되어 있어서 조작 불가");
|
Debug.Log($"[CameraControlSystem] DOF 증가: {currentDOFValue:F3}");
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 현재 DOF를 targetDOF로 초기화 (처음 호출 시)
|
|
||||||
if (!isApplyingDofForce)
|
|
||||||
{
|
|
||||||
var currentDOF = GetCurrentDOFValue();
|
|
||||||
if (currentDOF.HasValue)
|
|
||||||
{
|
|
||||||
targetDOF = currentDOF.Value;
|
|
||||||
}
|
|
||||||
isApplyingDofForce = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
float currentForce = dofForces[currentDofForceIndex];
|
|
||||||
ApplyDOFForce(currentForce); // 양의 포스 적용
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DecreaseDOF()
|
private void DecreaseDOF()
|
||||||
{
|
{
|
||||||
Debug.Log("[CameraControlSystem] DecreaseDOF() 호출됨");
|
if (beautifyOverride == null || !isDOFEnabled) return;
|
||||||
if (beautifyOverride == null)
|
|
||||||
{
|
|
||||||
Debug.LogWarning("[CameraControlSystem] beautifyOverride가 null이어서 DecreaseDOF() 중단됨");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isDOFEnabled)
|
currentDOFValue = Mathf.Clamp(currentDOFValue - dofStep, minDOF, maxDOF);
|
||||||
{
|
SetDOFValue(currentDOFValue);
|
||||||
Debug.Log("[CameraControlSystem] DOF가 비활성화되어 있어서 조작 불가");
|
Debug.Log($"[CameraControlSystem] DOF 감소: {currentDOFValue:F3}");
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 현재 DOF를 targetDOF로 초기화 (처음 호출 시)
|
|
||||||
if (!isApplyingDofForce)
|
|
||||||
{
|
|
||||||
Debug.Log("[CameraControlSystem] 현재 DOF 값 가져오는 중...");
|
|
||||||
var currentDOF = GetCurrentDOFValue();
|
|
||||||
if (currentDOF.HasValue)
|
|
||||||
{
|
|
||||||
targetDOF = currentDOF.Value;
|
|
||||||
Debug.Log($"[CameraControlSystem] 현재 DOF 값: {currentDOF.Value}");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.LogWarning("[CameraControlSystem] 현재 DOF 값을 가져올 수 없음");
|
|
||||||
}
|
|
||||||
isApplyingDofForce = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
float currentForce = dofForces[currentDofForceIndex];
|
|
||||||
ApplyDOFForce(-currentForce); // 음의 포스 적용
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CycleDOFSpeed()
|
|
||||||
{
|
|
||||||
currentDofForceIndex = (currentDofForceIndex + 1) % dofForces.Length;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ApplyDOFForce(float force)
|
|
||||||
{
|
|
||||||
// 포스를 속도에 더함 (가속도 = 포스, 질량 = 1로 가정)
|
|
||||||
dofVelocity += force * Time.deltaTime;
|
|
||||||
|
|
||||||
// 최대 속도 제한
|
|
||||||
dofVelocity = Mathf.Clamp(dofVelocity, -dofMaxVelocity, dofMaxVelocity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateDOFPhysics()
|
private void UpdateDOFPhysics()
|
||||||
{
|
{
|
||||||
if (beautifyOverride == null || !isDOFEnabled) return;
|
// 더 이상 물리 시스템 사용 안 함
|
||||||
|
|
||||||
var currentDOF = GetCurrentDOFValue();
|
|
||||||
if (!currentDOF.HasValue) return;
|
|
||||||
|
|
||||||
// 더 부드러운 감쇠력 적용 (지수적 감쇠)
|
|
||||||
float dampingFactor = Mathf.Exp(-dofDamping * Time.deltaTime);
|
|
||||||
dofVelocity *= dampingFactor;
|
|
||||||
|
|
||||||
// 속도가 거의 0에 가까우면 완전히 정지 (더 작은 임계값)
|
|
||||||
if (Mathf.Abs(dofVelocity) < 0.01f)
|
|
||||||
{
|
|
||||||
dofVelocity = 0f;
|
|
||||||
isApplyingDofForce = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 속도가 있을 때만 DOF 업데이트
|
|
||||||
if (Mathf.Abs(dofVelocity) > 0.001f)
|
|
||||||
{
|
|
||||||
float newDOF = currentDOF.Value + (dofVelocity * Time.deltaTime);
|
|
||||||
|
|
||||||
// DOF 범위 제한 및 경계에서 부드러운 반발
|
|
||||||
if (newDOF <= minDOF)
|
|
||||||
{
|
|
||||||
newDOF = minDOF;
|
|
||||||
dofVelocity = Mathf.Max(0f, dofVelocity * 0.3f); // 부드러운 반발
|
|
||||||
}
|
|
||||||
else if (newDOF >= maxDOF)
|
|
||||||
{
|
|
||||||
newDOF = maxDOF;
|
|
||||||
dofVelocity = Mathf.Min(0f, dofVelocity * 0.3f); // 부드러운 반발
|
|
||||||
}
|
|
||||||
|
|
||||||
SetDOFValue(newDOF);
|
|
||||||
targetDOF = newDOF;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DOF 값을 가져오는 헬퍼 메서드
|
// DOF Focal Length 값을 가져오는 헬퍼 메서드
|
||||||
private float? GetCurrentDOFValue()
|
private float? GetCurrentDOFValue()
|
||||||
{
|
{
|
||||||
if (beautifyOverride == null) return null;
|
if (beautifyOverride == null) return null;
|
||||||
|
|
||||||
string[] possibleFieldNames = {
|
string[] possibleFieldNames = {
|
||||||
"depthOfFieldDistance",
|
"depthOfFieldFocalLength",
|
||||||
"dofDistance",
|
"focalLength",
|
||||||
"focusDistance",
|
"dofFocalLength"
|
||||||
"depthOfFieldFocusDistance",
|
|
||||||
"distance"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var overrideType = beautifyOverride.GetType();
|
var overrideType = beautifyOverride.GetType();
|
||||||
@ -693,7 +574,7 @@ public class CameraControlSystem : MonoBehaviour
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DOF 값을 설정하는 헬퍼 메서드
|
// DOF Focal Length 값을 설정하는 헬퍼 메서드
|
||||||
private void SetDOFValue(float newValue)
|
private void SetDOFValue(float newValue)
|
||||||
{
|
{
|
||||||
if (beautifyOverride == null)
|
if (beautifyOverride == null)
|
||||||
@ -703,11 +584,9 @@ public class CameraControlSystem : MonoBehaviour
|
|||||||
}
|
}
|
||||||
|
|
||||||
string[] possibleFieldNames = {
|
string[] possibleFieldNames = {
|
||||||
"depthOfFieldDistance",
|
"depthOfFieldFocalLength",
|
||||||
"dofDistance",
|
"focalLength",
|
||||||
"focusDistance",
|
"dofFocalLength"
|
||||||
"depthOfFieldFocusDistance",
|
|
||||||
"distance"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var overrideType = beautifyOverride.GetType();
|
var overrideType = beautifyOverride.GetType();
|
||||||
@ -747,7 +626,7 @@ public class CameraControlSystem : MonoBehaviour
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.LogError("[CameraControlSystem] DOF Distance 필드를 찾을 수 없거나 설정할 수 없습니다");
|
Debug.LogError("[CameraControlSystem] DOF Focal Length 필드를 찾을 수 없거나 설정할 수 없습니다");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateBeautifyOverride(Volume volume, System.Type beautifyType)
|
private void CreateBeautifyOverride(Volume volume, System.Type beautifyType)
|
||||||
@ -885,7 +764,7 @@ public class CameraControlSystem : MonoBehaviour
|
|||||||
|
|
||||||
case "depthOfFieldDistance":
|
case "depthOfFieldDistance":
|
||||||
valueProperty.SetValue(fieldValue, 1f);
|
valueProperty.SetValue(fieldValue, 1f);
|
||||||
targetDOF = 1f;
|
currentDOFValue = 1f;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "depthOfFieldBokeh":
|
case "depthOfFieldBokeh":
|
||||||
@ -921,6 +800,7 @@ public class CameraControlSystem : MonoBehaviour
|
|||||||
if (valueProperty.PropertyType == typeof(float))
|
if (valueProperty.PropertyType == typeof(float))
|
||||||
{
|
{
|
||||||
valueProperty.SetValue(fieldValue, 0.3f); // 포커스 렌즈 길이 0.3
|
valueProperty.SetValue(fieldValue, 0.3f); // 포커스 렌즈 길이 0.3
|
||||||
|
currentDOFValue = 0.3f;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1005,6 +885,175 @@ public class CameraControlSystem : MonoBehaviour
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ToggleControlMode()
|
||||||
|
{
|
||||||
|
isFOVMode = !isFOVMode;
|
||||||
|
Debug.Log($"[CameraControlSystem] 제어 모드 전환: {(isFOVMode ? "FOV" : "DOF")} 모드");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleF18Click()
|
||||||
|
{
|
||||||
|
float currentTime = Time.time;
|
||||||
|
float timeSinceLastClick = currentTime - lastF18ClickTime;
|
||||||
|
|
||||||
|
if (timeSinceLastClick <= doubleClickThreshold)
|
||||||
|
{
|
||||||
|
// 더블클릭: DOF ON/OFF
|
||||||
|
ToggleDOF();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 싱글클릭: DOF 타겟 전환
|
||||||
|
CycleDOFTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
lastF18ClickTime = currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FindDOFTargets()
|
||||||
|
{
|
||||||
|
availableDOFTargets.Clear();
|
||||||
|
|
||||||
|
// 씬의 모든 CustomRetargetingScript 찾기
|
||||||
|
var retargetingScripts = FindObjectsByType<KindRetargeting.CustomRetargetingScript>(FindObjectsSortMode.None);
|
||||||
|
Debug.Log($"[CameraControlSystem] CustomRetargetingScript {retargetingScripts.Length}개 발견");
|
||||||
|
|
||||||
|
foreach (var script in retargetingScripts)
|
||||||
|
{
|
||||||
|
Debug.Log($"[CameraControlSystem] 스크립트 검사 중: {script.gameObject.name}, targetAnimator = {script.targetAnimator}");
|
||||||
|
|
||||||
|
if (script.targetAnimator != null)
|
||||||
|
{
|
||||||
|
// Head 본 찾기
|
||||||
|
Transform headBone = script.targetAnimator.GetBoneTransform(HumanBodyBones.Head);
|
||||||
|
Debug.Log($"[CameraControlSystem] Head 본 찾기: {(headBone != null ? headBone.name : "null")}");
|
||||||
|
|
||||||
|
if (headBone != null)
|
||||||
|
{
|
||||||
|
// Head에 콜라이더가 없으면 추가
|
||||||
|
bool hasCollider = headBone.TryGetComponent<SphereCollider>(out _);
|
||||||
|
Debug.Log($"[CameraControlSystem] {headBone.name}에 기존 콜라이더: {hasCollider}");
|
||||||
|
|
||||||
|
if (!hasCollider)
|
||||||
|
{
|
||||||
|
var collider = headBone.gameObject.AddComponent<SphereCollider>();
|
||||||
|
collider.radius = 0.1f;
|
||||||
|
collider.isTrigger = true;
|
||||||
|
Debug.Log($"[CameraControlSystem] {headBone.name}에 SphereCollider 추가 완료 (radius: 0.1)");
|
||||||
|
}
|
||||||
|
|
||||||
|
availableDOFTargets.Add(headBone);
|
||||||
|
Debug.Log($"[CameraControlSystem] DOF 타겟 추가: {headBone.name} ({script.targetAnimator.gameObject.name})");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Log($"[CameraControlSystem] 총 {availableDOFTargets.Count}개의 DOF 타겟 발견");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CycleDOFTarget()
|
||||||
|
{
|
||||||
|
if (currentVirtualCamera == null)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("[CameraControlSystem] 가상 카메라가 없습니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 카메라 중앙에서 레이 발사
|
||||||
|
Camera mainCamera = Camera.main;
|
||||||
|
if (mainCamera == null)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("[CameraControlSystem] 메인 카메라를 찾을 수 없습니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ray ray = mainCamera.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0));
|
||||||
|
RaycastHit[] hits = Physics.RaycastAll(ray, 100f);
|
||||||
|
|
||||||
|
Debug.Log($"[CameraControlSystem] 레이캐스트: {hits.Length}개의 오브젝트 감지");
|
||||||
|
|
||||||
|
// SphereCollider가 있는 Head 본만 필터링
|
||||||
|
List<RaycastHit> validHits = new List<RaycastHit>();
|
||||||
|
foreach (var hit in hits)
|
||||||
|
{
|
||||||
|
if (hit.collider is SphereCollider && hit.transform.name.Contains("Head"))
|
||||||
|
{
|
||||||
|
validHits.Add(hit);
|
||||||
|
Debug.Log($"[CameraControlSystem] 유효한 타겟 발견: {hit.transform.name} (거리: {hit.distance:F2}m)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validHits.Count == 0)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("[CameraControlSystem] 레이에 맞은 Head 타겟이 없습니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 거리순으로 정렬
|
||||||
|
validHits.Sort((a, b) => a.distance.CompareTo(b.distance));
|
||||||
|
|
||||||
|
// 현재 타겟 찾기
|
||||||
|
int nextIndex = 0;
|
||||||
|
if (currentDOFTarget != null)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < validHits.Count; i++)
|
||||||
|
{
|
||||||
|
if (validHits[i].transform == currentDOFTarget)
|
||||||
|
{
|
||||||
|
nextIndex = (i + 1) % validHits.Count;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 다음 타겟 설정
|
||||||
|
currentDOFTarget = validHits[nextIndex].transform;
|
||||||
|
float distance = validHits[nextIndex].distance;
|
||||||
|
|
||||||
|
// depthOfFieldDistance 설정
|
||||||
|
SetDOFDistance(distance);
|
||||||
|
|
||||||
|
Debug.Log($"[CameraControlSystem] DOF 타겟 설정: {currentDOFTarget.name} (거리: {distance:F2}m)");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetDOFDistance(float distance)
|
||||||
|
{
|
||||||
|
if (beautifyOverride == null)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("[CameraControlSystem] beautifyOverride가 null입니다");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var overrideType = beautifyOverride.GetType();
|
||||||
|
var dofDistanceField = overrideType.GetField("depthOfFieldDistance");
|
||||||
|
|
||||||
|
if (dofDistanceField != null)
|
||||||
|
{
|
||||||
|
var fieldValue = dofDistanceField.GetValue(beautifyOverride);
|
||||||
|
if (fieldValue != null)
|
||||||
|
{
|
||||||
|
var valueProperty = fieldValue.GetType().GetProperty("value");
|
||||||
|
var overrideProperty = fieldValue.GetType().GetProperty("overrideState");
|
||||||
|
|
||||||
|
if (valueProperty != null && overrideProperty != null)
|
||||||
|
{
|
||||||
|
overrideProperty.SetValue(fieldValue, true);
|
||||||
|
valueProperty.SetValue(fieldValue, distance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateDOFTargetTracking()
|
||||||
|
{
|
||||||
|
// 현재 타겟이 설정되어 있고, DOF가 활성화되어 있으면 지속적으로 거리 업데이트
|
||||||
|
if (currentDOFTarget != null && isDOFEnabled && currentVirtualCamera != null)
|
||||||
|
{
|
||||||
|
float distance = Vector3.Distance(currentVirtualCamera.transform.position, currentDOFTarget.position);
|
||||||
|
SetDOFDistance(distance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Public 메서드들 (외부에서 호출 가능)
|
// Public 메서드들 (외부에서 호출 가능)
|
||||||
public void SetFOV(float fov)
|
public void SetFOV(float fov)
|
||||||
{
|
{
|
||||||
@ -1038,12 +1087,7 @@ public class CameraControlSystem : MonoBehaviour
|
|||||||
// UI에서 사용할 Public 메서드들
|
// UI에서 사용할 Public 메서드들
|
||||||
public float GetCurrentForce()
|
public float GetCurrentForce()
|
||||||
{
|
{
|
||||||
return fovForces[currentForceIndex];
|
return fovForce;
|
||||||
}
|
|
||||||
|
|
||||||
public int GetCurrentForceIndex()
|
|
||||||
{
|
|
||||||
return currentForceIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetCurrentVelocity()
|
public float GetCurrentVelocity()
|
||||||
@ -1060,16 +1104,16 @@ public class CameraControlSystem : MonoBehaviour
|
|||||||
|
|
||||||
public float GetCurrentDofForce()
|
public float GetCurrentDofForce()
|
||||||
{
|
{
|
||||||
return dofForces[currentDofForceIndex];
|
return dofStep;
|
||||||
}
|
|
||||||
|
|
||||||
public int GetCurrentDofForceIndex()
|
|
||||||
{
|
|
||||||
return currentDofForceIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetCurrentDofVelocity()
|
public float GetCurrentDofVelocity()
|
||||||
{
|
{
|
||||||
return dofVelocity;
|
return 0f; // 더 이상 velocity 사용 안 함
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsFOVMode()
|
||||||
|
{
|
||||||
|
return isFOVMode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,9 +89,9 @@ public class CameraInfoUI : MonoBehaviour
|
|||||||
// 텍스트들 생성
|
// 텍스트들 생성
|
||||||
CreateInfoText("Camera Name: ", out cameraNameText, 0);
|
CreateInfoText("Camera Name: ", out cameraNameText, 0);
|
||||||
CreateInfoText("FOV: ", out fovValueText, 1);
|
CreateInfoText("FOV: ", out fovValueText, 1);
|
||||||
CreateInfoText("FOV Force: ", out fovSpeedText, 2);
|
CreateInfoText("Control Mode: ", out fovSpeedText, 2);
|
||||||
CreateInfoText("FOV Velocity: ", out velocityText, 3);
|
CreateInfoText("FOV Velocity: ", out velocityText, 3);
|
||||||
CreateInfoText("DOF Distance: ", out dofValueText, 4);
|
CreateInfoText("DOF Focal Length: ", out dofValueText, 4);
|
||||||
CreateInfoText("DOF Force: ", out dofSpeedText, 5);
|
CreateInfoText("DOF Force: ", out dofSpeedText, 5);
|
||||||
CreateInfoText("DOF Velocity: ", out dofVelocityText, 6);
|
CreateInfoText("DOF Velocity: ", out dofVelocityText, 6);
|
||||||
|
|
||||||
@ -146,18 +146,19 @@ public class CameraInfoUI : MonoBehaviour
|
|||||||
|
|
||||||
if (cameraControlSystem != null)
|
if (cameraControlSystem != null)
|
||||||
{
|
{
|
||||||
fovSpeedText.text = $"FOV Force: {cameraControlSystem.GetCurrentForce():F0} ({cameraControlSystem.GetCurrentForceIndex() + 1}/3)";
|
string currentMode = cameraControlSystem.IsFOVMode() ? "FOV" : "DOF";
|
||||||
|
fovSpeedText.text = $"Mode: {currentMode}";
|
||||||
velocityText.text = $"FOV Velocity: {cameraControlSystem.GetCurrentVelocity():F1}";
|
velocityText.text = $"FOV Velocity: {cameraControlSystem.GetCurrentVelocity():F1}";
|
||||||
|
|
||||||
dofValueText.text = $"DOF Distance: {cameraControlSystem.GetCurrentDOF():F1}";
|
dofValueText.text = $"DOF Focal Length: {cameraControlSystem.GetCurrentDOF():F3}";
|
||||||
dofSpeedText.text = $"DOF Force: {cameraControlSystem.GetCurrentDofForce():F1} ({cameraControlSystem.GetCurrentDofForceIndex() + 1}/3)";
|
dofSpeedText.text = $"DOF Force: {cameraControlSystem.GetCurrentDofForce():F1}";
|
||||||
dofVelocityText.text = $"DOF Velocity: {cameraControlSystem.GetCurrentDofVelocity():F2}";
|
dofVelocityText.text = $"DOF Velocity: {cameraControlSystem.GetCurrentDofVelocity():F2}";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fovSpeedText.text = "FOV Force: --";
|
fovSpeedText.text = "FOV Force: --";
|
||||||
velocityText.text = "FOV Velocity: --";
|
velocityText.text = "FOV Velocity: --";
|
||||||
dofValueText.text = "DOF Distance: --";
|
dofValueText.text = "DOF Focal Length: --";
|
||||||
dofSpeedText.text = "DOF Force: --";
|
dofSpeedText.text = "DOF Force: --";
|
||||||
dofVelocityText.text = "DOF Velocity: --";
|
dofVelocityText.text = "DOF Velocity: --";
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user