Integration of the octo input system and centralization of player values
This commit is contained in:
@@ -87,6 +87,27 @@ MonoBehaviour:
|
||||
Icon:
|
||||
UseName: 1
|
||||
Sprite: {fileID: 0}
|
||||
- Name: Diapason
|
||||
MapName: Player
|
||||
Action: -1931519977
|
||||
Reference: {fileID: 2137832212915005411, guid: 052faaac586de48259a63d0c4782560b, type: 3}
|
||||
Icon:
|
||||
UseName: 1
|
||||
Sprite: {fileID: 0}
|
||||
- Name: Fire
|
||||
MapName: Player
|
||||
Action: 380421744
|
||||
Reference: {fileID: -4999962443572761203, guid: 052faaac586de48259a63d0c4782560b, type: 3}
|
||||
Icon:
|
||||
UseName: 1
|
||||
Sprite: {fileID: 0}
|
||||
- Name: Exit
|
||||
MapName: Player
|
||||
Action: -2092987256
|
||||
Reference: {fileID: -7887538567484535354, guid: 052faaac586de48259a63d0c4782560b, type: 3}
|
||||
Icon:
|
||||
UseName: 1
|
||||
Sprite: {fileID: 0}
|
||||
- Name: Navigate
|
||||
MapName: UI
|
||||
Action: -1768796602
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"GeneratedFrom": "PlayerController",
|
||||
"GeneratedOn": "2026-02-09 21:55:05",
|
||||
"GeneratedOn": "2026-02-14 14:55:28",
|
||||
"Actions": [
|
||||
{
|
||||
"Name": "Player_Move",
|
||||
@@ -68,6 +68,12 @@
|
||||
"MapName": "Player",
|
||||
"ActionName": "Fire"
|
||||
},
|
||||
{
|
||||
"Name": "Player_Exit",
|
||||
"Hash": -2092987256,
|
||||
"MapName": "Player",
|
||||
"ActionName": "Exit"
|
||||
},
|
||||
{
|
||||
"Name": "UI_Navigate",
|
||||
"Hash": -1768796602,
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e3742e029846ff43acf1eb7d93d1966
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,330 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class OctoIkArmsImproved : MonoBehaviour
|
||||
{
|
||||
// Stores raycast hit information
|
||||
private class RaycastInfos
|
||||
{
|
||||
public bool HasHit;
|
||||
public float Distance;
|
||||
public float MaxDistance;
|
||||
public Vector3 Position;
|
||||
public Vector3 Normal;
|
||||
public Transform Transform;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
private class RaycastRig
|
||||
{
|
||||
public Transform Root;
|
||||
public float Distance = 1f;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
private class ArmRig
|
||||
{
|
||||
public bool Enabled = true;
|
||||
public OctoIkLimb Arm;
|
||||
public Vector3 RotationOffset;
|
||||
public RaycastRig[] Raycasts;
|
||||
|
||||
[HideInInspector] public Vector3 TargetOriginPos;
|
||||
[HideInInspector] public Quaternion TargetOriginRot;
|
||||
[HideInInspector] public Vector3 PoleOriginPos;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
if (Arm)
|
||||
{
|
||||
if (Arm.Target)
|
||||
{
|
||||
TargetOriginPos = Arm.Target.localPosition;
|
||||
TargetOriginRot = Arm.Target.localRotation;
|
||||
}
|
||||
|
||||
if (Arm.Pole)
|
||||
{
|
||||
PoleOriginPos = Arm.Pole.localPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
private class Settings
|
||||
{
|
||||
[Header("Raycast")]
|
||||
public LayerMask LayerMask;
|
||||
|
||||
[Header("Stickiness")]
|
||||
[Tooltip("Distance to start sticking (meters)")]
|
||||
[Range(0.1f, 2f)]
|
||||
public float StickStartDistance = 0.8f;
|
||||
|
||||
[Tooltip("Distance to fully release (meters)")]
|
||||
[Range(0.5f, 3f)]
|
||||
public float StickReleaseDistance = 1.2f;
|
||||
|
||||
[Header("Smoothing")]
|
||||
[Tooltip("Stick speed (units/sec)")]
|
||||
[Range(1f, 20f)]
|
||||
public float StickSpeed = 10f;
|
||||
|
||||
[Tooltip("Release speed (units/sec)")]
|
||||
[Range(1f, 20f)]
|
||||
public float ReleaseSpeed = 6f;
|
||||
|
||||
[Tooltip("Rotation speed (deg/sec)")]
|
||||
[Range(90f, 720f)]
|
||||
public float RotationSpeed = 360f;
|
||||
|
||||
[Header("Arm Selection")]
|
||||
[Tooltip("Can both arms stick at the same time?")]
|
||||
public bool AllowBothArms = true;
|
||||
|
||||
[Tooltip("Max surface angle to accept sticking (degrees)")]
|
||||
[Range(0f, 90f)]
|
||||
public float MaxSurfaceAngle = 60f;
|
||||
|
||||
[Header("Temporal Smoothing")]
|
||||
[Tooltip("Frames before releasing (prevents flickering)")]
|
||||
[Range(0, 10)]
|
||||
public int StabilityFrames = 3;
|
||||
}
|
||||
|
||||
[SerializeField] private ArmRig _leftArm;
|
||||
[SerializeField] private ArmRig _rightArm;
|
||||
[SerializeField] private Settings _settings;
|
||||
|
||||
private ArmRig[] _arms;
|
||||
private RaycastInfos[][] _raycasts = new RaycastInfos[2][];
|
||||
private RaycastInfos[] _nearestHitRaycasts = new RaycastInfos[2];
|
||||
private int[] _noHitFrameCount = new int[2];
|
||||
private float[] _currentStickiness = new float[2];
|
||||
|
||||
void Awake()
|
||||
{
|
||||
_arms = new ArmRig[2] { _leftArm, _rightArm };
|
||||
foreach (ArmRig armRig in _arms)
|
||||
armRig.Init();
|
||||
|
||||
// Initialize raycast arrays for both arms
|
||||
_raycasts = new RaycastInfos[_arms.Length][];
|
||||
for (int i = 0; i < _arms.Length; i++)
|
||||
{
|
||||
_raycasts[i] = new RaycastInfos[_arms[i].Raycasts.Length];
|
||||
for (int u = 0; u < _raycasts[i].Length; u++)
|
||||
_raycasts[i][u] = new RaycastInfos() { MaxDistance = 1 };
|
||||
}
|
||||
|
||||
_nearestHitRaycasts = new RaycastInfos[_arms.Length];
|
||||
for (int i = 0; i < _nearestHitRaycasts.Length; i++)
|
||||
_nearestHitRaycasts[i] = new RaycastInfos() { MaxDistance = 1 };
|
||||
|
||||
_noHitFrameCount = new int[_arms.Length];
|
||||
_currentStickiness = new float[_arms.Length];
|
||||
}
|
||||
|
||||
void OnDrawGizmos()
|
||||
{
|
||||
if (Application.isPlaying || !enabled) return;
|
||||
|
||||
foreach (ArmRig armRig in new ArmRig[2] { _leftArm, _rightArm })
|
||||
{
|
||||
if (armRig.Raycasts == null) continue;
|
||||
|
||||
for (int i = 0; i < armRig.Raycasts.Length; i++)
|
||||
{
|
||||
RaycastRig raycastRig = armRig.Raycasts[i];
|
||||
if (raycastRig.Root == null) continue;
|
||||
|
||||
Debug.DrawRay(raycastRig.Root.position, raycastRig.Root.TransformDirection(Vector3.forward) * raycastRig.Distance, Color.cyan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
PerformRaycasts();
|
||||
FindNearestHits();
|
||||
UpdateArmPositions();
|
||||
}
|
||||
|
||||
// Cast all configured raycasts and store results
|
||||
private void PerformRaycasts()
|
||||
{
|
||||
for (int i = 0; i < _arms.Length; i++)
|
||||
{
|
||||
ArmRig armRig = _arms[i];
|
||||
|
||||
if (!armRig.Enabled || armRig.Raycasts == null)
|
||||
continue;
|
||||
|
||||
for (int u = 0; u < armRig.Raycasts.Length; u++)
|
||||
{
|
||||
RaycastRig raycastRig = armRig.Raycasts[u];
|
||||
if (raycastRig.Root == null) continue;
|
||||
|
||||
RaycastInfos raycastInfos = _raycasts[i][u];
|
||||
RaycastHit hit;
|
||||
|
||||
Vector3 origin = raycastRig.Root.position;
|
||||
Vector3 direction = raycastRig.Root.TransformDirection(Vector3.forward);
|
||||
|
||||
if (Physics.Raycast(origin, direction, out hit, raycastRig.Distance, _settings.LayerMask))
|
||||
{
|
||||
Debug.DrawRay(origin, direction * hit.distance, Color.green);
|
||||
|
||||
raycastInfos.HasHit = true;
|
||||
raycastInfos.Distance = hit.distance;
|
||||
raycastInfos.MaxDistance = raycastRig.Distance;
|
||||
raycastInfos.Position = hit.point;
|
||||
raycastInfos.Normal = hit.normal;
|
||||
raycastInfos.Transform = hit.transform;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.DrawRay(origin, direction * raycastRig.Distance, Color.red);
|
||||
|
||||
raycastInfos.HasHit = false;
|
||||
raycastInfos.Distance = raycastRig.Distance;
|
||||
raycastInfos.MaxDistance = raycastRig.Distance;
|
||||
raycastInfos.Position = Vector3.zero;
|
||||
raycastInfos.Normal = Vector3.zero;
|
||||
raycastInfos.Transform = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find the closest raycast hit for each arm
|
||||
private void FindNearestHits()
|
||||
{
|
||||
for (int i = 0; i < _arms.Length; i++)
|
||||
{
|
||||
ArmRig armRig = _arms[i];
|
||||
RaycastInfos nearest = _nearestHitRaycasts[i];
|
||||
|
||||
nearest.HasHit = false;
|
||||
float closestDistance = float.MaxValue;
|
||||
|
||||
if (armRig.Raycasts == null) continue;
|
||||
|
||||
// Find the closest hit among all raycasts for this arm
|
||||
for (int u = 0; u < armRig.Raycasts.Length; u++)
|
||||
{
|
||||
RaycastInfos raycastInfos = _raycasts[i][u];
|
||||
|
||||
if (raycastInfos.HasHit && raycastInfos.Distance < closestDistance)
|
||||
{
|
||||
closestDistance = raycastInfos.Distance;
|
||||
|
||||
nearest.HasHit = true;
|
||||
nearest.Distance = raycastInfos.Distance;
|
||||
nearest.MaxDistance = raycastInfos.MaxDistance;
|
||||
nearest.Position = raycastInfos.Position;
|
||||
nearest.Normal = raycastInfos.Normal;
|
||||
nearest.Transform = raycastInfos.Transform;
|
||||
}
|
||||
}
|
||||
|
||||
// Track frames without hits for temporal smoothing
|
||||
if (!nearest.HasHit)
|
||||
{
|
||||
_noHitFrameCount[i]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
_noHitFrameCount[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update arm positions based on raycast hits
|
||||
private void UpdateArmPositions()
|
||||
{
|
||||
for (int i = 0; i < _arms.Length; i++)
|
||||
{
|
||||
ArmRig armRig = _arms[i];
|
||||
if (armRig.Arm == null || armRig.Arm.Target == null) continue;
|
||||
|
||||
RaycastInfos raycastInfos = _nearestHitRaycasts[i];
|
||||
|
||||
// Default to origin position/rotation
|
||||
Vector3 targetPos = armRig.TargetOriginPos;
|
||||
Quaternion targetRot = armRig.TargetOriginRot;
|
||||
|
||||
bool shouldStick = false;
|
||||
|
||||
// Check if we should stick to surface
|
||||
if (raycastInfos.HasHit && _noHitFrameCount[i] < _settings.StabilityFrames)
|
||||
{
|
||||
if (IsValidSurface(raycastInfos, i))
|
||||
{
|
||||
// Calculate target position on surface
|
||||
targetPos = armRig.Arm.Target.parent.InverseTransformPoint(raycastInfos.Position);
|
||||
|
||||
// Calculate target rotation aligned to surface
|
||||
targetRot = Quaternion.LookRotation(
|
||||
-armRig.Arm.Target.parent.InverseTransformDirection(raycastInfos.Normal),
|
||||
transform.up
|
||||
) * Quaternion.Euler(armRig.RotationOffset);
|
||||
|
||||
shouldStick = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Smooth stickiness transition
|
||||
float targetStickiness = shouldStick ? 1f : 0f;
|
||||
float stickinessSpeed = shouldStick ? _settings.StickSpeed : _settings.ReleaseSpeed;
|
||||
_currentStickiness[i] = Mathf.MoveTowards(_currentStickiness[i], targetStickiness, stickinessSpeed * Time.deltaTime);
|
||||
|
||||
// Apply distance-based stickiness factor (hysteresis)
|
||||
float distanceFactor = 0f;
|
||||
if (shouldStick && raycastInfos.HasHit)
|
||||
{
|
||||
distanceFactor = 1f - Mathf.InverseLerp(_settings.StickStartDistance, _settings.StickReleaseDistance, raycastInfos.Distance);
|
||||
distanceFactor = Mathf.Clamp01(distanceFactor);
|
||||
}
|
||||
|
||||
float finalStickiness = _currentStickiness[i] * distanceFactor;
|
||||
|
||||
// Calculate interpolation speeds
|
||||
float posSpeed = Mathf.Lerp(_settings.ReleaseSpeed, _settings.StickSpeed, finalStickiness);
|
||||
float rotSpeed = _settings.RotationSpeed * Mathf.Deg2Rad;
|
||||
|
||||
// Exponential smoothing for natural movement
|
||||
float tPos = 1f - Mathf.Exp(-posSpeed * Time.deltaTime);
|
||||
float tRot = 1f - Mathf.Exp(-rotSpeed * Time.deltaTime);
|
||||
|
||||
// Apply smooth interpolation
|
||||
armRig.Arm.Target.localPosition = Vector3.Lerp(armRig.Arm.Target.localPosition, targetPos, tPos);
|
||||
armRig.Arm.Target.localRotation = Quaternion.Slerp(armRig.Arm.Target.localRotation, targetRot, tRot);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the surface is valid for sticking
|
||||
private bool IsValidSurface(RaycastInfos raycast, int armIndex)
|
||||
{
|
||||
if (raycast.Transform == null)
|
||||
return false;
|
||||
|
||||
// Check surface angle (reject surfaces too angled)
|
||||
float surfaceAngle = Vector3.Angle(-raycast.Normal, transform.forward);
|
||||
if (surfaceAngle > _settings.MaxSurfaceAngle)
|
||||
return false;
|
||||
|
||||
// If not allowing both arms, check if arm is on correct side
|
||||
if (!_settings.AllowBothArms)
|
||||
{
|
||||
Vector3 hitLocalPos = transform.InverseTransformPoint(raycast.Position);
|
||||
bool isLeftSide = hitLocalPos.x < 0;
|
||||
bool isLeftArm = armIndex == 0;
|
||||
|
||||
if (isLeftSide != isLeftArm)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 97777a4e863d974428be79c0d8a40883
|
||||
@@ -0,0 +1,24 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 011e98eab6596764fac103ff106476e3, type: 3}
|
||||
m_Name: CamSettings
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Unheimlich.Data.PlayerSettings
|
||||
aimAssistStrength: 8
|
||||
aimAssistMaxAngle: 8
|
||||
shakeFrequency: 40
|
||||
idleBobSpeed: 1
|
||||
idleBobAmplitude: 0.005
|
||||
walkBobSpeed: 12
|
||||
walkBobAmplitude: 0.02
|
||||
runBobSpeed: 18
|
||||
runBobAmplitude: 0.03
|
||||
resetSpeed: 5
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 28f72f5bbd71f384a86c547567dbb5bf
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+504
-35
@@ -1,5 +1,36 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &517583305094533349
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 6579694192787271975}
|
||||
m_Layer: 0
|
||||
m_Name: InspectionHoldPoint
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &6579694192787271975
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 517583305094533349}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 1.166, z: 0.866}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 8725966219179855439}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &2101508725665932610
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -12,6 +43,7 @@ GameObject:
|
||||
- component: {fileID: 3666612565151794712}
|
||||
- component: {fileID: 6053283114444666027}
|
||||
- component: {fileID: 6989128982853398086}
|
||||
- component: {fileID: 522399111239992785}
|
||||
m_Layer: 0
|
||||
m_Name: Camera Player
|
||||
m_TagString: MainCamera
|
||||
@@ -27,12 +59,12 @@ Transform:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2101508725665932610}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 1.562, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 8725966219179855439}
|
||||
m_Father: {fileID: 4440040250278121308}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!20 &3666612565151794712
|
||||
Camera:
|
||||
@@ -137,6 +169,101 @@ MonoBehaviour:
|
||||
m_VarianceClampScale: 0.9
|
||||
m_ContrastAdaptiveSharpening: 0
|
||||
m_Version: 2
|
||||
--- !u!114 &522399111239992785
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2101508725665932610}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: d96ceb0ee513b1e4197e55e9b926269b, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Unheimlich.Interactions.Core.InteractionHandler
|
||||
_interactionRange: 5
|
||||
_interactableLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 8
|
||||
_raycastInterval: 0
|
||||
--- !u!1 &4625798697874999476
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1175390396199967368}
|
||||
m_Layer: 0
|
||||
m_Name: InspectionHoldPoint
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &1175390396199967368
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4625798697874999476}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0.43299997, z: 2}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4440040250278121308}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &5575782855984327677
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4440040250278121308}
|
||||
- component: {fileID: 986184075687059205}
|
||||
m_Layer: 0
|
||||
m_Name: CameraPivot
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &4440040250278121308
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5575782855984327677}
|
||||
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:
|
||||
- {fileID: 1836339402272228918}
|
||||
- {fileID: 1175390396199967368}
|
||||
- {fileID: 1104299543543969252}
|
||||
m_Father: {fileID: 8725966219179855439}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &986184075687059205
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5575782855984327677}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: a2e180d338cc26242a3a9d962eea7f7c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Unheimlich.Gameplay.Player.CameraHeadBob
|
||||
--- !u!1 &8162540767767967414
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -148,6 +275,14 @@ GameObject:
|
||||
- component: {fileID: 8725966219179855439}
|
||||
- component: {fileID: 1735456339091181674}
|
||||
- component: {fileID: 5295567073180248356}
|
||||
- component: {fileID: 688176918831081180}
|
||||
- component: {fileID: 3522630547589622128}
|
||||
- component: {fileID: 493263706218074437}
|
||||
- component: {fileID: 2525145087024189396}
|
||||
- component: {fileID: 3622123650942162330}
|
||||
- component: {fileID: 4152409555847978467}
|
||||
- component: {fileID: 6849123884232344894}
|
||||
- component: {fileID: 4281753130586762125}
|
||||
m_Layer: 0
|
||||
m_Name: OctoPlayerFP
|
||||
m_TagString: Player
|
||||
@@ -168,8 +303,9 @@ Transform:
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 1836339402272228918}
|
||||
- {fileID: 4440040250278121308}
|
||||
- {fileID: 2639365499984405449}
|
||||
- {fileID: 6579694192787271975}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!143 &1735456339091181674
|
||||
@@ -230,6 +366,162 @@ MonoBehaviour:
|
||||
SensitivityY: 0.1
|
||||
MinPitch: -80
|
||||
MaxPitch: 80
|
||||
--- !u!114 &688176918831081180
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8162540767767967414}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 2d192ca4042c25c4ea16f024d0e262c1, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Unheimlich.Gameplay.Player.PlayerController
|
||||
--- !u!114 &3522630547589622128
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8162540767767967414}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: e05e5ee4f09d55d4a93324fe0eb85d6e, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Unheimlich.Gameplay.Player.CameraEffects
|
||||
Settings: {fileID: 0}
|
||||
--- !u!114 &493263706218074437
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8162540767767967414}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 69e8150bab500424eb366f0ac8761995, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Unheimlich.Gameplay.CameraControl.CameraPanController
|
||||
_defaultSettings: {fileID: 11400000, guid: 9973a518f73c3c1489819494e37d0980, type: 2}
|
||||
--- !u!114 &2525145087024189396
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8162540767767967414}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 2094bd9c6f72e5b4cadf430f4d70f8f6, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Unheimlich.Gameplay.Player.DiapasonListeningHandler
|
||||
_diapasonObject: {fileID: 4171827204873703387}
|
||||
_diapasonAnimator: {fileID: 2521987284762225689}
|
||||
_listeningRange: 5
|
||||
_listenableLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
_concentrationDuration: 1
|
||||
_breathInDuration: 0.5
|
||||
_diapasonTweenDuration: 0.3
|
||||
_diapasonHideOffset: -0.5
|
||||
_diapasonTweenCurve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
- serializedVersion: 3
|
||||
time: 1
|
||||
value: 1
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
_vibrationDuration: 15
|
||||
_vignetteIntensity: 0.5
|
||||
_vignetteEffect: {fileID: 3622123650942162330}
|
||||
_handTouchFeedback: {fileID: 0}
|
||||
_diapasonParticles: {fileID: 8433960879374805761}
|
||||
_breathInClip: {fileID: 8300000, guid: 091b6df1c99cbd647bce921a5ba7c1af, type: 3}
|
||||
_diapasonTapClip: {fileID: 8300000, guid: 99100d62c8b5d264f8694516673a9eeb, type: 3}
|
||||
_diapasonTapVolume: 0.3
|
||||
_ambientAttenuationAmount: 0.3
|
||||
_audioFadeDuration: 0.5
|
||||
_touchDistance: 2
|
||||
--- !u!114 &3622123650942162330
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8162540767767967414}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 878ebc270c13e5c49a3813b1848f6ea5, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Unheimlich.Gameplay.Player.ListeningVignetteEffect
|
||||
_listeningVolume: {fileID: 0}
|
||||
_targetIntensity: 0.5
|
||||
_transitionSpeed: 2
|
||||
--- !u!114 &4152409555847978467
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8162540767767967414}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 464960797e705e84a9eb87ecce4e9311, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Unheimlich.Interactions.Core.PlayerInspectionHandler
|
||||
_inspectionHoldPoint: {fileID: 6579694192787271975}
|
||||
--- !u!114 &6849123884232344894
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8162540767767967414}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 9f9f72364623a2a4bb50f02537fd2e72, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Unheimlich.Gameplay.DetectiveBoard.DetectiveBoardController
|
||||
_boardCameraPanSettings: {fileID: 11400000, guid: f176d1f8c15496946994170f1b633061, type: 2}
|
||||
_activationRange: 2
|
||||
_boardLayer:
|
||||
serializedVersion: 2
|
||||
m_Bits: 128
|
||||
--- !u!114 &4281753130586762125
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8162540767767967414}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 39b78978d656e894ea455342398ef8ba, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Unheimlich.Gameplay.Player.HandTouchFeedback
|
||||
_feedbackImage: {fileID: 0}
|
||||
_readyColor: {r: 0, g: 1, b: 0, a: 1}
|
||||
_pulseSpeed: 2
|
||||
_pulseIntensity: 0.3
|
||||
--- !u!1001 &2564566619627430770
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -278,6 +570,14 @@ PrefabInstance:
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 880987313172909187, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: _leftArm.RotationOffset.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 880987313172909187, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: _rightArm.RotationOffset.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 899615586671794689, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Arms
|
||||
@@ -288,39 +588,39 @@ PrefabInstance:
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 905104535459292698, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: -0.2685
|
||||
value: -0.08000004
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 905104535459292698, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0.2737
|
||||
value: 0.371
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 905104535459292698, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: -0.3780753
|
||||
value: -0.25324655
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 905104535459292698, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0.44424582
|
||||
value: 0.52551085
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 905104535459292698, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: -0.5555247
|
||||
value: -0.38735777
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 905104535459292698, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0.5925345
|
||||
value: 0.7139038
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 905104535459292698, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 161.191
|
||||
value: 163.327
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 905104535459292698, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: -89.278015
|
||||
value: -98.862
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 905104535459292698, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 84.124
|
||||
value: 53.364
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2656140929319940858, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
@@ -346,61 +646,125 @@ PrefabInstance:
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 10
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3193146119612198720, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: -0.1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3193146119612198720, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 0.35385045
|
||||
value: 0.43294016
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3193146119612198720, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0.112266205
|
||||
value: 0.1385328
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3193146119612198720, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0.058453187
|
||||
value: 0.06752956
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3193146119612198720, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0.92669815
|
||||
value: 0.8881505
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3193146119612198720, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: -1.655
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3193146119612198720, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 14.451
|
||||
value: 17.731
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3193146119612198720, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 137.992
|
||||
value: 128.025
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4194213612049569317, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0.1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4194213612049569317, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 0.11226625
|
||||
value: 0.13853288
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4194213612049569317, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: -0.35385033
|
||||
value: -0.43293998
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4194213612049569317, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0.92669827
|
||||
value: 0.8881505
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4194213612049569317, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: -0.05845286
|
||||
value: -0.06752957
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4194213612049569317, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 1.655
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4194213612049569317, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 165.549
|
||||
value: 162.269
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4194213612049569317, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: -42.008
|
||||
value: -51.975
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5001575734268334496, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: -0.179
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5001575734268334496, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0.033
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5469352163685454240, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: -0.1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5469352163685454240, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5469352163685454240, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5469352163685454240, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5469352163685454240, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5469352163685454240, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6371905255704357408, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0.1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6371905255704357408, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6371905255704357408, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6371905255704357408, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6371905255704357408, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6371905255704357408, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6729180175069464909, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
@@ -408,39 +772,39 @@ PrefabInstance:
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6729180175069464909, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: -0.2685
|
||||
value: -0.08000004
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6729180175069464909, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0.2737
|
||||
value: 0.37100005
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6729180175069464909, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 0.44424608
|
||||
value: 0.5255113
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6729180175069464909, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0.37807533
|
||||
value: 0.25324643
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6729180175069464909, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0.59253436
|
||||
value: 0.71390367
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6729180175069464909, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0.5555246
|
||||
value: 0.38735744
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6729180175069464909, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 198.809
|
||||
value: 196.673
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6729180175069464909, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: -90.721985
|
||||
value: -81.138
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6729180175069464909, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: -95.87601
|
||||
value: -126.636
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6868471396772723999, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
@@ -492,3 +856,108 @@ Transform:
|
||||
m_CorrespondingSourceObject: {fileID: 520098895314436283, guid: 73480b78f75094a4da6b76dedb392ae9, type: 3}
|
||||
m_PrefabInstance: {fileID: 2564566619627430770}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!1001 &4716067031739800990
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
serializedVersion: 3
|
||||
m_TransformParent: {fileID: 4440040250278121308}
|
||||
m_Modifications:
|
||||
- target: {fileID: 2315210776226997430, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 0.75190187
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2315210776226997430, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: -0.13395086
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2315210776226997430, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: -0.6397146
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2315210776226997430, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: -0.08640652
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2315210776226997430, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: -18.179
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2315210776226997430, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: -81.182
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2315210776226997430, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 2.5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5629947512209565818, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0.78281003
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5629947512209565818, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: -0.6192932
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5629947512209565818, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 1.138
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5629947512209565818, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 0.9926423
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5629947512209565818, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: -0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5629947512209565818, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: -0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5629947512209565818, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0.121084325
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5629947512209565818, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5629947512209565818, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5629947512209565818, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 13.909
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 8689584738786529861, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Diapason
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_AddedGameObjects: []
|
||||
m_AddedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
--- !u!4 &1104299543543969252 stripped
|
||||
Transform:
|
||||
m_CorrespondingSourceObject: {fileID: 5629947512209565818, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
m_PrefabInstance: {fileID: 4716067031739800990}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!95 &2521987284762225689 stripped
|
||||
Animator:
|
||||
m_CorrespondingSourceObject: {fileID: 7173446854330675591, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
m_PrefabInstance: {fileID: 4716067031739800990}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!1 &4171827204873703387 stripped
|
||||
GameObject:
|
||||
m_CorrespondingSourceObject: {fileID: 8689584738786529861, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
m_PrefabInstance: {fileID: 4716067031739800990}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!198 &8433960879374805761 stripped
|
||||
ParticleSystem:
|
||||
m_CorrespondingSourceObject: {fileID: 3781237283850892959, guid: 2812cddb6de789b46ac9d640bb9ce410, type: 3}
|
||||
m_PrefabInstance: {fileID: 4716067031739800990}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
|
||||
@@ -74,7 +74,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 899c54efeace73346a0a16faa3afe726, type: 3}
|
||||
m_Name: Vignette
|
||||
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.Vignette
|
||||
active: 0
|
||||
active: 1
|
||||
color:
|
||||
m_OverrideState: 0
|
||||
m_Value: {r: 0, g: 0, b: 0, a: 1}
|
||||
@@ -83,7 +83,7 @@ MonoBehaviour:
|
||||
m_Value: {x: 0.5, y: 0.5}
|
||||
intensity:
|
||||
m_OverrideState: 1
|
||||
m_Value: 0.444
|
||||
m_Value: 0.423
|
||||
smoothness:
|
||||
m_OverrideState: 1
|
||||
m_Value: 1
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,41 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unheimlich.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Central event system for player actions.
|
||||
/// Decouples player components from each other.
|
||||
/// </summary>
|
||||
public static class PlayerEvents
|
||||
{
|
||||
// Movement events
|
||||
public static event System.Action OnJump;
|
||||
public static event System.Action<Vector3, Quaternion> OnTeleport;
|
||||
|
||||
// Camera events
|
||||
public static event System.Action<float> OnCameraShake;
|
||||
|
||||
// Diapason events
|
||||
public static event System.Action OnDiapasonEquip;
|
||||
public static event System.Action OnDiapasonUnequip;
|
||||
public static event System.Action OnDiapasonTap;
|
||||
|
||||
// Context events
|
||||
public static event System.Action OnEnterDialogue;
|
||||
public static event System.Action OnExitDialogue;
|
||||
public static event System.Action OnEnterListening;
|
||||
public static event System.Action OnExitListening;
|
||||
|
||||
// Trigger methods
|
||||
public static void TriggerJump() => OnJump?.Invoke();
|
||||
public static void TriggerTeleport(Vector3 position, Quaternion rotation) => OnTeleport?.Invoke(position, rotation);
|
||||
public static void TriggerCameraShake(float intensity) => OnCameraShake?.Invoke(intensity);
|
||||
public static void TriggerDiapasonEquip() => OnDiapasonEquip?.Invoke();
|
||||
public static void TriggerDiapasonUnequip() => OnDiapasonUnequip?.Invoke();
|
||||
public static void TriggerDiapasonTap() => OnDiapasonTap?.Invoke();
|
||||
public static void TriggerEnterDialogue() => OnEnterDialogue?.Invoke();
|
||||
public static void TriggerExitDialogue() => OnExitDialogue?.Invoke();
|
||||
public static void TriggerEnterListening() => OnEnterListening?.Invoke();
|
||||
public static void TriggerExitListening() => OnExitListening?.Invoke();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82279ebe597d0b84eb1f7ab31139587d
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ca9f0ebb935bc2e4eab3700478b41297
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,30 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unheimlich.Data
|
||||
{
|
||||
[CreateAssetMenu(fileName = "CameraEffectsSettings", menuName = "Unheimlich/Camera Effects Settings")]
|
||||
public class CameraEffectsSettings : ScriptableObject
|
||||
{
|
||||
[Header("Aim Assist")]
|
||||
public float aimAssistStrength = 25f;
|
||||
public float aimAssistMaxAngle = 10f;
|
||||
|
||||
[Header("Camera Shake")]
|
||||
public float shakeFrequency = 40f;
|
||||
|
||||
[Header("Head Bob - Idle")]
|
||||
public float idleBobSpeed = 1f;
|
||||
public float idleBobAmplitude = 0.005f;
|
||||
|
||||
[Header("Head Bob - Walk")]
|
||||
public float walkBobSpeed = 12f;
|
||||
public float walkBobAmplitude = 0.02f;
|
||||
|
||||
[Header("Head Bob - Run")]
|
||||
public float runBobSpeed = 18f;
|
||||
public float runBobAmplitude = 0.03f;
|
||||
|
||||
[Header("Head Bob - General")]
|
||||
public float resetSpeed = 5f;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 011e98eab6596764fac103ff106476e3
|
||||
@@ -2,27 +2,22 @@ using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using Unheimlich.Data.CameraSettings;
|
||||
using PlayerInput = Unheimlich.Managers.PlayerInputManager;
|
||||
using Unheimlich.Gameplay.Player;
|
||||
using InputManager = Unheimlich.Managers.InputManager;
|
||||
|
||||
namespace Unheimlich.Gameplay.CameraControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles camera panning and player/camera alignment to targets.
|
||||
/// Uses CameraPanSettings ScriptableObject for configuration.
|
||||
/// Supports two modes:
|
||||
/// - Pan: Smooth panning with edge detection (for object inspection)
|
||||
/// - FreeLook: Direct mouse/stick control with angle clamping (for detective board)
|
||||
/// </summary>
|
||||
public class CameraPanController : MonoBehaviour
|
||||
{
|
||||
[Header("References")]
|
||||
[SerializeField] private UnityEngine.Camera _camera;
|
||||
[SerializeField] private Transform _playerTransform;
|
||||
|
||||
[Header("Default Settings")]
|
||||
[SerializeField] private CameraPanSettings _defaultSettings;
|
||||
|
||||
private CameraPanSettings _settings;
|
||||
private UnityEngine.Camera _camera;
|
||||
private Transform _playerTransform;
|
||||
|
||||
private Vector2 _originalCameraRotation;
|
||||
private Vector3 _originalCameraLocalPosition;
|
||||
@@ -53,11 +48,25 @@ namespace Unheimlich.Gameplay.CameraControl
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (_camera == null)
|
||||
_camera = UnityEngine.Camera.main;
|
||||
// Defer initialization if PlayerController not ready
|
||||
if (PlayerController.Instance != null)
|
||||
{
|
||||
_camera = PlayerController.Instance.PlayerCamera;
|
||||
_playerTransform = PlayerController.Instance.transform;
|
||||
}
|
||||
|
||||
if (_playerTransform == null)
|
||||
_playerTransform = transform;
|
||||
if (_defaultSettings != null)
|
||||
_settings = _defaultSettings;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// Retry if not initialized in Awake
|
||||
if (_camera == null && PlayerController.Instance != null)
|
||||
{
|
||||
_camera = PlayerController.Instance.PlayerCamera;
|
||||
_playerTransform = PlayerController.Instance.transform;
|
||||
}
|
||||
|
||||
if (_camera != null)
|
||||
{
|
||||
@@ -65,7 +74,8 @@ namespace Unheimlich.Gameplay.CameraControl
|
||||
_originalCameraLocalRotation = _camera.transform.localEulerAngles;
|
||||
}
|
||||
|
||||
_originalPlayerPosition = _playerTransform.position;
|
||||
if (_playerTransform != null)
|
||||
_originalPlayerPosition = _playerTransform.position;
|
||||
_originalPlayerRotation = _playerTransform.eulerAngles;
|
||||
|
||||
if (_settings == null && _defaultSettings != null)
|
||||
@@ -132,9 +142,6 @@ namespace Unheimlich.Gameplay.CameraControl
|
||||
_needsUpdate = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops camera pan mode and returns to original state.
|
||||
/// </summary>
|
||||
public void StopPan()
|
||||
{
|
||||
IsPanning = false;
|
||||
@@ -165,7 +172,7 @@ namespace Unheimlich.Gameplay.CameraControl
|
||||
float lookY = 0f;
|
||||
bool hasInput = false;
|
||||
|
||||
var lookAction = PlayerInput.GetLookAction();
|
||||
var lookAction = InputManager.GetLookAction();
|
||||
if (lookAction != null)
|
||||
{
|
||||
Vector2 lookInput = lookAction.ReadValue<Vector2>();
|
||||
@@ -199,7 +206,7 @@ namespace Unheimlich.Gameplay.CameraControl
|
||||
float panY = 0f;
|
||||
bool hasInput = false;
|
||||
|
||||
var lookAction = PlayerInput.GetLookAction();
|
||||
var lookAction = InputManager.GetLookAction();
|
||||
if (lookAction != null)
|
||||
{
|
||||
Vector2 lookInput = lookAction.ReadValue<Vector2>();
|
||||
|
||||
@@ -1,43 +1,30 @@
|
||||
using UnityEngine;
|
||||
using Unheimlich.Core;
|
||||
using Unheimlich.Data.CameraSettings;
|
||||
using Unheimlich.Gameplay.CameraControl;
|
||||
using Unheimlich.Gameplay.Player;
|
||||
using PlayerInput = Unheimlich.Managers.PlayerInputManager;
|
||||
using InputManager = Unheimlich.Managers.InputManager;
|
||||
using Unheimlich.UI.DetectiveBoard;
|
||||
|
||||
namespace Unheimlich.Gameplay.DetectiveBoard
|
||||
{
|
||||
/// <summary>
|
||||
/// Controls player interaction with the detective board in world space.
|
||||
/// Uses CameraPanController for wide-angle camera movement across the board.
|
||||
/// Activates when player is in range and looking at the board.
|
||||
/// Controls player interaction with the detective board.
|
||||
/// </summary>
|
||||
public class DetectiveBoardController : MonoBehaviour
|
||||
public class DetectiveBoardController : Singleton<DetectiveBoardController>
|
||||
{
|
||||
[Header("References")]
|
||||
[SerializeField] private CameraPanController _cameraPanController;
|
||||
[SerializeField] private Transform _boardTransform;
|
||||
|
||||
[Header("Settings")]
|
||||
[SerializeField] private CameraPanSettings _boardCameraPanSettings;
|
||||
[SerializeField] private float _activationRange = 2f;
|
||||
[SerializeField] private LayerMask _boardLayer;
|
||||
|
||||
private Camera _playerCamera;
|
||||
private bool _isBoardActive;
|
||||
private CameraPanSettings _originalCameraPanSettings;
|
||||
private CameraHeadBob _cameraHeadBob;
|
||||
|
||||
public bool IsBoardActive => _isBoardActive;
|
||||
|
||||
private void Awake()
|
||||
protected override void OnAwake()
|
||||
{
|
||||
_playerCamera = Camera.main;
|
||||
|
||||
if (_cameraPanController == null)
|
||||
{
|
||||
_cameraPanController = FindFirstObjectByType<CameraPanController>();
|
||||
}
|
||||
|
||||
_cameraHeadBob = FindFirstObjectByType<CameraHeadBob>();
|
||||
}
|
||||
|
||||
@@ -53,24 +40,30 @@ namespace Unheimlich.Gameplay.DetectiveBoard
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if player is looking at the board and in range to activate.
|
||||
/// </summary>
|
||||
private void CheckForBoardActivation()
|
||||
{
|
||||
if (_playerCamera == null || _boardTransform == null)
|
||||
if (PlayerController.Instance == null ||
|
||||
PlayerController.Instance.PlayerCamera == null ||
|
||||
DetectiveBoardCanvas.Instance == null)
|
||||
return;
|
||||
|
||||
float distanceToBoard = Vector3.Distance(_playerCamera.transform.position, _boardTransform.position);
|
||||
var camera = PlayerController.Instance.PlayerCamera;
|
||||
var boardTransform = DetectiveBoardCanvas.Instance.transform;
|
||||
|
||||
float distanceToBoard = Vector3.Distance(camera.transform.position, boardTransform.position);
|
||||
if (distanceToBoard > _activationRange)
|
||||
return;
|
||||
|
||||
Ray ray = new Ray(_playerCamera.transform.position, _playerCamera.transform.forward);
|
||||
Ray ray = new Ray(camera.transform.position, camera.transform.forward);
|
||||
if (Physics.Raycast(ray, out RaycastHit hit, _activationRange, _boardLayer))
|
||||
{
|
||||
if (hit.transform.IsChildOf(_boardTransform) || hit.transform == _boardTransform)
|
||||
bool isLookingAtBoard = (hit.transform == boardTransform) ||
|
||||
(boardTransform.IsChildOf(hit.transform)) ||
|
||||
(hit.transform.IsChildOf(boardTransform));
|
||||
|
||||
if (isLookingAtBoard)
|
||||
{
|
||||
var interactAction = PlayerInput.GetInteractAction();
|
||||
var interactAction = InputManager.GetInteractAction();
|
||||
if (interactAction != null && interactAction.WasPressedThisFrame())
|
||||
{
|
||||
ActivateBoard();
|
||||
@@ -79,12 +72,12 @@ namespace Unheimlich.Gameplay.DetectiveBoard
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Activates the detective board, switching to pan mode with wide-angle settings.
|
||||
/// </summary>
|
||||
public void ActivateBoard()
|
||||
{
|
||||
if (_cameraPanController == null || _boardCameraPanSettings == null)
|
||||
if (_isBoardActive ||
|
||||
PlayerController.Instance?.CameraPanController == null ||
|
||||
DetectiveBoardCanvas.Instance == null ||
|
||||
_boardCameraPanSettings == null)
|
||||
{
|
||||
Debug.LogError("[DetectiveBoardController] Missing required references!");
|
||||
return;
|
||||
@@ -92,71 +85,73 @@ namespace Unheimlich.Gameplay.DetectiveBoard
|
||||
|
||||
_isBoardActive = true;
|
||||
|
||||
_originalCameraPanSettings = _cameraPanController.Settings;
|
||||
_cameraPanController.Settings = _boardCameraPanSettings;
|
||||
|
||||
_cameraPanController.SaveOriginalState();
|
||||
_cameraPanController.AlignToTarget(_boardTransform, () =>
|
||||
// Disable OctoPlayer completely to prevent ANY input processing
|
||||
if (PlayerController.Instance.Movement != null)
|
||||
{
|
||||
_cameraPanController.StartPan();
|
||||
});
|
||||
|
||||
PlayerInput.SetContext(PlayerInput.InputContext.Listening);
|
||||
|
||||
ApplyHeadBobSettings(_boardCameraPanSettings);
|
||||
|
||||
Debug.Log("[DetectiveBoardController] Detective board activated");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles board interaction while active (panning and exit).
|
||||
/// </summary>
|
||||
private void HandleBoardInteraction()
|
||||
{
|
||||
if (_cameraPanController != null)
|
||||
{
|
||||
_cameraPanController.UpdatePan();
|
||||
PlayerController.Instance.Movement.enabled = false;
|
||||
}
|
||||
|
||||
var exitAction = PlayerInput.GetExitAction();
|
||||
var cameraPan = PlayerController.Instance.CameraPanController;
|
||||
_originalCameraPanSettings = cameraPan.Settings;
|
||||
cameraPan.Settings = _boardCameraPanSettings;
|
||||
|
||||
// Save state for return (before alignment)
|
||||
cameraPan.SaveOriginalState();
|
||||
|
||||
// Align to target, then start pan AFTER alignment completes
|
||||
cameraPan.AlignToTarget(DetectiveBoardCanvas.Instance.transform, () =>
|
||||
{
|
||||
// NOW start pan using the aligned rotation as base
|
||||
cameraPan.StartPan();
|
||||
});
|
||||
|
||||
InputManager.SetContext(InputManager.InputContext.Listening);
|
||||
|
||||
ApplyHeadBobSettings(_boardCameraPanSettings);
|
||||
}
|
||||
|
||||
private void HandleBoardInteraction()
|
||||
{
|
||||
if (PlayerController.Instance?.CameraPanController != null)
|
||||
{
|
||||
PlayerController.Instance.CameraPanController.UpdatePan();
|
||||
}
|
||||
|
||||
var exitAction = InputManager.GetExitAction();
|
||||
if (exitAction != null && exitAction.WasPressedThisFrame())
|
||||
{
|
||||
DeactivateBoard();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deactivates the board and returns to normal gameplay.
|
||||
/// </summary>
|
||||
public void DeactivateBoard()
|
||||
{
|
||||
if (!_isBoardActive)
|
||||
if (!_isBoardActive || PlayerController.Instance?.CameraPanController == null)
|
||||
return;
|
||||
|
||||
_isBoardActive = false;
|
||||
|
||||
if (_cameraPanController != null)
|
||||
var cameraPan = PlayerController.Instance.CameraPanController;
|
||||
cameraPan.StopPan();
|
||||
cameraPan.ReturnToOriginalPosition(() =>
|
||||
{
|
||||
_cameraPanController.StopPan();
|
||||
_cameraPanController.ReturnToOriginalPosition(() =>
|
||||
if (_originalCameraPanSettings != null)
|
||||
{
|
||||
if (_originalCameraPanSettings != null)
|
||||
{
|
||||
_cameraPanController.Settings = _originalCameraPanSettings;
|
||||
}
|
||||
});
|
||||
}
|
||||
cameraPan.Settings = _originalCameraPanSettings;
|
||||
}
|
||||
|
||||
PlayerInput.SetContext(PlayerInput.InputContext.Normal);
|
||||
// Re-enable OctoPlayer AFTER the return animation completes
|
||||
if (PlayerController.Instance?.Movement != null)
|
||||
{
|
||||
PlayerController.Instance.Movement.enabled = true;
|
||||
}
|
||||
});
|
||||
|
||||
InputManager.SetContext(InputManager.InputContext.Normal);
|
||||
|
||||
RestoreHeadBob();
|
||||
|
||||
Debug.Log("[DetectiveBoardController] Detective board deactivated");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies head bob settings based on CameraPanSettings configuration.
|
||||
/// </summary>
|
||||
private void ApplyHeadBobSettings(CameraPanSettings settings)
|
||||
{
|
||||
if (_cameraHeadBob == null || settings == null)
|
||||
@@ -165,9 +160,6 @@ namespace Unheimlich.Gameplay.DetectiveBoard
|
||||
_cameraHeadBob.SetMode(settings.HeadBobMode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restores head bob to normal behavior.
|
||||
/// </summary>
|
||||
private void RestoreHeadBob()
|
||||
{
|
||||
if (_cameraHeadBob == null)
|
||||
@@ -178,11 +170,11 @@ namespace Unheimlich.Gameplay.DetectiveBoard
|
||||
|
||||
private void OnDrawGizmosSelected()
|
||||
{
|
||||
if (_boardTransform == null)
|
||||
if (DetectiveBoardCanvas.Instance == null)
|
||||
return;
|
||||
|
||||
Gizmos.color = _isBoardActive ? Color.green : Color.yellow;
|
||||
Gizmos.DrawWireSphere(_boardTransform.position, _activationRange);
|
||||
Gizmos.DrawWireSphere(DetectiveBoardCanvas.Instance.transform.position, _activationRange);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using Unheimlich.Data;
|
||||
using Unheimlich.Managers;
|
||||
|
||||
namespace Unheimlich.Gameplay.Player
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles camera effects: aim assist and shake.
|
||||
/// </summary>
|
||||
public class CameraEffects : MonoBehaviour
|
||||
{
|
||||
[Header("Settings")]
|
||||
public CameraEffectsSettings Settings;
|
||||
|
||||
private float _shakeTimer = 0f;
|
||||
private float _shakeInterval;
|
||||
private Vector3 _shakeTarget;
|
||||
private Vector3 _shakeOriginalPos;
|
||||
private float _shakeSmoothness;
|
||||
private Vector3 _pendingAimAssistTarget;
|
||||
private bool _hasAimAssistTarget;
|
||||
|
||||
public bool IsAimLocked { get; private set; }
|
||||
public bool HasActiveLookInput { get; private set; }
|
||||
public bool IsUsingGamepad { get; private set; }
|
||||
|
||||
void Start()
|
||||
{
|
||||
if (Settings != null)
|
||||
_shakeInterval = 1f / Settings.shakeFrequency;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
DetectInputDevice();
|
||||
}
|
||||
|
||||
void LateUpdate()
|
||||
{
|
||||
if (_hasAimAssistTarget)
|
||||
{
|
||||
ApplyAimAssistInternal(_pendingAimAssistTarget);
|
||||
}
|
||||
}
|
||||
|
||||
private void DetectInputDevice()
|
||||
{
|
||||
Vector2 lookInput = InputManager.GetLookInput();
|
||||
HasActiveLookInput = lookInput.magnitude > 0.1f;
|
||||
|
||||
if (Gamepad.current != null && Gamepad.current.rightStick.ReadValue().magnitude > 0.1f)
|
||||
IsUsingGamepad = true;
|
||||
else if (Mouse.current != null && Mouse.current.delta.ReadValue().magnitude > 0.1f)
|
||||
IsUsingGamepad = false;
|
||||
}
|
||||
|
||||
public void ShakeCamera(float amplitude, float smoothness = 0f)
|
||||
{
|
||||
if (PlayerController.Instance == null || PlayerController.Instance.CameraPivot == null || Settings == null)
|
||||
return;
|
||||
|
||||
_shakeSmoothness = smoothness;
|
||||
_shakeTimer -= Time.deltaTime;
|
||||
|
||||
if (_shakeTimer <= 0f)
|
||||
{
|
||||
_shakeTimer = _shakeInterval * amplitude;
|
||||
_shakeOriginalPos = PlayerController.Instance.CameraPivot.position;
|
||||
|
||||
float x = Random.Range(-1f, 1f) * amplitude;
|
||||
float y = Random.Range(-1f, 1f) * amplitude;
|
||||
|
||||
_shakeTarget = _shakeOriginalPos + new Vector3(x, y, 0f);
|
||||
}
|
||||
|
||||
if (_shakeSmoothness > 0f)
|
||||
{
|
||||
PlayerController.Instance.CameraPivot.position = Vector3.Lerp(
|
||||
PlayerController.Instance.CameraPivot.position,
|
||||
_shakeTarget,
|
||||
Time.deltaTime * _shakeSmoothness);
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayerController.Instance.CameraPivot.position = _shakeTarget;
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyAimAssist(Vector3 targetCenter)
|
||||
{
|
||||
_pendingAimAssistTarget = targetCenter;
|
||||
_hasAimAssistTarget = true;
|
||||
}
|
||||
|
||||
private void ApplyAimAssistInternal(Vector3 targetCenter)
|
||||
{
|
||||
if (PlayerController.Instance == null || PlayerController.Instance.CameraTransform == null || Settings == null)
|
||||
return;
|
||||
|
||||
if (PlayerController.Instance.Movement == null)
|
||||
return;
|
||||
|
||||
if (IsAimLocked && HasActiveLookInput)
|
||||
IsAimLocked = false;
|
||||
|
||||
Vector3 directionToTarget = (targetCenter - PlayerController.Instance.CameraTransform.position).normalized;
|
||||
float angleError = Vector3.Angle(PlayerController.Instance.CameraTransform.forward, directionToTarget);
|
||||
|
||||
if (IsAimLocked || angleError < Settings.aimAssistMaxAngle)
|
||||
{
|
||||
Vector3 targetDirection = directionToTarget;
|
||||
float targetYaw = Mathf.Atan2(targetDirection.x, targetDirection.z) * Mathf.Rad2Deg;
|
||||
float targetPitch = -Mathf.Asin(targetDirection.y) * Mathf.Rad2Deg;
|
||||
|
||||
float currentYaw = PlayerController.Instance.Movement.Yaw;
|
||||
float currentPitch = PlayerController.Instance.Movement.Pitch;
|
||||
|
||||
float newYaw = Mathf.LerpAngle(currentYaw, targetYaw, Settings.aimAssistStrength * Time.deltaTime);
|
||||
float newPitch = Mathf.Lerp(currentPitch, targetPitch, Settings.aimAssistStrength * Time.deltaTime);
|
||||
|
||||
PlayerController.Instance.Movement.Yaw = newYaw;
|
||||
PlayerController.Instance.Movement.Pitch = newPitch;
|
||||
}
|
||||
|
||||
_hasAimAssistTarget = false;
|
||||
}
|
||||
|
||||
public void LockAim(bool locked)
|
||||
{
|
||||
IsAimLocked = locked;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e05e5ee4f09d55d4a93324fe0eb85d6e
|
||||
@@ -6,20 +6,9 @@ namespace Unheimlich.Gameplay.Player
|
||||
{
|
||||
/// <summary>
|
||||
/// Simulates camera head bobbing motion during player movement and idle states.
|
||||
/// Applies subtle oscillation based on player grounded and movement state.
|
||||
/// </summary>
|
||||
public class CameraHeadBob : MonoBehaviour
|
||||
{
|
||||
[Header("Bob Settings - Idle")]
|
||||
[SerializeField] private float _idleBobSpeed = 1f;
|
||||
[SerializeField] private float _idleBobAmplitude = 0.005f;
|
||||
|
||||
[Header("Bob Settings - Walk")]
|
||||
[SerializeField] private float _walkBobSpeed = 12f;
|
||||
[SerializeField] private float _walkBobAmplitude = 0.02f;
|
||||
[SerializeField] private float _resetSpeed = 5f;
|
||||
|
||||
private PlayerMovement _playerMovement;
|
||||
private float _timer = 0f;
|
||||
private Vector3 _startLocalPos;
|
||||
|
||||
@@ -29,55 +18,57 @@ namespace Unheimlich.Gameplay.Player
|
||||
|
||||
void Start()
|
||||
{
|
||||
_playerMovement = PlayerMovement.Instance;
|
||||
_startLocalPos = transform.localPosition;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (_playerMovement == null || _playerMovement.CharacterController == null)
|
||||
if (PlayerController.Instance == null || PlayerController.Instance.CharController == null)
|
||||
return;
|
||||
|
||||
var settings = PlayerController.Instance.CameraEffects?.Settings;
|
||||
if (settings == null) return;
|
||||
|
||||
HeadBobMode currentMode = _hasOverride ? _overrideMode : HeadBobMode.Normal;
|
||||
|
||||
if (currentMode == HeadBobMode.Disabled)
|
||||
{
|
||||
ResetPosition();
|
||||
ResetPosition(settings.resetSpeed);
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentMode == HeadBobMode.Idle || (PlayerInspectionHandler.Instance != null && PlayerInspectionHandler.Instance.IsInspecting))
|
||||
{
|
||||
ApplyBob(_idleBobSpeed, _idleBobAmplitude);
|
||||
ApplyBob(settings.idleBobSpeed, settings.idleBobAmplitude);
|
||||
return;
|
||||
}
|
||||
|
||||
bool isMoving = _playerMovement.IsMoving;
|
||||
bool isGrounded = _playerMovement.CharacterController.isGrounded;
|
||||
bool isMoving = PlayerController.Instance.IsMoving;
|
||||
bool isRunning = PlayerController.Instance.IsRunning;
|
||||
bool isGrounded = PlayerController.Instance.CharController.isGrounded;
|
||||
|
||||
if (isGrounded)
|
||||
{
|
||||
if (isMoving)
|
||||
ApplyBob(_walkBobSpeed, _walkBobAmplitude);
|
||||
{
|
||||
if (isRunning)
|
||||
ApplyBob(settings.runBobSpeed, settings.runBobAmplitude);
|
||||
else
|
||||
ApplyBob(settings.walkBobSpeed, settings.walkBobAmplitude);
|
||||
}
|
||||
else
|
||||
ApplyBob(_idleBobSpeed, _idleBobAmplitude);
|
||||
ApplyBob(settings.idleBobSpeed, settings.idleBobAmplitude);
|
||||
}
|
||||
else
|
||||
ResetPosition();
|
||||
ResetPosition(settings.resetSpeed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the head bob mode override.
|
||||
/// </summary>
|
||||
public void SetMode(HeadBobMode mode)
|
||||
{
|
||||
_overrideMode = mode;
|
||||
_hasOverride = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the override and returns to normal behavior.
|
||||
/// </summary>
|
||||
public void ClearOverride()
|
||||
{
|
||||
_hasOverride = false;
|
||||
@@ -89,9 +80,6 @@ namespace Unheimlich.Gameplay.Player
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Smoothly lerps the head bob position to zero over the specified duration.
|
||||
/// </summary>
|
||||
public void LerpToZero(float duration)
|
||||
{
|
||||
if (_resetCoroutine != null)
|
||||
@@ -131,9 +119,9 @@ namespace Unheimlich.Gameplay.Player
|
||||
transform.localPosition = newPos;
|
||||
}
|
||||
|
||||
private void ResetPosition()
|
||||
private void ResetPosition(float resetSpeed)
|
||||
{
|
||||
transform.localPosition = Vector3.Lerp(transform.localPosition, _startLocalPos, Time.deltaTime * _resetSpeed);
|
||||
transform.localPosition = Vector3.Lerp(transform.localPosition, _startLocalPos, Time.deltaTime * resetSpeed);
|
||||
|
||||
if (Vector3.Distance(transform.localPosition, _startLocalPos) < 0.001f)
|
||||
_timer = 0f;
|
||||
|
||||
+61
-32
@@ -7,19 +7,12 @@ using Unheimlich.Utility;
|
||||
using Unheimlich.Gameplay.Player;
|
||||
using Unheimlich.Gameplay.CameraControl;
|
||||
using Unheimlich.Data.CameraSettings;
|
||||
using InputManager = Unheimlich.Managers.PlayerInputManager;
|
||||
using InputManager = Unheimlich.Managers.InputManager;
|
||||
|
||||
namespace Unheimlich.Gameplay.Player
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages the tuning fork (diapason) listening mechanic.
|
||||
/// Handles:
|
||||
/// - Equipping/unequipping the diapason with tween animations
|
||||
/// - Concentration phase (breathing sound and duration)
|
||||
/// - Listening mode with camera pan control (via CameraPanController)
|
||||
/// - Tapping the diapason on listenable objects
|
||||
/// - Visual feedback (vignette, cursor, particles)
|
||||
/// - Preventing multiple taps on the same emitter
|
||||
/// </summary>
|
||||
public class DiapasonListeningHandler : Singleton<DiapasonListeningHandler>
|
||||
{
|
||||
@@ -29,8 +22,7 @@ namespace Unheimlich.Gameplay.Player
|
||||
[Header("References")]
|
||||
[SerializeField] private GameObject _diapasonObject;
|
||||
[SerializeField] private Animator _diapasonAnimator;
|
||||
[SerializeField] private UnityEngine.Camera _playerCamera;
|
||||
[SerializeField] private CameraPanController _cameraPanController;
|
||||
private CameraPanController _cameraPanController;
|
||||
|
||||
[Header("Listening Settings")]
|
||||
[SerializeField] private float _listeningRange = 5f;
|
||||
@@ -85,13 +77,20 @@ namespace Unheimlich.Gameplay.Player
|
||||
if (_playerAudioSource == null)
|
||||
_playerAudioSource = gameObject.AddComponent<AudioSource>();
|
||||
|
||||
|
||||
_cameraPanController = GetComponent<CameraPanController>();
|
||||
if (_cameraPanController == null)
|
||||
{
|
||||
_cameraPanController = GetComponent<CameraPanController>();
|
||||
if (_cameraPanController == null)
|
||||
Debug.LogWarning("[Diapason] CameraPanController not found! Adding one automatically.");
|
||||
_cameraPanController = gameObject.AddComponent<CameraPanController>();
|
||||
}
|
||||
|
||||
if (_vignetteEffect == null)
|
||||
{
|
||||
_vignetteEffect = GetComponentInChildren<ListeningVignetteEffect>();
|
||||
if (_vignetteEffect == null)
|
||||
{
|
||||
Debug.LogWarning("[Diapason] CameraPanController not found! Adding one automatically.");
|
||||
_cameraPanController = gameObject.AddComponent<CameraPanController>();
|
||||
Debug.LogError("[Diapason] ListeningVignetteEffect not found! Vignette won't work.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,10 +149,10 @@ namespace Unheimlich.Gameplay.Player
|
||||
|
||||
private void CheckForNearbyEmitter()
|
||||
{
|
||||
if (_playerCamera == null)
|
||||
if (PlayerController.Instance == null || PlayerController.Instance.PlayerCamera == null)
|
||||
return;
|
||||
|
||||
Ray ray = _playerCamera.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));
|
||||
Ray ray = PlayerController.Instance.PlayerCamera.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));
|
||||
|
||||
if (Physics.Raycast(ray, out RaycastHit hit, _listeningRange, _listenableLayers))
|
||||
{
|
||||
@@ -239,6 +238,12 @@ namespace Unheimlich.Gameplay.Player
|
||||
IsConcentrating = true;
|
||||
InputManager.SetContext(InputManager.InputContext.Listening);
|
||||
|
||||
// IMMEDIATELY disable OctoPlayer to prevent any player movement
|
||||
if (PlayerController.Instance?.Movement != null)
|
||||
{
|
||||
PlayerController.Instance.Movement.enabled = false;
|
||||
}
|
||||
|
||||
if (_currentTargetEmitter != null && _cameraPanController != null)
|
||||
{
|
||||
_originalCameraSettings = _cameraPanController.Settings;
|
||||
@@ -247,7 +252,16 @@ namespace Unheimlich.Gameplay.Player
|
||||
|
||||
_currentTargetEmitter.SetConcentrating(true);
|
||||
|
||||
_cameraPanController.AlignToTarget(_currentTargetEmitter.transform);
|
||||
// Save state for return (before alignment)
|
||||
_cameraPanController.SaveOriginalState();
|
||||
|
||||
// Align camera first, then start pan AFTER alignment
|
||||
_cameraPanController.AlignToTarget(_currentTargetEmitter.transform, () =>
|
||||
{
|
||||
// NOW start pan using the aligned rotation as base
|
||||
_cameraPanController.StartPan();
|
||||
});
|
||||
|
||||
yield return new WaitForSeconds(1f / 3f);
|
||||
}
|
||||
|
||||
@@ -287,8 +301,8 @@ namespace Unheimlich.Gameplay.Player
|
||||
EnableVignette(true);
|
||||
|
||||
ApplyHeadBobSettings(_cameraPanController.Settings);
|
||||
_cameraPanController.StartPan();
|
||||
|
||||
// Pan is already active from the beginning of the sequence
|
||||
|
||||
Cursor.lockState = CursorLockMode.Confined;
|
||||
Cursor.visible = false;
|
||||
@@ -324,12 +338,27 @@ namespace Unheimlich.Gameplay.Player
|
||||
if (_cameraPanController != null)
|
||||
{
|
||||
_cameraPanController.StopPan();
|
||||
_cameraPanController.ReturnToOriginalPosition();
|
||||
|
||||
if (_originalCameraSettings != null)
|
||||
_cameraPanController.ReturnToOriginalPosition(() =>
|
||||
{
|
||||
_cameraPanController.Settings = _originalCameraSettings;
|
||||
_originalCameraSettings = null;
|
||||
if (_originalCameraSettings != null)
|
||||
{
|
||||
_cameraPanController.Settings = _originalCameraSettings;
|
||||
_originalCameraSettings = null;
|
||||
}
|
||||
|
||||
// Re-enable OctoPlayer AFTER the return animation completes
|
||||
if (PlayerController.Instance?.Movement != null)
|
||||
{
|
||||
PlayerController.Instance.Movement.enabled = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// If no camera pan controller, re-enable immediately
|
||||
if (PlayerController.Instance?.Movement != null)
|
||||
{
|
||||
PlayerController.Instance.Movement.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -413,10 +442,10 @@ namespace Unheimlich.Gameplay.Player
|
||||
/// </summary>
|
||||
private void CheckForListenableObject()
|
||||
{
|
||||
if (_playerCamera == null)
|
||||
if (PlayerController.Instance == null || PlayerController.Instance.PlayerCamera == null)
|
||||
return;
|
||||
|
||||
Ray ray = _playerCamera.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));
|
||||
Ray ray = PlayerController.Instance.PlayerCamera.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));
|
||||
|
||||
if (Physics.Raycast(ray, out RaycastHit hit, _listeningRange, _listenableLayers))
|
||||
{
|
||||
@@ -544,11 +573,11 @@ namespace Unheimlich.Gameplay.Player
|
||||
|
||||
private void EnableVignette(bool enable)
|
||||
{
|
||||
if (_vignetteEffect != null)
|
||||
{
|
||||
_vignetteEffect.EnableVignette(enable);
|
||||
_vignetteEffect.SetIntensity(_vignetteIntensity);
|
||||
}
|
||||
if (_vignetteEffect == null)
|
||||
return;
|
||||
|
||||
_vignetteEffect.EnableVignette(enable);
|
||||
_vignetteEffect.SetIntensity(_vignetteIntensity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -575,10 +604,10 @@ namespace Unheimlich.Gameplay.Player
|
||||
|
||||
private void OnDrawGizmosSelected()
|
||||
{
|
||||
if (_playerCamera != null && IsListening)
|
||||
if (PlayerController.Instance != null && PlayerController.Instance.PlayerCamera != null && IsListening)
|
||||
{
|
||||
Gizmos.color = _currentTargetEmitter != null ? Color.green : Color.yellow;
|
||||
Ray ray = _playerCamera.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));
|
||||
Ray ray = PlayerController.Instance.PlayerCamera.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));
|
||||
Gizmos.DrawRay(ray.origin, ray.direction * _listeningRange);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
using UnityEngine;
|
||||
using OctoCore.Components;
|
||||
using Unheimlich.Core;
|
||||
using Unheimlich.Data;
|
||||
using Unheimlich.Managers;
|
||||
using Unheimlich.Gameplay.CameraControl;
|
||||
|
||||
namespace Unheimlich.Gameplay.Player
|
||||
{
|
||||
/// <summary>
|
||||
/// Central hub for all player systems.
|
||||
/// Exposes components and settings with zero Inspector refs needed for other scripts.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(OctoPlayer))]
|
||||
[RequireComponent(typeof(CharacterController))]
|
||||
public class PlayerController : Singleton<PlayerController>
|
||||
{
|
||||
// Auto-found components (exposed publicly, found once in Awake)
|
||||
public OctoPlayer Movement { get; private set; }
|
||||
public CharacterController CharController { get; private set; }
|
||||
public Camera PlayerCamera { get; private set; }
|
||||
public Transform CameraTransform { get; private set; }
|
||||
public Transform CameraPivot { get; private set; }
|
||||
public CameraEffects CameraEffects { get; private set; }
|
||||
public CameraPanController CameraPanController { get; private set; }
|
||||
public InputManager Inputs => InputManager.Instance;
|
||||
|
||||
public bool IsMoving
|
||||
{
|
||||
get
|
||||
{
|
||||
// Read directly from action instead of cached value
|
||||
var moveAction = InputManager.GetMoveAction();
|
||||
if (moveAction == null) return false;
|
||||
return moveAction.ReadValue<UnityEngine.Vector2>().magnitude > 0.1f;
|
||||
}
|
||||
}
|
||||
public bool IsRunning
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Movement == null || OctoCore.OctoCore.Instance == null) return false;
|
||||
|
||||
var actions = OctoCore.OctoCore.Instance.Inputs?.Actions;
|
||||
if (actions != null)
|
||||
{
|
||||
foreach (var actionInfo in actions)
|
||||
{
|
||||
if (actionInfo.Name == "Sprint" && actionInfo.Reference != null)
|
||||
return actionInfo.Reference.action.IsPressed();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnAwake()
|
||||
{
|
||||
// Auto-find all components once
|
||||
Movement = GetComponent<OctoPlayer>();
|
||||
CharController = GetComponent<CharacterController>();
|
||||
CameraEffects = GetComponent<CameraEffects>();
|
||||
CameraPanController = GetComponent<CameraPanController>();
|
||||
PlayerCamera = GetComponentInChildren<Camera>();
|
||||
|
||||
if (PlayerCamera != null)
|
||||
{
|
||||
CameraTransform = PlayerCamera.transform;
|
||||
CameraPivot = CameraTransform.parent;
|
||||
}
|
||||
}
|
||||
|
||||
// Teleport
|
||||
public void Teleport(Vector3 position, Quaternion rotation)
|
||||
{
|
||||
Movement.Teleport(position, rotation);
|
||||
PlayerEvents.TriggerTeleport(position, rotation);
|
||||
}
|
||||
|
||||
// Helper methods
|
||||
public Vector3 GetForward()
|
||||
{
|
||||
if (PlayerCamera == null) return transform.forward;
|
||||
|
||||
Vector3 forward = PlayerCamera.transform.forward;
|
||||
forward.y = 0;
|
||||
return forward.normalized;
|
||||
}
|
||||
|
||||
public Vector3 GetRight()
|
||||
{
|
||||
if (PlayerCamera == null) return transform.right;
|
||||
|
||||
Vector3 right = PlayerCamera.transform.right;
|
||||
right.y = 0;
|
||||
return right.normalized;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d192ca4042c25c4ea16f024d0e262c1
|
||||
@@ -1,171 +0,0 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using Unheimlich.Core;
|
||||
using Unheimlich.Gameplay.Portals;
|
||||
using InputManager = Unheimlich.Managers.PlayerInputManager;
|
||||
|
||||
namespace Unheimlich.Gameplay.Player
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles first-person camera rotation and look mechanics for the player.
|
||||
/// Supports both mouse and gamepad input with adaptive sensitivity.
|
||||
/// Includes aim assist for dialogue choices and camera shake effects.
|
||||
/// </summary>
|
||||
public class PlayerLook : Singleton<PlayerLook>
|
||||
{
|
||||
private const float INPUT_DEADZONE = 0.1f;
|
||||
private const float MOUSE_DELTA_MULTIPLIER = 0.001f;
|
||||
|
||||
[Header("Components")]
|
||||
[SerializeField] private Transform _playerCamera, _playerCameraPivot;
|
||||
|
||||
[Header("Settings")]
|
||||
[SerializeField] private int _frameRate = 120;
|
||||
[SerializeField] private float _mouseSensitivity = 0.2f;
|
||||
[SerializeField] private float _gamepadSensitivity = 100f;
|
||||
[SerializeField] private float _minLookAngle = -60f;
|
||||
[SerializeField] private float _maxLookAngle = 60f;
|
||||
|
||||
[Header("Aim Assist")]
|
||||
[SerializeField] private float _aimAssistStrength = 25f;
|
||||
[SerializeField] private float _aimAssistMaxAngle = 10f;
|
||||
|
||||
public bool HasActiveLookInput { get; private set; }
|
||||
public bool IsAimLocked { get; private set; } = false;
|
||||
|
||||
[Header("Shake Control")]
|
||||
[SerializeField] private float _shakeFrequency = 40f;
|
||||
private float _shakeInterval;
|
||||
private float _shakeTimer = 0f;
|
||||
private Vector3 _shakeTarget = Vector3.zero;
|
||||
private Vector3 _shakeOriginalPos = Vector3.zero;
|
||||
private float _shakeSmoothness = 0f;
|
||||
|
||||
private float _horizontalRotation;
|
||||
private float _verticalRotation;
|
||||
private bool _isUsingGamepad = false;
|
||||
|
||||
protected override void OnAwake()
|
||||
{
|
||||
QualitySettings.vSyncCount = 0;
|
||||
Application.targetFrameRate = _frameRate;
|
||||
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Cursor.lockState = CursorLockMode.Locked;
|
||||
Cursor.visible = false;
|
||||
_shakeInterval = 1f / _shakeFrequency;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if(!InputManager.IsLookingEnabled)
|
||||
return;
|
||||
|
||||
HandleLook();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes look input from mouse or gamepad and updates camera rotation.
|
||||
/// Automatically detects input device and applies appropriate sensitivity.
|
||||
/// Clamps vertical rotation to prevent over-rotation.
|
||||
/// </summary>
|
||||
private void HandleLook()
|
||||
{
|
||||
Vector2 lookInput = InputManager.Instance.LookInput;
|
||||
|
||||
HasActiveLookInput = lookInput.magnitude > INPUT_DEADZONE;
|
||||
|
||||
if (Gamepad.current != null && Gamepad.current.rightStick.ReadValue().magnitude > PortalConstants.GAMEPAD_DEADZONE)
|
||||
_isUsingGamepad = true;
|
||||
else if (Mouse.current != null && Mouse.current.delta.ReadValue().magnitude > PortalConstants.GAMEPAD_DEADZONE)
|
||||
_isUsingGamepad = false;
|
||||
|
||||
float sensitivity = _isUsingGamepad ? _gamepadSensitivity : _mouseSensitivity;
|
||||
float deltaMultiplier = _isUsingGamepad ? Time.deltaTime : MOUSE_DELTA_MULTIPLIER;
|
||||
|
||||
_horizontalRotation += lookInput.x * sensitivity * deltaMultiplier;
|
||||
transform.rotation = Quaternion.Euler(0, _horizontalRotation, 0f);
|
||||
|
||||
_verticalRotation -= lookInput.y * sensitivity * deltaMultiplier;
|
||||
_verticalRotation = Mathf.Clamp(_verticalRotation, _minLookAngle, _maxLookAngle);
|
||||
|
||||
_playerCamera.localRotation = Quaternion.Euler(_verticalRotation, 0f, 0f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Smoothly rotates the player camera toward a target using spherical interpolation.
|
||||
/// Assists player aiming by gently pulling the view toward dialogue choices when looking near them.
|
||||
/// Automatically unlocks if player provides manual input.
|
||||
/// </summary>
|
||||
public void ApplyAimAssist(Vector3 targetCenter)
|
||||
{
|
||||
if (IsAimLocked && HasActiveLookInput)
|
||||
IsAimLocked = false;
|
||||
|
||||
Vector3 directionToTarget = (targetCenter - _playerCamera.position).normalized;
|
||||
float angleError = Vector3.Angle(_playerCamera.forward, directionToTarget);
|
||||
|
||||
if (IsAimLocked || (angleError > 0.01f && angleError < _aimAssistMaxAngle))
|
||||
{
|
||||
Quaternion targetRotation = Quaternion.LookRotation(directionToTarget);
|
||||
|
||||
Quaternion correctedRotation = Quaternion.Slerp(
|
||||
_playerCamera.rotation,
|
||||
targetRotation,
|
||||
_aimAssistStrength * Time.deltaTime
|
||||
);
|
||||
Quaternion newBodyRotation = Quaternion.Euler(0, correctedRotation.eulerAngles.y, 0);
|
||||
|
||||
_horizontalRotation = newBodyRotation.eulerAngles.y;
|
||||
transform.rotation = newBodyRotation;
|
||||
|
||||
float newVerticalAngle = correctedRotation.eulerAngles.x;
|
||||
|
||||
if (newVerticalAngle > 180) newVerticalAngle -= 360;
|
||||
|
||||
_verticalRotation = Mathf.Clamp(newVerticalAngle, _minLookAngle, _maxLookAngle);
|
||||
_playerCamera.localRotation = Quaternion.Euler(_verticalRotation, 0f, 0f);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a random camera shake effect for feedback (e.g., impacts, events).
|
||||
/// Uses a timer-based interval to control shake frequency.
|
||||
/// Amplitude controls both the intensity and duration of the shake.
|
||||
/// Smoothness controls how quickly the camera interpolates to the shake position (0 = instant, higher = smoother).
|
||||
/// </summary>
|
||||
public void Shake(float amplitude, float smoothness = 0f)
|
||||
{
|
||||
_shakeSmoothness = smoothness;
|
||||
_shakeTimer -= Time.deltaTime;
|
||||
|
||||
if (_shakeTimer <= 0f)
|
||||
{
|
||||
_shakeTimer = _shakeInterval * amplitude;
|
||||
_shakeOriginalPos = _playerCameraPivot.position;
|
||||
|
||||
float x = Random.Range(-1f, 1f) * amplitude;
|
||||
float y = Random.Range(-1f, 1f) * amplitude;
|
||||
|
||||
_shakeTarget = _shakeOriginalPos + new Vector3(x, y, 0f);
|
||||
}
|
||||
|
||||
if (_shakeSmoothness > 0f)
|
||||
{
|
||||
_playerCameraPivot.position = Vector3.Lerp(_playerCameraPivot.position, _shakeTarget, Time.deltaTime * _shakeSmoothness);
|
||||
}
|
||||
else
|
||||
{
|
||||
_playerCameraPivot.position = _shakeTarget;
|
||||
}
|
||||
}
|
||||
|
||||
public void LockAim(bool locked)
|
||||
{
|
||||
IsAimLocked = locked;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1ddcefd49548ddb4b9bc694da032caee
|
||||
@@ -1,63 +0,0 @@
|
||||
using UnityEngine;
|
||||
using Unheimlich.Core;
|
||||
using Unheimlich.Managers;
|
||||
|
||||
namespace Unheimlich.Gameplay.Player
|
||||
{
|
||||
[RequireComponent(typeof(CharacterController))]
|
||||
public class PlayerMovement : Singleton<PlayerMovement>
|
||||
{
|
||||
|
||||
[Header("Settings")]
|
||||
[SerializeField] private float _moveSpeed = 5f;
|
||||
[SerializeField] private float _jumpForce = 10f;
|
||||
[SerializeField] private float _groundedGravity = -2f;
|
||||
|
||||
public CharacterController CharacterController { get; private set; }
|
||||
|
||||
public bool IsMoving { get; private set; }
|
||||
|
||||
private float _ySpeed;
|
||||
private Vector3 _moveDirection;
|
||||
|
||||
protected override void OnAwake()
|
||||
{
|
||||
CharacterController = GetComponent<CharacterController>();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!PlayerInputManager.IsInputEnabled || CharacterController == null)
|
||||
return;
|
||||
|
||||
HandleMovement();
|
||||
}
|
||||
|
||||
private void HandleMovement()
|
||||
{
|
||||
Vector2 input = PlayerInputManager.Instance.MoveInput;
|
||||
|
||||
Vector3 forward = transform.forward * input.y;
|
||||
Vector3 right = transform.right * input.x;
|
||||
|
||||
_moveDirection = forward + right;
|
||||
_moveDirection = _moveDirection.normalized * _moveSpeed;
|
||||
|
||||
IsMoving = _moveDirection.magnitude > 0.1f && CharacterController.isGrounded;
|
||||
|
||||
if (CharacterController.isGrounded)
|
||||
{
|
||||
_ySpeed = _groundedGravity;
|
||||
|
||||
var jumpAction = PlayerInputManager.GetJumpAction();
|
||||
if (jumpAction != null && jumpAction.WasPressedThisFrame())
|
||||
_ySpeed = _jumpForce;
|
||||
}
|
||||
else
|
||||
_ySpeed += Physics.gravity.y * Time.deltaTime;
|
||||
|
||||
_moveDirection.y = _ySpeed;
|
||||
CharacterController.Move(_moveDirection * Time.deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a25b5737428861f4f8460e0ec5c93015
|
||||
@@ -1,7 +1,7 @@
|
||||
using UnityEngine;
|
||||
using Unheimlich.Core;
|
||||
using Unheimlich.Managers;
|
||||
using Unheimlich.Utility;
|
||||
using InputManager = Unheimlich.Managers.InputManager;
|
||||
|
||||
namespace Unheimlich.Interactions.Core
|
||||
{
|
||||
@@ -44,7 +44,7 @@ namespace Unheimlich.Interactions.Core
|
||||
|
||||
private void HandleInteractionInput()
|
||||
{
|
||||
var interactAction = PlayerInputManager.GetInteractAction();
|
||||
var interactAction = InputManager.GetInteractAction();
|
||||
if (interactAction != null && interactAction.WasPressedThisFrame())
|
||||
{
|
||||
if (_currentInteractable != null)
|
||||
|
||||
@@ -3,13 +3,13 @@ using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using Unheimlich.Core;
|
||||
using Unheimlich.Gameplay.Items;
|
||||
using InputManager = Unheimlich.Managers.PlayerInputManager;
|
||||
using Unheimlich.Gameplay.Player;
|
||||
using InputManager = Unheimlich.Managers.InputManager;
|
||||
|
||||
namespace Unheimlich.Interactions.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles player item inspection mode.
|
||||
/// When inspecting, disables player movement and allows item rotation using look input.
|
||||
/// </summary>
|
||||
public class PlayerInspectionHandler : Singleton<PlayerInspectionHandler>
|
||||
{
|
||||
@@ -42,7 +42,14 @@ namespace Unheimlich.Interactions.Core
|
||||
IsInspecting = true;
|
||||
_currentInspectedItem = item;
|
||||
|
||||
InputManager.ToggleInput(false);
|
||||
// Set Inspection context (handles cursor automatically)
|
||||
InputManager.SetContext(InputManager.InputContext.Inspection);
|
||||
|
||||
// Disable OctoPlayer to prevent movement and look
|
||||
if (PlayerController.Instance?.Movement != null)
|
||||
{
|
||||
PlayerController.Instance.Movement.enabled = false;
|
||||
}
|
||||
|
||||
item.PrepareForInspection(_inspectionHoldPoint);
|
||||
|
||||
@@ -77,7 +84,17 @@ namespace Unheimlich.Interactions.Core
|
||||
private IEnumerator DelayedToggleInput(bool enable)
|
||||
{
|
||||
yield return new WaitForEndOfFrame();
|
||||
InputManager.ToggleInput(enable);
|
||||
|
||||
// Re-enable OctoPlayer
|
||||
if (PlayerController.Instance?.Movement != null)
|
||||
{
|
||||
PlayerController.Instance.Movement.enabled = true;
|
||||
}
|
||||
|
||||
// Restore Normal context (handles cursor automatically)
|
||||
InputManager.SetContext(InputManager.InputContext.Normal);
|
||||
|
||||
yield break;
|
||||
}
|
||||
|
||||
|
||||
@@ -109,21 +126,44 @@ namespace Unheimlich.Interactions.Core
|
||||
|
||||
private void HandleObjectRotation()
|
||||
{
|
||||
if (InputManager.Instance == null) return;
|
||||
if (_currentInspectedItem == null) return;
|
||||
|
||||
Vector2 lookInput = InputManager.Instance.LookInput;
|
||||
Vector2 lookInput = Vector2.zero;
|
||||
bool hasInput = false;
|
||||
|
||||
if (lookInput != Vector2.zero)
|
||||
// Read input directly (not cached)
|
||||
if (Gamepad.current != null)
|
||||
{
|
||||
if (Gamepad.current != null && Gamepad.current.rightStick.ReadValue().magnitude > 0.01f)
|
||||
Vector2 stickInput = Gamepad.current.rightStick.ReadValue();
|
||||
if (stickInput.sqrMagnitude > 0.01f)
|
||||
{
|
||||
lookInput = stickInput;
|
||||
hasInput = true;
|
||||
_isUsingGamepad = true;
|
||||
else if (Mouse.current != null && Mouse.current.delta.ReadValue().magnitude > 0.01f)
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasInput && Mouse.current != null)
|
||||
{
|
||||
Vector2 mouseDelta = Mouse.current.delta.ReadValue();
|
||||
if (mouseDelta.sqrMagnitude > 0.01f)
|
||||
{
|
||||
lookInput = mouseDelta;
|
||||
hasInput = true;
|
||||
_isUsingGamepad = false;
|
||||
}
|
||||
}
|
||||
|
||||
float deltaMultiplier = _isUsingGamepad ? Time.deltaTime : 0.005f;
|
||||
// Only rotate if there's actual input
|
||||
if (hasInput)
|
||||
{
|
||||
// Normalize to get constant rotation speed regardless of input magnitude
|
||||
Vector2 direction = lookInput.normalized;
|
||||
|
||||
float rotX = lookInput.y * _currentInspectedItem.RotationSpeed * deltaMultiplier;
|
||||
float rotY = lookInput.x * _currentInspectedItem.RotationSpeed * deltaMultiplier;
|
||||
float rotationMultiplier = _isUsingGamepad ? Time.deltaTime : 0.02f;
|
||||
|
||||
float rotX = direction.y * _currentInspectedItem.RotationSpeed * rotationMultiplier;
|
||||
float rotY = direction.x * _currentInspectedItem.RotationSpeed * rotationMultiplier;
|
||||
|
||||
_currentInspectedItem.transform.Rotate(transform.up, -rotY, Space.World);
|
||||
_currentInspectedItem.transform.Rotate(transform.right, rotX, Space.World);
|
||||
|
||||
@@ -10,14 +10,12 @@ namespace Unheimlich.Managers
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages gaze-based focus detection for dialogue choices using raycasts.
|
||||
/// Handles progressive focus timers, aim assist integration, visual feedback,
|
||||
/// and automatic choice selection when player maintains focus for a duration.
|
||||
/// </summary>
|
||||
public class DialogueFocusSystem
|
||||
{
|
||||
private readonly DialogueManager _manager;
|
||||
private readonly Camera _mainCamera;
|
||||
private readonly PlayerLook _playerLook;
|
||||
private readonly CameraEffects _cameraEffects;
|
||||
|
||||
private ChoiceFocusHandler _currentFocusedHandler;
|
||||
private float _focusTimer = 0f;
|
||||
@@ -38,7 +36,7 @@ namespace Unheimlich.Managers
|
||||
public DialogueFocusSystem(
|
||||
DialogueManager manager,
|
||||
Camera mainCamera,
|
||||
PlayerLook playerLook,
|
||||
CameraEffects cameraEffects,
|
||||
LayerMask choiceLayer,
|
||||
float focusRange,
|
||||
float focusTime,
|
||||
@@ -49,7 +47,7 @@ namespace Unheimlich.Managers
|
||||
{
|
||||
_manager = manager;
|
||||
_mainCamera = mainCamera;
|
||||
_playerLook = playerLook;
|
||||
_cameraEffects = cameraEffects;
|
||||
_choiceLayer = choiceLayer;
|
||||
_focusRange = focusRange;
|
||||
_focusTime = focusTime;
|
||||
@@ -101,8 +99,8 @@ namespace Unheimlich.Managers
|
||||
{
|
||||
hitHandler = hit.collider.GetComponent<ChoiceFocusHandler>();
|
||||
|
||||
if (_playerLook != null && hitHandler != null)
|
||||
_playerLook.ApplyAimAssist(hit.collider.bounds.center);
|
||||
if (_cameraEffects != null && hitHandler != null)
|
||||
_cameraEffects.ApplyAimAssist(hit.collider.bounds.center);
|
||||
}
|
||||
|
||||
if (hitHandler != _currentFocusedHandler)
|
||||
@@ -121,8 +119,8 @@ namespace Unheimlich.Managers
|
||||
_focusTimer = 0f;
|
||||
_retentionTimer = _focusRetentionTime;
|
||||
|
||||
if (_playerLook != null)
|
||||
_playerLook.LockAim(true);
|
||||
if (_cameraEffects != null)
|
||||
_cameraEffects.LockAim(true);
|
||||
|
||||
ApplyUnfocusEffectToOthers(hitHandler);
|
||||
|
||||
@@ -152,11 +150,11 @@ namespace Unheimlich.Managers
|
||||
DialogueAnimationSettings currentSettings = _manager.CurrentAnimationSettings;
|
||||
bool shouldShake = currentSettings == null || currentSettings.EnableCameraShakeOnFocus;
|
||||
|
||||
if (shouldShake && _playerLook != null)
|
||||
if (shouldShake && _cameraEffects != null)
|
||||
{
|
||||
float shakeIntensity = currentSettings != null ? currentSettings.CameraShakeIntensity : _fallbackShakeIntensity;
|
||||
float shakeSmoothness = currentSettings != null ? currentSettings.CameraShakeSmoothness : 10f;
|
||||
_playerLook.Shake(progress / shakeIntensity, shakeSmoothness);
|
||||
_cameraEffects.ShakeCamera(progress / shakeIntensity, shakeSmoothness);
|
||||
}
|
||||
|
||||
if (_focusTimer >= _focusTime)
|
||||
@@ -183,8 +181,8 @@ namespace Unheimlich.Managers
|
||||
|
||||
selectedHandler.ResetFeedback(_recoveryDuration);
|
||||
|
||||
if (_playerLook != null)
|
||||
_playerLook.LockAim(false);
|
||||
if (_cameraEffects != null)
|
||||
_cameraEffects.LockAim(false);
|
||||
}
|
||||
}
|
||||
else if (_currentFocusedHandler != null && _retentionTimer <= 0f)
|
||||
@@ -202,8 +200,8 @@ namespace Unheimlich.Managers
|
||||
|
||||
ResetAnimationTimers();
|
||||
|
||||
if (_playerLook != null)
|
||||
_playerLook.LockAim(false);
|
||||
if (_cameraEffects != null)
|
||||
_cameraEffects.LockAim(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ using Unheimlich.Gameplay.Player;
|
||||
using Unheimlich.UI;
|
||||
using Unheimlich.Interactions.Dialogues;
|
||||
using System.Collections.Generic;
|
||||
using InputManager = Unheimlich.Managers.InputManager;
|
||||
|
||||
namespace Unheimlich.Managers
|
||||
{
|
||||
@@ -41,7 +42,6 @@ namespace Unheimlich.Managers
|
||||
|
||||
private DialogueFocusSystem _focusSystem;
|
||||
private Camera _mainCamera;
|
||||
private PlayerLook _playerLook;
|
||||
private DialogueAnimationSettings _currentAnimationSettings;
|
||||
private DialogueUI _activeDialogueUI;
|
||||
private Transform _currentChoiceAnchor;
|
||||
@@ -57,13 +57,12 @@ namespace Unheimlich.Managers
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_playerLook = PlayerLook.Instance;
|
||||
_mainCamera = Camera.main;
|
||||
|
||||
_focusSystem = new DialogueFocusSystem(
|
||||
this,
|
||||
_mainCamera,
|
||||
_playerLook,
|
||||
PlayerController.Instance?.CameraEffects,
|
||||
_choiceLayer,
|
||||
_focusRange,
|
||||
_focusTime,
|
||||
@@ -107,7 +106,7 @@ namespace Unheimlich.Managers
|
||||
}
|
||||
}
|
||||
|
||||
var interactAction = PlayerInputManager.GetInteractAction();
|
||||
var interactAction = InputManager.GetInteractAction();
|
||||
if (interactAction != null && interactAction.WasPressedThisFrame())
|
||||
{
|
||||
EndDialogue();
|
||||
|
||||
@@ -0,0 +1,267 @@
|
||||
using UnityEngine;
|
||||
using OctoCore;
|
||||
using OctoCore.Inputs;
|
||||
using Unheimlich.Core;
|
||||
|
||||
namespace Unheimlich.Managers
|
||||
{
|
||||
/// <summary>
|
||||
/// Unified input manager wrapping OctoCore inputs with Unheimlich-specific contexts.
|
||||
/// Replaces the old PlayerInputManager while keeping context system (Normal, Dialogue, Listening).
|
||||
/// </summary>
|
||||
public class InputManager : Singleton<InputManager>
|
||||
{
|
||||
public enum InputContext
|
||||
{
|
||||
Normal, // All inputs enabled
|
||||
Dialogue, // Only look and interact
|
||||
Listening, // Only look and diapason
|
||||
Inspection // Only look and interact (for item inspection)
|
||||
}
|
||||
|
||||
[Header("Current State")]
|
||||
[SerializeField] private InputContext _currentContext = InputContext.Normal;
|
||||
|
||||
// Public access to current context
|
||||
public static InputContext CurrentContext => Instance ? Instance._currentContext : InputContext.Normal;
|
||||
|
||||
// Input values (cached for compatibility)
|
||||
public static Vector2 MoveInput { get; private set; }
|
||||
public static Vector2 LookInput { get; private set; }
|
||||
|
||||
// Legacy compatibility
|
||||
public static bool IsInputEnabled => CurrentContext == InputContext.Normal;
|
||||
public static bool IsLookingEnabled => CurrentContext != InputContext.Dialogue;
|
||||
|
||||
protected override void OnAwake()
|
||||
{
|
||||
// Try to subscribe, will retry in Start if needed
|
||||
SubscribeAllInputs();
|
||||
SetContext(InputContext.Normal);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Debug.Log("[InputManager] Start() called");
|
||||
|
||||
if (OctoCore.OctoCore.Instance == null)
|
||||
{
|
||||
Debug.LogError("[InputManager] OctoCore.Instance is NULL!");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log("[InputManager] OctoCore.Instance exists");
|
||||
|
||||
if (OctoCore.OctoCore.Instance.Inputs == null)
|
||||
{
|
||||
Debug.LogError("[InputManager] OctoCore.Instance.Inputs is NULL!");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log("[InputManager] OctoCore.Instance.Inputs exists");
|
||||
|
||||
// Ensure we're subscribed
|
||||
SubscribeAllInputs();
|
||||
Debug.Log("[InputManager] Initialized and subscribed to OctoCore inputs.");
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
UnsubscribeAllInputs();
|
||||
}
|
||||
|
||||
// Subscribe to OctoCore inputs
|
||||
private void SubscribeAllInputs()
|
||||
{
|
||||
if (OctoCore.OctoCore.Instance == null) return;
|
||||
|
||||
OctoCore.OctoCore.Instance.Inputs.SubscribeAction(OctoActions.Player_Move, OnMove);
|
||||
OctoCore.OctoCore.Instance.Inputs.SubscribeAction(OctoActions.Player_Look, OnLook);
|
||||
OctoCore.OctoCore.Instance.Inputs.SubscribeAction(OctoActions.Player_Jump, OnJump);
|
||||
OctoCore.OctoCore.Instance.Inputs.SubscribeAction(OctoActions.Player_Interact, OnInteract);
|
||||
OctoCore.OctoCore.Instance.Inputs.SubscribeAction(OctoActions.Player_Diapason, OnDiapason);
|
||||
OctoCore.OctoCore.Instance.Inputs.SubscribeAction(OctoActions.Player_Fire, OnFire);
|
||||
OctoCore.OctoCore.Instance.Inputs.SubscribeAction(OctoActions.Player_Exit, OnExit);
|
||||
}
|
||||
|
||||
private void UnsubscribeAllInputs()
|
||||
{
|
||||
if (OctoCore.OctoCore.Instance == null) return;
|
||||
|
||||
OctoCore.OctoCore.Instance.Inputs.UnsubscribeAction(OctoActions.Player_Move, OnMove);
|
||||
OctoCore.OctoCore.Instance.Inputs.UnsubscribeAction(OctoActions.Player_Look, OnLook);
|
||||
OctoCore.OctoCore.Instance.Inputs.UnsubscribeAction(OctoActions.Player_Jump, OnJump);
|
||||
OctoCore.OctoCore.Instance.Inputs.UnsubscribeAction(OctoActions.Player_Interact, OnInteract);
|
||||
OctoCore.OctoCore.Instance.Inputs.UnsubscribeAction(OctoActions.Player_Diapason, OnDiapason);
|
||||
OctoCore.OctoCore.Instance.Inputs.UnsubscribeAction(OctoActions.Player_Fire, OnFire);
|
||||
OctoCore.OctoCore.Instance.Inputs.UnsubscribeAction(OctoActions.Player_Exit, OnExit);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets input context and handles cursor/component state
|
||||
/// </summary>
|
||||
public static void SetContext(InputContext context)
|
||||
{
|
||||
if (Instance == null) return;
|
||||
|
||||
Instance._currentContext = context;
|
||||
|
||||
switch (context)
|
||||
{
|
||||
case InputContext.Normal:
|
||||
// All inputs active
|
||||
Cursor.lockState = CursorLockMode.Locked;
|
||||
Cursor.visible = false;
|
||||
break;
|
||||
|
||||
case InputContext.Dialogue:
|
||||
// Only look and interact (movement disabled)
|
||||
Cursor.lockState = CursorLockMode.None;
|
||||
Cursor.visible = true;
|
||||
break;
|
||||
|
||||
case InputContext.Listening:
|
||||
// Only look, diapason, fire, exit (movement disabled)
|
||||
Cursor.lockState = CursorLockMode.Locked;
|
||||
Cursor.visible = false;
|
||||
break;
|
||||
|
||||
case InputContext.Inspection:
|
||||
// Only look and interact (for item inspection, movement disabled)
|
||||
Cursor.lockState = CursorLockMode.Locked;
|
||||
Cursor.visible = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Legacy compatibility
|
||||
public static void ToggleInput(bool enable)
|
||||
{
|
||||
SetContext(enable ? InputContext.Normal : InputContext.Dialogue);
|
||||
}
|
||||
|
||||
// Input callbacks - cache values and filter by context
|
||||
private void OnMove(Vector2 value)
|
||||
{
|
||||
MoveInput = _currentContext == InputContext.Normal ? value : Vector2.zero;
|
||||
}
|
||||
|
||||
private void OnLook(Vector2 value)
|
||||
{
|
||||
LookInput = value; // Look enabled in all contexts
|
||||
}
|
||||
|
||||
private void OnJump()
|
||||
{
|
||||
if (_currentContext != InputContext.Normal) return;
|
||||
// Broadcast jump event if needed
|
||||
}
|
||||
|
||||
private void OnInteract()
|
||||
{
|
||||
if (_currentContext == InputContext.Listening) return;
|
||||
// Broadcast interact event
|
||||
}
|
||||
|
||||
private void OnDiapason()
|
||||
{
|
||||
if (_currentContext == InputContext.Dialogue) return;
|
||||
// Broadcast diapason event
|
||||
}
|
||||
|
||||
private void OnFire()
|
||||
{
|
||||
if (_currentContext != InputContext.Listening) return;
|
||||
// Broadcast fire event
|
||||
}
|
||||
|
||||
private void OnExit()
|
||||
{
|
||||
if (_currentContext != InputContext.Listening) return;
|
||||
// Broadcast exit event
|
||||
}
|
||||
|
||||
// Public accessors for backward compatibility
|
||||
public static Vector2 GetMoveInput() => MoveInput;
|
||||
public static Vector2 GetLookInput() => LookInput;
|
||||
|
||||
// Action accessors for direct button checks
|
||||
public static UnityEngine.InputSystem.InputAction GetMoveAction()
|
||||
{
|
||||
var asset = OctoCore.OctoCore.Instance?.Inputs?.Actions;
|
||||
if (asset == null) return null;
|
||||
|
||||
foreach (var actionInfo in asset)
|
||||
{
|
||||
if (actionInfo.Name == "Move" && actionInfo.Reference != null)
|
||||
return actionInfo.Reference.action;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static UnityEngine.InputSystem.InputAction GetDiapasonAction()
|
||||
{
|
||||
var asset = OctoCore.OctoCore.Instance?.Inputs?.Actions;
|
||||
if (asset == null) return null;
|
||||
|
||||
foreach (var actionInfo in asset)
|
||||
{
|
||||
if (actionInfo.Name == "Diapason" && actionInfo.Reference != null)
|
||||
return actionInfo.Reference.action;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static UnityEngine.InputSystem.InputAction GetInteractAction()
|
||||
{
|
||||
var asset = OctoCore.OctoCore.Instance?.Inputs?.Actions;
|
||||
if (asset == null) return null;
|
||||
|
||||
foreach (var actionInfo in asset)
|
||||
{
|
||||
if (actionInfo.Name == "Interact" && actionInfo.Reference != null)
|
||||
return actionInfo.Reference.action;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static UnityEngine.InputSystem.InputAction GetFireAction()
|
||||
{
|
||||
var asset = OctoCore.OctoCore.Instance?.Inputs?.Actions;
|
||||
if (asset == null) return null;
|
||||
|
||||
foreach (var actionInfo in asset)
|
||||
{
|
||||
if (actionInfo.Name == "Fire" && actionInfo.Reference != null)
|
||||
return actionInfo.Reference.action;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static UnityEngine.InputSystem.InputAction GetExitAction()
|
||||
{
|
||||
var asset = OctoCore.OctoCore.Instance?.Inputs?.Actions;
|
||||
if (asset == null) return null;
|
||||
|
||||
foreach (var actionInfo in asset)
|
||||
{
|
||||
if (actionInfo.Name == "Exit" && actionInfo.Reference != null)
|
||||
return actionInfo.Reference.action;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static UnityEngine.InputSystem.InputAction GetLookAction()
|
||||
{
|
||||
var asset = OctoCore.OctoCore.Instance?.Inputs?.Actions;
|
||||
if (asset == null) return null;
|
||||
|
||||
foreach (var actionInfo in asset)
|
||||
{
|
||||
if (actionInfo.Name == "Look" && actionInfo.Reference != null)
|
||||
return actionInfo.Reference.action;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e340839b22a784542ba8afdfde612c2e
|
||||
@@ -1,179 +0,0 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using Unheimlich.Core;
|
||||
using Unheimlich.Gameplay.Player;
|
||||
|
||||
namespace Unheimlich.Managers
|
||||
{
|
||||
/// <summary>
|
||||
/// Centralizes Input System handling for the player.
|
||||
/// Manages input state, action references, and global input enable/disable functionality.
|
||||
/// Supports different input contexts (Normal, Dialogue, Listening) to control which inputs are active.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(PlayerInput))]
|
||||
public class PlayerInputManager : Singleton<PlayerInputManager>
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines different input contexts that control which player actions are enabled.
|
||||
/// </summary>
|
||||
public enum InputContext
|
||||
{
|
||||
Normal, // All inputs enabled (movement, look, jump, interact, diapason)
|
||||
Dialogue, // Only look and interact enabled (for dialogues/UI)
|
||||
Listening // Only look enabled, movement disabled (for diapason camera pan)
|
||||
}
|
||||
|
||||
[Header("Input Values (Read only)")]
|
||||
public Vector2 MoveInput;
|
||||
public Vector2 LookInput;
|
||||
|
||||
public static bool IsInputEnabled { get; private set; } = true;
|
||||
public static bool IsLookingEnabled { get; private set; } = true;
|
||||
public static InputContext CurrentContext { get; private set; } = InputContext.Normal;
|
||||
|
||||
private InputActionMap _playerActionMap;
|
||||
private InputAction _moveAction;
|
||||
private InputAction _lookAction;
|
||||
private InputAction _jumpAction;
|
||||
private InputAction _interactAction;
|
||||
private InputAction _diapasonAction;
|
||||
private InputAction _fireAction;
|
||||
private InputAction _exitAction;
|
||||
|
||||
private PlayerMovement _playerMovement;
|
||||
private PlayerLook _playerLook;
|
||||
private CameraHeadBob _headBob;
|
||||
|
||||
protected override void OnAwake()
|
||||
{
|
||||
IsInputEnabled = true;
|
||||
|
||||
PlayerInput playerInput = GetComponent<PlayerInput>();
|
||||
playerInput.actions.Enable();
|
||||
|
||||
_playerActionMap = playerInput.actions.FindActionMap("Player");
|
||||
_moveAction = _playerActionMap.FindAction("Move");
|
||||
_lookAction = _playerActionMap.FindAction("Look");
|
||||
_jumpAction = _playerActionMap.FindAction("Jump");
|
||||
_interactAction = _playerActionMap.FindAction("Interact");
|
||||
_diapasonAction = _playerActionMap.FindAction("Diapason");
|
||||
_fireAction = _playerActionMap.FindAction("Fire");
|
||||
_exitAction = _playerActionMap.FindAction("Exit");
|
||||
|
||||
_playerMovement = GetComponent<PlayerMovement>();
|
||||
_playerLook = GetComponent<PlayerLook>();
|
||||
_headBob = GetComponentInChildren<CameraHeadBob>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the input context, controlling which inputs and player components are active.
|
||||
/// </summary>
|
||||
public static void SetContext(InputContext context)
|
||||
{
|
||||
if (Instance == null) return;
|
||||
|
||||
CurrentContext = context;
|
||||
|
||||
switch (context)
|
||||
{
|
||||
case InputContext.Normal:
|
||||
Instance._playerActionMap.Enable();
|
||||
Instance.SetComponentsEnabled(true, true, true);
|
||||
IsInputEnabled = true;
|
||||
IsLookingEnabled = true;
|
||||
Cursor.lockState = CursorLockMode.Locked;
|
||||
Cursor.visible = false;
|
||||
break;
|
||||
|
||||
case InputContext.Dialogue:
|
||||
Instance._playerActionMap.Disable();
|
||||
Instance._lookAction.Enable();
|
||||
Instance._interactAction.Enable();
|
||||
if (Instance._diapasonAction != null)
|
||||
Instance._diapasonAction.Enable();
|
||||
Instance.SetComponentsEnabled(false, false, false);
|
||||
IsInputEnabled = false;
|
||||
IsLookingEnabled = false;
|
||||
break;
|
||||
|
||||
case InputContext.Listening:
|
||||
Instance._playerActionMap.Disable();
|
||||
Instance._lookAction.Enable();
|
||||
if (Instance._diapasonAction != null)
|
||||
Instance._diapasonAction.Enable();
|
||||
if (Instance._fireAction != null)
|
||||
Instance._fireAction.Enable();
|
||||
if (Instance._exitAction != null)
|
||||
Instance._exitAction.Enable();
|
||||
Instance.SetComponentsEnabled(false, false, true);
|
||||
IsInputEnabled = false;
|
||||
IsLookingEnabled = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables player movement components.
|
||||
/// </summary>
|
||||
private void SetComponentsEnabled(bool movement, bool look, bool headBob)
|
||||
{
|
||||
if (_playerMovement != null)
|
||||
_playerMovement.enabled = movement;
|
||||
if (_playerLook != null)
|
||||
_playerLook.enabled = look;
|
||||
if (_headBob != null)
|
||||
_headBob.enabled = headBob;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Globally toggles player input on/off. When disabled, only look and interact actions remain active.
|
||||
/// Used during dialogues, inspections, or UI interactions.
|
||||
/// LEGACY: Use SetContext(InputContext.Dialogue) instead.
|
||||
/// </summary>
|
||||
public static void ToggleInput(bool enable)
|
||||
{
|
||||
SetContext(enable ? InputContext.Normal : InputContext.Dialogue);
|
||||
}
|
||||
|
||||
public void OnMove(InputAction.CallbackContext context)
|
||||
{
|
||||
MoveInput = context.ReadValue<Vector2>();
|
||||
}
|
||||
|
||||
public void Look(InputAction.CallbackContext context)
|
||||
{
|
||||
LookInput = context.ReadValue<Vector2>();
|
||||
}
|
||||
|
||||
public void OnJump(InputAction.CallbackContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnInteract(InputAction.CallbackContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnDiapason(InputAction.CallbackContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnFire(InputAction.CallbackContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnExit(InputAction.CallbackContext context)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides public access to input actions for other systems.
|
||||
/// </summary>
|
||||
public static InputAction GetMoveAction() => Instance?._moveAction;
|
||||
public static InputAction GetLookAction() => Instance?._lookAction;
|
||||
public static InputAction GetJumpAction() => Instance?._jumpAction;
|
||||
public static InputAction GetInteractAction() => Instance?._interactAction;
|
||||
public static InputAction GetDiapasonAction() => Instance?._diapasonAction;
|
||||
public static InputAction GetFireAction() => Instance?._fireAction;
|
||||
public static InputAction GetExitAction() => Instance?._exitAction;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 860eff61af1c75243b697035c7b7fc83
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- JumpAction: {fileID: -2099379676528639254, guid: 052faaac586de48259a63d0c4782560b, type: 3}
|
||||
- InteractAction: {fileID: 1781555164194001046, guid: 052faaac586de48259a63d0c4782560b, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -4,10 +4,11 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Unheimlich.Data.DetectiveBoard;
|
||||
using Unheimlich.Managers;
|
||||
using Unheimlich.Core;
|
||||
|
||||
namespace Unheimlich.UI.DetectiveBoard
|
||||
{
|
||||
public class DetectiveBoardCanvas : MonoBehaviour
|
||||
public class DetectiveBoardCanvas : Singleton<DetectiveBoardCanvas>
|
||||
{
|
||||
[Header("References")]
|
||||
[SerializeField] private Canvas _canvas;
|
||||
@@ -60,7 +61,7 @@ namespace Unheimlich.UI.DetectiveBoard
|
||||
ToggleNodeEliminated(node);
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
protected override void OnAwake()
|
||||
{
|
||||
if (_canvas == null)
|
||||
_canvas = GetComponent<Canvas>();
|
||||
|
||||
@@ -92,6 +92,19 @@ namespace OctoCore.Components
|
||||
public bool IsPaused => _isPaused;
|
||||
public float Radius => _references.Controller ? _references.Controller.radius : 0;
|
||||
|
||||
// Public access to yaw and pitch for external aim assist systems
|
||||
public float Yaw
|
||||
{
|
||||
get => _yaw;
|
||||
set => _yaw = value;
|
||||
}
|
||||
|
||||
public float Pitch
|
||||
{
|
||||
get => _pitch;
|
||||
set => _pitch = Mathf.Clamp(value, _firstPerson.MinPitch, _firstPerson.MaxPitch);
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
if (!Instance) Instance = this;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// Backup saved in: Assets/OctoCore/Generated/OctoActions.json
|
||||
// To regenerate: OctoSettings > Mapping > Click 'Generate Inputs'
|
||||
// Generated from: PlayerController
|
||||
// Generated on: 2026-02-09 21:55:05
|
||||
// Generated on: 2026-02-14 14:55:28
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
namespace OctoCore.Inputs
|
||||
@@ -40,6 +40,8 @@ namespace OctoCore.Inputs
|
||||
Player_Diapason = -1931519977,
|
||||
/// <summary>Player > Fire</summary>
|
||||
Player_Fire = 380421744,
|
||||
/// <summary>Player > Exit</summary>
|
||||
Player_Exit = -2092987256,
|
||||
/// <summary>UI > Navigate</summary>
|
||||
UI_Navigate = -1768796602,
|
||||
/// <summary>UI > Submit</summary>
|
||||
|
||||
Reference in New Issue
Block a user