Fix : Slope bug for player & add case for inifinite stairs
This commit is contained in:
@@ -180,8 +180,8 @@ MonoBehaviour:
|
||||
Sprite: {fileID: 0}
|
||||
Languages:
|
||||
Default: 0
|
||||
SaveWritten: {fileID: 11400000, guid: 32dca1ce9df9b064b8a0a2b3ab0fd8dd, type: 2}
|
||||
SaveAudio: {fileID: 11400000, guid: 225ffb773e59f8141bacbba2a9ede731, type: 2}
|
||||
SaveWritten: {fileID: 0}
|
||||
SaveAudio: {fileID: 0}
|
||||
Overrides: []
|
||||
Scenes:
|
||||
SceneDatas: []
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 134e0811334c5814e96a4823d9665656
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 445844e5540fe42449d9a96cd68cbcea
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &-3947132882786938876
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 11
|
||||
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: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion
|
||||
version: 10
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: StairsMaterial
|
||||
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords: []
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap:
|
||||
RenderType: Opaque
|
||||
disabledShaderPasses:
|
||||
- MOTIONVECTORS
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BaseMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _SpecGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_Lightmaps:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_LightmapsInd:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_ShadowMasks:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _AddPrecomputedVelocity: 0
|
||||
- _AlphaClip: 0
|
||||
- _AlphaToMask: 0
|
||||
- _Blend: 0
|
||||
- _BlendModePreserveSpecular: 1
|
||||
- _BumpScale: 1
|
||||
- _ClearCoatMask: 0
|
||||
- _ClearCoatSmoothness: 0
|
||||
- _Cull: 2
|
||||
- _Cutoff: 0.5
|
||||
- _DetailAlbedoMapScale: 1
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _DstBlendAlpha: 0
|
||||
- _EnvironmentReflections: 1
|
||||
- _GlossMapScale: 0
|
||||
- _Glossiness: 0
|
||||
- _GlossyReflections: 0
|
||||
- _Metallic: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.005
|
||||
- _QueueOffset: 0
|
||||
- _ReceiveShadows: 1
|
||||
- _Smoothness: 0
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _SrcBlendAlpha: 1
|
||||
- _Surface: 0
|
||||
- _WorkflowMode: 1
|
||||
- _XRMotionVectorsPass: 1
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _BaseColor: {r: 0.3773585, g: 0.3773585, b: 0.3773585, a: 1}
|
||||
- _Color: {r: 0.37735847, g: 0.37735847, b: 0.37735847, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
|
||||
m_BuildTextureStacks: []
|
||||
m_AllowLocking: 1
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5bb237e5d23b5264b8fcb45d620a4108
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: baf901c128ce7a644b7b1737ba04de04
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+1845
File diff suppressed because it is too large
Load Diff
+7
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b278a20a2783def489d009364c988771
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+3233
File diff suppressed because it is too large
Load Diff
+7
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3159084da89126c4f8f26519f0c6f75e
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+5887
File diff suppressed because it is too large
Load Diff
+7
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b096230e5db7f84fbdc9ec1f398c205
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 629e2f358900b4e46b9b43539224cba1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+218
-83
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -8,6 +8,9 @@ namespace Unheimlich.Features.Player
|
||||
/// Simulates camera head bobbing motion during player movement and idle states.
|
||||
/// Smoothly transitions between idle, walk and run bob parameters.
|
||||
/// Adds a subtle Z-axis roll to the bob and a strafe tilt applied in LateUpdate.
|
||||
///
|
||||
/// Sprint bob is automatically disabled when OctoPlayer.CanRun is false,
|
||||
/// since IsRunning already returns false in that case.
|
||||
/// </summary>
|
||||
public class CameraHeadBob : MonoBehaviour
|
||||
{
|
||||
@@ -15,15 +18,15 @@ namespace Unheimlich.Features.Player
|
||||
private Vector3 _startLocalPos;
|
||||
|
||||
// Smoothly interpolated bob parameters to avoid brutal state switches.
|
||||
private float _currentBobSpeed = 0f;
|
||||
private float _currentBobSpeed = 0f;
|
||||
private float _currentBobAmplitude = 0f;
|
||||
|
||||
// Strafe tilt (Z roll applied in LateUpdate, after OctoPlayer sets camera pitch).
|
||||
private float _currentTilt = 0f;
|
||||
|
||||
private HeadBobMode _overrideMode = HeadBobMode.Normal;
|
||||
private bool _hasOverride = false;
|
||||
private Coroutine _resetCoroutine;
|
||||
private HeadBobMode _overrideMode = HeadBobMode.Normal;
|
||||
private bool _hasOverride = false;
|
||||
private Coroutine _resetCoroutine;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
@@ -32,7 +35,7 @@ namespace Unheimlich.Features.Player
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (PlayerController.Instance == null || PlayerController.Instance.CharController == null)
|
||||
if (OctoCore.Components.OctoPlayer.Instance == null || PlayerController.Instance == null || PlayerController.Instance.CharController == null)
|
||||
return;
|
||||
|
||||
var settings = PlayerController.Instance.CameraEffects?.Settings;
|
||||
@@ -66,20 +69,21 @@ namespace Unheimlich.Features.Player
|
||||
}
|
||||
|
||||
// Drive bob parameters directly from the actual physics velocity.
|
||||
// This is naturally in sync with OctoPlayer's inertia — no extra lerp needed.
|
||||
float horizontalSpeed = new Vector3(
|
||||
PlayerController.Instance.CharController.velocity.x,
|
||||
0f,
|
||||
PlayerController.Instance.CharController.velocity.z).magnitude;
|
||||
PlayerController.Instance.CharController.velocity.z
|
||||
).magnitude;
|
||||
|
||||
bool isRunning = PlayerController.Instance.IsRunning;
|
||||
// IsRunning already returns false when OctoPlayer.CanRun is off —
|
||||
// so the bob falls back to walk params automatically.
|
||||
bool isRunning = OctoCore.Components.OctoPlayer.Instance.IsRunning;
|
||||
|
||||
// Normalise: 0 = stopped, 1 = full walk/run speed (m/s converted from km/h ÷ 3.6).
|
||||
const float WalkSpeedMs = 10f / 3.6f;
|
||||
const float RunSpeedMs = 20f / 3.6f;
|
||||
|
||||
float maxSpeed = isRunning ? RunSpeedMs : WalkSpeedMs;
|
||||
float t = Mathf.Clamp01(horizontalSpeed / maxSpeed);
|
||||
float maxSpeed = isRunning ? RunSpeedMs : WalkSpeedMs;
|
||||
float t = Mathf.Clamp01(horizontalSpeed / maxSpeed);
|
||||
|
||||
float targetSpeed = Mathf.Lerp(settings.idleBobSpeed, isRunning ? settings.runBobSpeed : settings.walkBobSpeed, t);
|
||||
float targetAmplitude = Mathf.Lerp(settings.idleBobAmplitude, isRunning ? settings.runBobAmplitude : settings.walkBobAmplitude, t);
|
||||
@@ -99,19 +103,16 @@ namespace Unheimlich.Features.Player
|
||||
var settings = PlayerController.Instance.CameraEffects?.Settings;
|
||||
if (settings == null) return;
|
||||
|
||||
// Strafe direction in local space using actual character velocity.
|
||||
Vector3 velocity = PlayerController.Instance.CharController.velocity;
|
||||
float strafeAmount = Vector3.Dot(velocity, PlayerController.Instance.transform.right);
|
||||
Vector3 velocity = PlayerController.Instance.CharController.velocity;
|
||||
float strafeAmount = Vector3.Dot(velocity, PlayerController.Instance.transform.right);
|
||||
|
||||
// Normalise by run speed (km/h → m/s: / 3.6) to get a -1..1 factor.
|
||||
float runSpeedMs = PlayerController.Instance.Movement != null ? 20f / 3.6f : 5.5f;
|
||||
float strafeFactor = Mathf.Clamp(strafeAmount / runSpeedMs, -1f, 1f);
|
||||
float runSpeedMs = PlayerController.Instance.Movement != null ? 20f / 3.6f : 5.5f;
|
||||
float strafeFactor = Mathf.Clamp(strafeAmount / runSpeedMs, -1f, 1f);
|
||||
|
||||
float targetTilt = -strafeFactor * settings.strafeTiltAngle;
|
||||
_currentTilt = Mathf.Lerp(_currentTilt, targetTilt, Time.deltaTime * settings.strafeTiltSpeed);
|
||||
float targetTilt = -strafeFactor * settings.strafeTiltAngle;
|
||||
_currentTilt = Mathf.Lerp(_currentTilt, targetTilt, Time.deltaTime * settings.strafeTiltSpeed);
|
||||
|
||||
// Compose with the existing local rotation (OctoPlayer already wrote pitch into it).
|
||||
Quaternion baseRot = transform.localRotation;
|
||||
Quaternion baseRot = transform.localRotation;
|
||||
transform.localRotation = baseRot * Quaternion.Euler(0f, 0f, _currentTilt);
|
||||
}
|
||||
|
||||
@@ -121,7 +122,7 @@ namespace Unheimlich.Features.Player
|
||||
public void SetMode(HeadBobMode mode)
|
||||
{
|
||||
_overrideMode = mode;
|
||||
_hasOverride = true;
|
||||
_hasOverride = true;
|
||||
}
|
||||
|
||||
/// <summary>Clears any active mode override and returns to Normal.</summary>
|
||||
@@ -147,25 +148,18 @@ namespace Unheimlich.Features.Player
|
||||
|
||||
// ── Private helpers ───────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>Sets bob speed and amplitude directly without lerp — velocity already carries the inertia.</summary>
|
||||
private void SetBobDirect(float speed, float amplitude)
|
||||
{
|
||||
_currentBobSpeed = speed;
|
||||
_currentBobAmplitude = amplitude;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Advances the bob timer and writes the resulting local position offset.
|
||||
/// Includes a subtle Z roll (Lissajous third axis) for organic feel.
|
||||
/// </summary>
|
||||
private void ApplySmoothedBob(float rollAmplitude)
|
||||
{
|
||||
_timer += Time.deltaTime * _currentBobSpeed;
|
||||
|
||||
float x = Mathf.Sin(_timer * 0.5f) * _currentBobAmplitude * 0.6f;
|
||||
float y = Mathf.Cos(_timer) * _currentBobAmplitude;
|
||||
|
||||
// Micro Z roll: half frequency of Y so it drifts independently.
|
||||
float x = Mathf.Sin(_timer * 0.5f) * _currentBobAmplitude * 0.6f;
|
||||
float y = Mathf.Cos(_timer) * _currentBobAmplitude;
|
||||
float roll = Mathf.Sin(_timer * 0.5f + Mathf.PI * 0.25f) * rollAmplitude * (_currentBobAmplitude / Mathf.Max(0.001f, 0.03f));
|
||||
|
||||
Vector3 newPos = _startLocalPos;
|
||||
@@ -173,21 +167,18 @@ namespace Unheimlich.Features.Player
|
||||
newPos.y += y;
|
||||
transform.localPosition = newPos;
|
||||
|
||||
// Store roll so LateUpdate can composite it with the strafe tilt.
|
||||
// We write only the bob-driven roll here; LateUpdate adds strafe tilt on top.
|
||||
Quaternion bobRot = Quaternion.Euler(0f, 0f, roll);
|
||||
transform.localRotation = bobRot;
|
||||
transform.localRotation = Quaternion.Euler(0f, 0f, roll);
|
||||
}
|
||||
|
||||
private System.Collections.IEnumerator LerpToZeroCoroutine(float duration)
|
||||
{
|
||||
Vector3 startPos = transform.localPosition;
|
||||
float elapsed = 0f;
|
||||
float elapsed = 0f;
|
||||
|
||||
while (elapsed < duration)
|
||||
{
|
||||
elapsed += Time.deltaTime;
|
||||
float t = Mathf.Clamp01(elapsed / duration);
|
||||
float t = Mathf.Clamp01(elapsed / duration);
|
||||
transform.localPosition = Vector3.Lerp(startPos, _startLocalPos, t);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using OctoCore.Inputs;
|
||||
using UnityEngine;
|
||||
using UnityEngine;
|
||||
|
||||
namespace OctoCore.Components
|
||||
{
|
||||
@@ -27,15 +27,24 @@ namespace OctoCore.Components
|
||||
|
||||
[Tooltip("Run speed (km/h).")]
|
||||
public float RunSpeed = 20;
|
||||
|
||||
|
||||
[Tooltip("Jump duration (seconds).")]
|
||||
public float JumpDuration = .4f;
|
||||
|
||||
[Tooltip("Maximum jump height reached at the apex (meters).")]
|
||||
public float JumpHeight = .4f;
|
||||
|
||||
[Tooltip("Maximum step height (meters).")]
|
||||
public float StepHeight = 0.3f;
|
||||
|
||||
[Tooltip("Downward acceleration applied to the player (m/s²).")]
|
||||
public float Gravity = 9.8f;
|
||||
|
||||
[Tooltip("Enable jump.")]
|
||||
public bool CanJump = true;
|
||||
|
||||
[Tooltip("Enable sprint.")]
|
||||
public bool CanRun = true;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
@@ -51,7 +60,6 @@ namespace OctoCore.Components
|
||||
private class FirstPerson
|
||||
{
|
||||
[Header("References")]
|
||||
|
||||
public Camera Camera;
|
||||
|
||||
[Header("Settings")]
|
||||
@@ -68,7 +76,7 @@ namespace OctoCore.Components
|
||||
[Tooltip("Maximum pitch (looking up).")]
|
||||
public float MaxPitch = 80f;
|
||||
}
|
||||
|
||||
|
||||
[SerializeField] private References _references;
|
||||
[SerializeField] private Settings _settings;
|
||||
[SerializeField] private Mapping _mapping;
|
||||
@@ -88,23 +96,38 @@ namespace OctoCore.Components
|
||||
private Vector2 _lookInput;
|
||||
private Vector3 _moveInertia;
|
||||
private Vector3 _moveDirection;
|
||||
|
||||
public bool IsPaused => _isPaused;
|
||||
public float Radius => _references.Controller ? _references.Controller.radius : 0;
|
||||
|
||||
|
||||
public bool IsPaused => _isPaused;
|
||||
public float Radius => _references.Controller ? _references.Controller.radius : 0;
|
||||
|
||||
/// <summary>True when the player is actively sprinting (inertia > 0.1 and CanRun enabled).</summary>
|
||||
public bool IsRunning => _settings.CanRun && _runInertia > 0.1f;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
public bool CanJump
|
||||
{
|
||||
get => _settings.CanJump;
|
||||
set => _settings.CanJump = value;
|
||||
}
|
||||
|
||||
public bool CanRun
|
||||
{
|
||||
get => _settings.CanRun;
|
||||
set => _settings.CanRun = value;
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
if (!Instance) Instance = this;
|
||||
@@ -132,26 +155,22 @@ namespace OctoCore.Components
|
||||
void Update()
|
||||
{
|
||||
_moveInput = _isPaused ? Vector2.zero : Vector2.ClampMagnitude(_moveInput, 1);
|
||||
Camera cam = (_firstPerson.Camera && _firstPerson.Camera.enabled && _firstPerson.Camera.gameObject.activeInHierarchy) ? _firstPerson.Camera : Camera.main;
|
||||
Camera cam = (_firstPerson.Camera && _firstPerson.Camera.enabled && _firstPerson.Camera.gameObject.activeInHierarchy)
|
||||
? _firstPerson.Camera
|
||||
: Camera.main;
|
||||
|
||||
bool accelerating = _moveInput.magnitude > .1f;
|
||||
bool isGrounded = _references.Controller ? _references.Controller.isGrounded : true;
|
||||
float t = Time.deltaTime / 3.6f;
|
||||
bool isGrounded = _references.Controller ? _references.Controller.isGrounded : true;
|
||||
float t = Time.deltaTime / 3.6f;
|
||||
|
||||
// Move
|
||||
// ── Move ────────────────────────────────────────────────────────────
|
||||
|
||||
Vector3 move = new Vector3(_moveInput.x, 0, _moveInput.y);
|
||||
|
||||
if (_settings.Orientation == Orientations.Camera && cam)
|
||||
{
|
||||
Vector3 camForward = cam.transform.forward;
|
||||
camForward.y = 0;
|
||||
camForward.Normalize();
|
||||
|
||||
Vector3 camRight = cam.transform.right;
|
||||
camRight.y = 0;
|
||||
camRight.Normalize();
|
||||
|
||||
Vector3 camForward = cam.transform.forward; camForward.y = 0; camForward.Normalize();
|
||||
Vector3 camRight = cam.transform.right; camRight.y = 0; camRight.Normalize();
|
||||
move = camRight * move.x + camForward * move.z;
|
||||
}
|
||||
|
||||
@@ -159,74 +178,114 @@ namespace OctoCore.Components
|
||||
_moveDirection = Vector3.Lerp(_moveDirection, move, deltaSmooth * 1.5f);
|
||||
|
||||
deltaSmooth *= 1 - Vector3.Cross(_moveInertia, _moveDirection).magnitude;
|
||||
_moveInertia = Vector3.Lerp(_moveInertia, move, deltaSmooth);
|
||||
_moveInertia = Vector3.Lerp(_moveInertia, move, deltaSmooth);
|
||||
|
||||
if (!accelerating && _moveInertia.magnitude < .01f) _moveInertia = Vector3.zero;
|
||||
|
||||
_runInertia = Mathf.Lerp(_runInertia, _runInput ? 1 : 0, t * (accelerating ? 5 : 3));
|
||||
// Sprint inertia — clamped to 0 if CanRun is off
|
||||
_runInertia = Mathf.Lerp(
|
||||
_runInertia,
|
||||
(_runInput && _settings.CanRun) ? 1f : 0f,
|
||||
t * (accelerating ? 5 : 3)
|
||||
);
|
||||
|
||||
Vector3 moveDelta = _moveInertia * t * Mathf.Lerp(_settings.WalkSpeed, _settings.RunSpeed, _runInertia);
|
||||
|
||||
if (isGrounded && _jumpInput && !_jumpping)
|
||||
|
||||
// ── Jump ────────────────────────────────────────────────────────────
|
||||
|
||||
if (isGrounded && _jumpInput && !_jumpping && _settings.CanJump)
|
||||
{
|
||||
_jumpInput = false;
|
||||
_jumpping = true;
|
||||
_jumpLerp = 0;
|
||||
_jumpTime = Time.timeSinceLevelLoad;
|
||||
_jumpInput = false;
|
||||
_jumpping = true;
|
||||
_jumpLerp = 0;
|
||||
_jumpTime = Time.timeSinceLevelLoad;
|
||||
_jumpAltitude = transform.position.y;
|
||||
}
|
||||
|
||||
// Consume the input even if CanJump is off, so it doesn't queue up
|
||||
if (_jumpInput && !_settings.CanJump) _jumpInput = false;
|
||||
|
||||
float jumpOffset = 0;
|
||||
|
||||
if (_jumpping)
|
||||
{
|
||||
_jumpLerp = (Time.timeSinceLevelLoad - _jumpTime) / _settings.JumpDuration;
|
||||
|
||||
if (_jumpLerp >= 1 || (_jumpLerp > .3f && isGrounded))
|
||||
// FIX: added 0.15s grace period before checking isGrounded to avoid immediate re-trigger
|
||||
bool landingAllowed = (Time.timeSinceLevelLoad - _jumpTime) > 0.15f;
|
||||
|
||||
if (_jumpLerp >= 1 || (_jumpLerp > .5f && isGrounded && landingAllowed))
|
||||
{
|
||||
_jumpping = false;
|
||||
_jumpLerp = 0;
|
||||
_jumpping = false;
|
||||
_jumpLerp = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
float x = _jumpLerp;
|
||||
x = x * 2 - 1f;
|
||||
float x = _jumpLerp * 2 - 1f;
|
||||
float y = x < 0
|
||||
? Mathf.Sqrt(1f - x * x)
|
||||
: Mathf.Cos(x * .5f * Mathf.PI);
|
||||
|
||||
float y;
|
||||
if (x < 0) y = Mathf.Sqrt(1f - x * x);
|
||||
else y = Mathf.Cos(x * .5f * Mathf.PI);
|
||||
y = _jumpAltitude + y * _settings.JumpHeight;
|
||||
|
||||
jumpOffset = y - transform.position.y;
|
||||
y = _jumpAltitude + y * _settings.JumpHeight;
|
||||
jumpOffset = y - transform.position.y;
|
||||
}
|
||||
}
|
||||
|
||||
// ── Step-up ─────────────────────────────────────────────────────────
|
||||
if (_references.Controller && isGrounded && !_jumpping)
|
||||
{
|
||||
float feetY = transform.position.y - (_references.Controller.height * 0.5f);
|
||||
|
||||
float castFromY = feetY + _settings.StepHeight;
|
||||
|
||||
Vector3 stepOrigin = new Vector3(transform.position.x, castFromY, transform.position.z);
|
||||
Vector3 stepDir = new Vector3(moveDelta.x, 0, moveDelta.z).normalized;
|
||||
|
||||
if (stepDir.magnitude > 0.1f)
|
||||
{
|
||||
float stepDist = _references.Controller.radius + 0.05f;
|
||||
|
||||
|
||||
if (!Physics.Raycast(stepOrigin, stepDir, stepDist))
|
||||
{
|
||||
Vector3 probeOrigin = stepOrigin + stepDir * stepDist;
|
||||
if (Physics.Raycast(probeOrigin, Vector3.down, out RaycastHit hit, _settings.StepHeight))
|
||||
{
|
||||
float stepUp = hit.point.y - feetY;
|
||||
if (stepUp > 0.05f)
|
||||
moveDelta.y = Mathf.Max(moveDelta.y, stepUp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Apply ───────────────────────────────────────────────────────────
|
||||
|
||||
if (_jumpping)
|
||||
moveDelta.y = jumpOffset;
|
||||
else
|
||||
else if (!isGrounded)
|
||||
moveDelta.y -= _settings.Gravity * Time.deltaTime;
|
||||
else moveDelta.y = -0.1f;
|
||||
|
||||
if (_references.Controller)
|
||||
_references.Controller.Move(moveDelta);
|
||||
else
|
||||
transform.position += moveDelta;
|
||||
|
||||
// Rotate
|
||||
// ── Rotate ──────────────────────────────────────────────────────────
|
||||
|
||||
switch (_settings.Mode)
|
||||
{
|
||||
case PlayerModes.FirstPerson:
|
||||
if (cam && !_isPaused)
|
||||
{
|
||||
Vector2 delta = _lookInput;
|
||||
float mouseX = _lookInput.x * _firstPerson.SensitivityX;
|
||||
float mouseY = _lookInput.y * _firstPerson.SensitivityY * -1;
|
||||
|
||||
float mouseX = delta.x * _firstPerson.SensitivityX;
|
||||
float mouseY = delta.y * _firstPerson.SensitivityY * -1;
|
||||
_yaw += mouseX;
|
||||
_pitch = Mathf.Clamp(_pitch + mouseY, _firstPerson.MinPitch, _firstPerson.MaxPitch);
|
||||
|
||||
_yaw += mouseX;
|
||||
_pitch = Mathf.Clamp(_pitch + mouseY, _firstPerson.MinPitch, _firstPerson.MaxPitch);
|
||||
|
||||
transform.rotation = Quaternion.Euler(0, _yaw, 0);
|
||||
transform.rotation = Quaternion.Euler(0, _yaw, 0);
|
||||
cam.transform.localRotation = Quaternion.Euler(_pitch, 0, 0);
|
||||
}
|
||||
break;
|
||||
@@ -237,74 +296,61 @@ namespace OctoCore.Components
|
||||
if (_moveInertia.magnitude > .002f)
|
||||
{
|
||||
Vector3 offset = _moveInertia - _moveDirection;
|
||||
offset *= _moveInertia.magnitude * _runInertia;
|
||||
offset = Vector3.ClampMagnitude(offset * 1f, 1f);
|
||||
Vector3 up = (Vector3.up - offset).normalized;
|
||||
offset *= _moveInertia.magnitude * _runInertia;
|
||||
offset = Vector3.ClampMagnitude(offset, 1f);
|
||||
Vector3 up = (Vector3.up - offset).normalized;
|
||||
Quaternion lookRot = Quaternion.LookRotation(_moveInertia, up);
|
||||
targetRot = Quaternion.Lerp(targetRot, lookRot, t * 30);
|
||||
targetRot = Quaternion.Lerp(targetRot, lookRot, t * 30);
|
||||
}
|
||||
transform.rotation = targetRot;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset
|
||||
|
||||
// ── Reset ───────────────────────────────────────────────────────────
|
||||
|
||||
_moveInput = Vector2.zero;
|
||||
_lookInput = Vector2.zero;
|
||||
_runInput = false;
|
||||
_runInput = false;
|
||||
}
|
||||
|
||||
public void Teleport(Vector3 position, Quaternion rotation)
|
||||
{
|
||||
_isPaused = _jumpInput = _jumpping = _runInput = false;
|
||||
_runInertia = _jumpLerp = _jumpTime = _jumpAltitude = 0;
|
||||
_moveInput = _lookInput = Vector2.zero;
|
||||
_moveInput = _lookInput = Vector2.zero;
|
||||
_moveInertia = _moveDirection = Vector3.zero;
|
||||
_yaw = rotation.eulerAngles.y;
|
||||
_yaw = rotation.eulerAngles.y;
|
||||
_pitch = 0;
|
||||
|
||||
if (_references.Controller)
|
||||
_references.Controller.enabled = false;
|
||||
|
||||
if (_references.Controller) _references.Controller.enabled = false;
|
||||
transform.position = position;
|
||||
transform.rotation = rotation;
|
||||
|
||||
if (_references.Controller)
|
||||
_references.Controller.enabled = true;
|
||||
if (_references.Controller) _references.Controller.enabled = true;
|
||||
}
|
||||
|
||||
|
||||
public void Pause(bool pause)
|
||||
{
|
||||
_isPaused = pause;
|
||||
|
||||
if (OctoCore.Instance)
|
||||
OctoCore.Instance.UI.SetCursor();
|
||||
if (OctoCore.Instance) OctoCore.Instance.UI.SetCursor();
|
||||
}
|
||||
|
||||
// Convenience methods for external scripts
|
||||
public void SetCanJump(bool value) => _settings.CanJump = value;
|
||||
public void SetCanRun(bool value) => _settings.CanRun = value;
|
||||
|
||||
private void Move(Vector2 value) { _moveInput = value; }
|
||||
private void Look(Vector2 value) { _lookInput = value; }
|
||||
private void Run() { _runInput = true; }
|
||||
private void Run() { _runInput = true; }
|
||||
private void Jump() { _jumpInput = true; }
|
||||
|
||||
private void SetMode()
|
||||
{
|
||||
switch (_settings.Mode)
|
||||
{
|
||||
case PlayerModes.FirstPerson:
|
||||
// Activate First Person Camera
|
||||
break;
|
||||
|
||||
case PlayerModes.ThirdPerson:
|
||||
// Activate Third Person Camera
|
||||
break;
|
||||
case PlayerModes.FirstPerson: break;
|
||||
case PlayerModes.ThirdPerson: break;
|
||||
}
|
||||
}
|
||||
|
||||
/*public static float Arc(float x)
|
||||
{
|
||||
x = Mathf.Clamp01(x) * 2 - 1f;
|
||||
return Mathf.Sqrt(1f - x * x);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,31 @@
|
||||
"key": "ShapeComponent.SettingsEnabled",
|
||||
"value": "{\"m_Value\":false}"
|
||||
},
|
||||
{
|
||||
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
|
||||
"key": "mesh.newShapesSnapToGrid",
|
||||
"value": "{\"m_Value\":true}"
|
||||
},
|
||||
{
|
||||
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
|
||||
"key": "mesh.meshColliderIsConvex",
|
||||
"value": "{\"m_Value\":false}"
|
||||
},
|
||||
{
|
||||
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
|
||||
"key": "editor.backFaceSelectEnabled",
|
||||
"value": "{\"m_Value\":false}"
|
||||
},
|
||||
{
|
||||
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
|
||||
"key": "editor.showSceneInfo",
|
||||
"value": "{\"m_Value\":false}"
|
||||
},
|
||||
{
|
||||
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
|
||||
"key": "editor.showEditorNotifications",
|
||||
"value": "{\"m_Value\":false}"
|
||||
},
|
||||
{
|
||||
"type": "UnityEngine.ProBuilder.SelectMode, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
|
||||
"key": "s_SelectMode",
|
||||
@@ -70,6 +95,46 @@
|
||||
"type": "UnityEngine.Quaternion, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
|
||||
"key": "ShapeBuilder.LastRotation.Prism",
|
||||
"value": "{\"m_Value\":{\"x\":0.0,\"y\":0.0,\"z\":0.0,\"w\":1.0}}"
|
||||
},
|
||||
{
|
||||
"type": "UnityEngine.Material, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
|
||||
"key": "mesh.userMaterial",
|
||||
"value": "{\"m_Value\":{\"instanceID\":0}}"
|
||||
},
|
||||
{
|
||||
"type": "UnityEngine.Rendering.ShadowCastingMode, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
|
||||
"key": "mesh.shadowCastingMode",
|
||||
"value": "{\"m_Value\":1}"
|
||||
},
|
||||
{
|
||||
"type": "UnityEditor.StaticEditorFlags, UnityEditor.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
|
||||
"key": "mesh.defaultStaticEditorFlags",
|
||||
"value": "{\"m_Value\":0}"
|
||||
},
|
||||
{
|
||||
"type": "UnityEngine.ProBuilder.ColliderType, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
|
||||
"key": "mesh.newShapeColliderType",
|
||||
"value": "{\"m_Value\":2}"
|
||||
},
|
||||
{
|
||||
"type": "UnityEngine.ProBuilder.UnwrapParameters, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
|
||||
"key": "lightmapping.defaultLightmapUnwrapParameters",
|
||||
"value": "{\"m_Value\":{\"m_HardAngle\":88.0,\"m_PackMargin\":20.0,\"m_AngleError\":8.0,\"m_AreaError\":15.0}}"
|
||||
},
|
||||
{
|
||||
"type": "UnityEngine.ProBuilder.RectSelectMode, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
|
||||
"key": "editor.dragSelectRectMode",
|
||||
"value": "{\"m_Value\":0}"
|
||||
},
|
||||
{
|
||||
"type": "UnityEngine.ProBuilder.ExtrudeMethod, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
|
||||
"key": "editor.extrudeMethod",
|
||||
"value": "{\"m_Value\":2}"
|
||||
},
|
||||
{
|
||||
"type": "UnityEditor.ProBuilder.Actions.DetachFaces+DetachSetting, Unity.ProBuilder.Editor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
|
||||
"key": "DetachFaces.target",
|
||||
"value": "{\"m_Value\":0}"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user