first commit
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
using UnityEngine;
|
||||
|
||||
[DefaultExecutionOrder(-50)]
|
||||
[RequireComponent(typeof(CharacterController))]
|
||||
[RequireComponent(typeof(SimpleFPSController))]
|
||||
public class PlayerStealth : MonoBehaviour
|
||||
{
|
||||
public enum NoiseState
|
||||
{
|
||||
Silent,
|
||||
Low,
|
||||
Medium,
|
||||
High
|
||||
}
|
||||
|
||||
[Header("References")]
|
||||
public CharacterController characterController;
|
||||
public SimpleFPSController fpsController;
|
||||
public Camera playerCamera;
|
||||
|
||||
[Header("Crouch")]
|
||||
public float standingHeight = 2f;
|
||||
public float crouchingHeight = 1.2f;
|
||||
public float crouchSpeedMultiplier = 0.55f;
|
||||
public float standingCameraLocalY = 0.8f;
|
||||
public float crouchCameraLocalY = 0.35f;
|
||||
public float crouchTransitionSpeed = 8f;
|
||||
public float crouchVisibilityMultiplier = 0.72f;
|
||||
|
||||
[Header("Noise")]
|
||||
public float noiseEmitInterval = 0.35f;
|
||||
public float crouchNoiseIntensity = 0.45f;
|
||||
public float walkNoiseIntensity = 0.8f;
|
||||
public float runNoiseIntensity = 1.25f;
|
||||
public float testNoiseIntensity = 1.6f;
|
||||
|
||||
public bool IsCrouching { get; private set; }
|
||||
public NoiseState CurrentNoiseState { get; private set; } = NoiseState.Silent;
|
||||
public float CurrentNoiseIntensity { get; private set; }
|
||||
public float VisibilityMultiplier => IsCrouching ? crouchVisibilityMultiplier : 1f;
|
||||
public string CurrentNoiseLabel => CurrentNoiseState.ToString().ToLowerInvariant();
|
||||
|
||||
private float currentControllerHeight;
|
||||
private float targetCameraLocalY;
|
||||
private float lastNoiseEmitTime = -999f;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
characterController = characterController != null ? characterController : GetComponent<CharacterController>();
|
||||
fpsController = fpsController != null ? fpsController : GetComponent<SimpleFPSController>();
|
||||
playerCamera = playerCamera != null ? playerCamera : GetComponentInChildren<Camera>();
|
||||
|
||||
currentControllerHeight = standingHeight;
|
||||
targetCameraLocalY = standingCameraLocalY;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
ApplyCharacterHeightImmediate(standingHeight);
|
||||
SetCameraLocalY(standingCameraLocalY);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
UpdateCrouchState();
|
||||
UpdateNoiseState();
|
||||
HandleManualNoise();
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
SmoothCrouchPresentation();
|
||||
}
|
||||
|
||||
private void UpdateCrouchState()
|
||||
{
|
||||
IsCrouching = Input.GetKey(KeyCode.LeftControl);
|
||||
fpsController.AllowRunning = !IsCrouching;
|
||||
fpsController.SpeedScale = IsCrouching ? crouchSpeedMultiplier : 1f;
|
||||
targetCameraLocalY = IsCrouching ? crouchCameraLocalY : standingCameraLocalY;
|
||||
}
|
||||
|
||||
private void UpdateNoiseState()
|
||||
{
|
||||
if (!fpsController.HasMovementInput)
|
||||
{
|
||||
SetNoiseState(NoiseState.Silent, 0f);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsCrouching)
|
||||
{
|
||||
SetNoiseState(NoiseState.Low, crouchNoiseIntensity);
|
||||
}
|
||||
else if (fpsController.IsRunning)
|
||||
{
|
||||
SetNoiseState(NoiseState.High, runNoiseIntensity);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetNoiseState(NoiseState.Medium, walkNoiseIntensity);
|
||||
}
|
||||
|
||||
if (CurrentNoiseState != NoiseState.Silent && Time.time >= lastNoiseEmitTime + noiseEmitInterval)
|
||||
{
|
||||
lastNoiseEmitTime = Time.time;
|
||||
// Периодические импульсы шума проще настраивать и удобнее для AI, чем шум каждый кадр.
|
||||
NoiseManager.EmitNoise(transform.position, CurrentNoiseIntensity);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleManualNoise()
|
||||
{
|
||||
if (Input.GetKeyDown(KeyCode.R))
|
||||
{
|
||||
NoiseManager.EmitNoise(transform.position, testNoiseIntensity);
|
||||
}
|
||||
}
|
||||
|
||||
private void SmoothCrouchPresentation()
|
||||
{
|
||||
float desiredHeight = IsCrouching ? crouchingHeight : standingHeight;
|
||||
currentControllerHeight = Mathf.Lerp(currentControllerHeight, desiredHeight, Time.deltaTime * crouchTransitionSpeed);
|
||||
ApplyCharacterHeightImmediate(currentControllerHeight);
|
||||
|
||||
if (playerCamera != null)
|
||||
{
|
||||
Vector3 localPosition = playerCamera.transform.localPosition;
|
||||
localPosition.y = Mathf.Lerp(localPosition.y, targetCameraLocalY, Time.deltaTime * crouchTransitionSpeed);
|
||||
playerCamera.transform.localPosition = localPosition;
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyCharacterHeightImmediate(float height)
|
||||
{
|
||||
characterController.height = height;
|
||||
characterController.center = new Vector3(0f, height * 0.5f, 0f);
|
||||
}
|
||||
|
||||
private void SetCameraLocalY(float localY)
|
||||
{
|
||||
if (playerCamera == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 localPosition = playerCamera.transform.localPosition;
|
||||
localPosition.y = localY;
|
||||
playerCamera.transform.localPosition = localPosition;
|
||||
}
|
||||
|
||||
private void SetNoiseState(NoiseState state, float intensity)
|
||||
{
|
||||
CurrentNoiseState = state;
|
||||
CurrentNoiseIntensity = intensity;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user