chunk 1: core gameplay scripts scenes runtime assets

This commit is contained in:
2026-04-06 11:02:34 +03:00
parent fa0388bc79
commit 0d11a097d8
703 changed files with 2292651 additions and 0 deletions

View File

@@ -0,0 +1,203 @@
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using Cinemachine;
/// <summary>
/// Custom Cinemachine input handler that replaces CinemachineInputProvider.
/// Uses CinemachineCore.GetInputAxis delegate for total control over camera orbit.
///
/// Supports:
/// - Gamepad right stick (X = horizontal orbit, Y = vertical orbit)
/// - Mobile touch drag (right half of screen, ignoring UI)
/// - Mouse delta (desktop/editor)
///
/// Attach this to the CinemachineFreeLook camera GameObject.
/// Remove or disable CinemachineInputProvider if present.
/// </summary>
public class CinemachineCameraInput : MonoBehaviour
{
[Header("Sensitivity")]
[SerializeField] private float gamepadSensitivityX = 200f;
[SerializeField] private float gamepadSensitivityY = 3f;
[SerializeField] private float touchSensitivityX = 0.15f;
[SerializeField] private float touchSensitivityY = 0.003f;
[SerializeField] private float mouseSensitivityX = 3f;
[SerializeField] private float mouseSensitivityY = 0.03f;
[Header("Touch Settings")]
[Tooltip("Only process touches on the right portion of the screen (0.5 = right half)")]
[Range(0f, 1f)]
[SerializeField] private float touchActiveScreenRatio = 0.4f;
[Tooltip("Ignore touches over UI elements (buttons, joysticks, etc.)")]
[SerializeField] private bool ignoreUITouches = true;
[Header("Filtering")]
[SerializeField] private float stickDeadzone = 0.15f;
[SerializeField] private float smoothing = 0.1f;
// Touch tracking
private int activeTouchId = -1;
private Vector2 lastTouchPos;
// Smoothed output
private float smoothedX;
private float smoothedY;
private float rawX;
private float rawY;
// Axis names used by CinemachineFreeLook
private const string XAxisName = "Mouse X";
private const string YAxisName = "Mouse Y";
private CinemachineFreeLook freeLookCam;
private void Awake()
{
freeLookCam = GetComponent<CinemachineFreeLook>();
}
private void OnEnable()
{
// Override Cinemachine's input gathering with our custom handler
CinemachineCore.GetInputAxis = HandleCinemachineInput;
// Disable CinemachineInputProvider if present (we replace it)
var provider = GetComponent<CinemachineInputProvider>();
if (provider != null)
{
provider.enabled = false;
Debug.Log("[CinemachineCameraInput] Disabled CinemachineInputProvider — using custom input handler");
}
// Clear the default input axis names on the FreeLook camera
// This prevents Cinemachine from also reading legacy Input Manager axes
if (freeLookCam != null)
{
freeLookCam.m_XAxis.m_InputAxisName = "";
freeLookCam.m_YAxis.m_InputAxisName = "";
}
Debug.Log("[CinemachineCameraInput] Custom camera input enabled (gamepad + touch + mouse)");
}
private void OnDisable()
{
// Restore default input handling when disabled
CinemachineCore.GetInputAxis = UnityEngine.Input.GetAxis;
}
private void Update()
{
// Gather raw input from all sources
rawX = 0f;
rawY = 0f;
ReadGamepadInput();
ReadTouchInput();
ReadMouseInput();
// Smooth the input
if (smoothing > 0.001f)
{
smoothedX = Mathf.Lerp(smoothedX, rawX, Time.unscaledDeltaTime / smoothing);
smoothedY = Mathf.Lerp(smoothedY, rawY, Time.unscaledDeltaTime / smoothing);
}
else
{
smoothedX = rawX;
smoothedY = rawY;
}
}
/// <summary>
/// Delegate callback — Cinemachine calls this instead of Input.GetAxis
/// </summary>
private float HandleCinemachineInput(string axisName)
{
if (axisName == XAxisName) return smoothedX;
if (axisName == YAxisName) return smoothedY;
return 0f;
}
// ======================== GAMEPAD ========================
private void ReadGamepadInput()
{
if (Gamepad.current == null) return;
Vector2 rightStick = Gamepad.current.rightStick.ReadValue();
// Apply deadzone
if (rightStick.magnitude < stickDeadzone)
return;
rawX += rightStick.x * gamepadSensitivityX * Time.unscaledDeltaTime;
rawY += rightStick.y * gamepadSensitivityY * Time.unscaledDeltaTime;
}
// ======================== TOUCH ========================
private void ReadTouchInput()
{
if (Touchscreen.current == null) return;
var touches = Touchscreen.current.touches;
bool foundActiveTouch = false;
for (int i = 0; i < touches.Count; i++)
{
var touch = touches[i];
if (!touch.press.isPressed) continue;
int id = touch.touchId.ReadValue();
Vector2 pos = touch.position.ReadValue();
// If no active touch, try to start tracking this one
if (activeTouchId == -1)
{
// Only track touches on the right portion of the screen
if (pos.x < Screen.width * touchActiveScreenRatio)
continue;
// Ignore touches over UI elements
if (ignoreUITouches && EventSystem.current != null &&
EventSystem.current.IsPointerOverGameObject(id))
continue;
activeTouchId = id;
lastTouchPos = pos;
continue;
}
if (touch.touchId.ReadValue() != activeTouchId)
continue;
foundActiveTouch = true;
Vector2 delta = pos - lastTouchPos;
lastTouchPos = pos;
rawX += delta.x * touchSensitivityX;
rawY += delta.y * touchSensitivityY;
}
// Reset tracking if active touch released
if (activeTouchId != -1 && !foundActiveTouch)
{
activeTouchId = -1;
}
}
// ======================== MOUSE ========================
private void ReadMouseInput()
{
if (Mouse.current == null) return;
// Only use mouse if right button is held (prevents accidental camera rotation)
if (!Mouse.current.rightButton.isPressed) return;
Vector2 mouseDelta = Mouse.current.delta.ReadValue();
rawX += mouseDelta.x * mouseSensitivityX * Time.unscaledDeltaTime;
rawY += mouseDelta.y * mouseSensitivityY * Time.unscaledDeltaTime;
}
}