Загрузка данных
using System;
using System.Windows.Forms;
using GTA;
using GTA.Math;
using GTA.Native;
public class SedanCabinCamera : Script
{
private Camera _carCamera;
private float _heightOffset = 0.50f;
private bool _wasInCar = false;
private float _mouseYaw = 0.0f;
private float _camPitch = 10.0f;
public SedanCabinCamera()
{
KeyDown += OnKeyDown;
Tick += OnTick;
GTA.UI.Notification.Show("~g~Камера (орбита + коллизии) загружена!");
}
private void OnTick(object sender, EventArgs e)
{
var vehicle = Game.Player.Character.CurrentVehicle;
if (vehicle == null) { RemoveCamera(); _wasInCar = false; return; }
bool isTarget = (vehicle.Model.Hash == Game.GenerateHash("jzx100") ||
vehicle.Model.Hash == Game.GenerateHash("mk2100"));
if (!isTarget) { RemoveCamera(); _wasInCar = false; return; }
if (!_wasInCar)
{
_mouseYaw = 0.0f;
_camPitch = 10.0f;
_wasInCar = true;
}
if (Function.Call<int>(Hash.GET_FOLLOW_VEHICLE_CAM_VIEW_MODE) == 4)
{ RemoveCamera(); return; }
bool isAiming = Function.Call<bool>(Hash.IS_CONTROL_PRESSED, 0, 25);
if (isAiming)
{
if (World.RenderingCamera == _carCamera)
{
World.RenderingCamera = null;
Function.Call(Hash.RENDER_SCRIPT_CAMS, false, false, 0, true, false);
}
return;
}
else
{
if (World.RenderingCamera == null || World.RenderingCamera != _carCamera)
{
if (_carCamera == null || !_carCamera.Exists())
_carCamera = World.CreateCamera(vehicle.Position, vehicle.Rotation, 60f);
World.RenderingCamera = _carCamera;
Function.Call(Hash.RENDER_SCRIPT_CAMS, true, false, 0, true, false);
}
}
if (_carCamera == null || !_carCamera.Exists())
_carCamera = World.CreateCamera(vehicle.Position, vehicle.Rotation, 60f);
float lookLR = Function.Call<float>(Hash.GET_CONTROL_NORMAL, 0, 2);
float lookUD = Function.Call<float>(Hash.GET_CONTROL_NORMAL, 0, 3);
_mouseYaw -= lookLR * 6.0f;
_camPitch -= lookUD * 3.0f;
_camPitch = Math.Max(-10.0f, Math.Min(45.0f, _camPitch));
float finalHeading = vehicle.Heading + _mouseYaw;
if (Function.Call<bool>(Hash.IS_CONTROL_PRESSED, 0, 26))
finalHeading += 180.0f;
float radH = finalHeading * (float)(Math.PI / 180.0);
float radP = _camPitch * (float)(Math.PI / 180.0);
float dist = 4.25f;
Vector3 center = vehicle.Position + new Vector3(0, 0, _heightOffset);
// Вычисляем идеальную точку, где камера ХОЧЕТ быть
float camX = center.X - (float)Math.Sin(radH) * dist * (float)Math.Cos(radP);
float camY = center.Y - (float)Math.Cos(radH) * dist * (float)Math.Cos(radP);
float camZ = center.Z + (float)Math.Sin(radP) * dist;
Vector3 desiredPos = new Vector3(camX, camY, camZ);
// --- КОЛЛИЗИИ: Пускаем луч от машины к камере ---
RaycastResult ray = World.Raycast(center, desiredPos, IntersectFlags.Map, vehicle);
// Если луч встретил препятствие, ставим камеру ПЕРЕД стеной
if (ray.DitHitAnything)
{
desiredPos = ray.HitPosition;
}
_carCamera.Position = desiredPos;
_carCamera.Rotation = new Vector3(-_camPitch, 0f, finalHeading);
}
private void OnKeyDown(object sender, KeyEventArgs e)
{
var vehicle = Game.Player.Character.CurrentVehicle;
if (vehicle == null) return;
bool isTarget = (vehicle.Model.Hash == Game.GenerateHash("jzx100") ||
vehicle.Model.Hash == Game.GenerateHash("mk2100"));
if (!isTarget) return;
if (e.KeyCode == Keys.NumPad9)
{
_heightOffset += 0.05f;
GTA.UI.Notification.Show("~g~Высота: " + _heightOffset.ToString("F2"));
}
else if (e.KeyCode == Keys.NumPad3)
{
_heightOffset -= 0.05f;
GTA.UI.Notification.Show("~y~Высота: " + _heightOffset.ToString("F2"));
}
}
private void RemoveCamera()
{
if (_carCamera != null && _carCamera.Exists())
{
World.RenderingCamera = null;
Function.Call(Hash.RENDER_SCRIPT_CAMS, false, false, 0, true, false);
Function.Call(Hash.DESTROY_CAM, _carCamera.Handle, true);
_carCamera = null;
}
}
}