This commit is contained in:
Oscar
2025-05-25 19:14:50 +03:00
parent df4b259d17
commit 4d212f2ff8
27 changed files with 735 additions and 142 deletions

226
Code/Player/Dedugan.cs Normal file
View File

@@ -0,0 +1,226 @@
using System;
using Sandbox;
using Sandbox.Citizen;
using ShrimpleCharacterController;
public sealed class Dedugan : Component
{
[RequireComponent] public ShrimpleCharacterController.ShrimpleCharacterController Controller { get; set; }
[RequireComponent] public CitizenAnimationHelper AnimationHelper { get; set; }
public SkinnedModelRenderer Renderer { get; set; }
public GameObject Camera { get; set; }
[Property][Range(1f, 200f, 1f)] public float CamOffsetX { get; set; }
[Property] public GameObject CameraPivot { get; set; }
[Property] [Range(50f, 1200f, 10f)] public float WalkSpeed { get; set; } = 100f;
[Property] [Range(100f, 1500f, 20f)] public float RunSpeed { get; set; } = 300f;
[Property] [Range(25f, 1100f, 5f)] public float DuckSpeed { get; set; } = 50f;
[Property] [Range(200f, 1500f, 20f)] public float JumpStrength { get; set; } = 350f;
[Sync] public Angles NetworkedEyeAngles { get; set; } // для передачи углов другим клиентам
private RagdollController RagdollController { get; set; }
public Angles EyeAngles { get; set; }
public Vector3 OverrideGravity { get; set; } = Vector3.Zero;
private Vector3 _directionToAxis = Vector3.Up;
private Vector3 _up = Vector3.Up;
private Vector3 _forward = Vector3.Forward;
private Vector3 _right = Vector3.Right;
[Sync] private float IsDucking { get; set; } = 0f;
private Vector3 wishDirection;
protected override void OnStart()
{
base.OnStart();
RagdollController = Components.Get<RagdollController>();
Renderer = Components.Get<SkinnedModelRenderer>(FindMode.EverythingInSelfAndDescendants);
if (!Network.IsOwner) return;
// var cameraComponent = GameObject.GetComponentInParent<CameraComponent>(true, true) ;//new GameObject(true, "Camera");
var cameraComponent = Scene.Camera ;//new GameObject(true, "Camera");
Camera = cameraComponent.GameObject;
Camera.SetParent(GameObject);
// var cameraComponent = Camera.Components.Create<CameraComponent>();
cameraComponent.ZFar = 32768f;
cameraComponent.FieldOfView = 100f;
}
protected override void DrawGizmos()
{
base.DrawGizmos();
Gizmo.Transform = global::Transform.Zero;
Gizmo.Draw.LineThickness = 2f;
Gizmo.Draw.IgnoreDepth = true;
Gizmo.Draw.Color = Color.Blue;
Gizmo.Draw.Arrow(WorldPosition, WorldPosition + (_up * 1200f));
Gizmo.Draw.Color = Color.Red;
Gizmo.Draw.Arrow(WorldPosition, WorldPosition + (_forward * 1200f));
Gizmo.Draw.Color = Color.Green;
Gizmo.Draw.Arrow(WorldPosition, WorldPosition + (_right * 1200f));
Gizmo.Draw.Color = Color.Black;
Gizmo.Draw.Arrow(WorldPosition, WorldPosition + (-_up * 100f));
Gizmo.Draw.Color = Color.Magenta;
Gizmo.Draw.Arrow(WorldPosition, WorldPosition + wishDirection * 10f);
var textStartPos = new Vector2(10f);
Gizmo.Draw.ScreenText($"IsOnGround: {Controller.IsOnGround}", textStartPos);
Gizmo.Draw.ScreenText($"IsSlipping: {Controller.IsSlipping}", textStartPos.WithY(30f));
Gizmo.Draw.ScreenText($"WishVelocity: {Controller.WishVelocity}", textStartPos.WithY(50f));
Gizmo.Draw.ScreenText($"Test: {Vector3.Dot(_right, _up)}", textStartPos.WithY(70f));
Gizmo.Draw.ScreenBiasedHalfCircle(WorldPosition, 3f);
}
protected override void OnFixedUpdate()
{
base.OnFixedUpdate();
if ( OverrideGravity == Vector3.Zero )
{
_directionToAxis = Vector3.VectorPlaneProject(WorldPosition, Vector3.Right).Normal;
}
else
{
_directionToAxis = OverrideGravity;
}
_up = -_directionToAxis;
_forward = Vector3.Right;
_right = Vector3.Cross(_up, _forward).Normal;
Controller.Up = _up;
Controller.VectorGravity = -_up * 850f;
if (Network.IsOwner)
{
LookAtSurfaceNormal(_up, _forward);
wishDirection = Input.AnalogMove.Normal * Rotation.FromYaw(EyeAngles.yaw) * WorldRotation;
var isDucking = Input.Down("Duck");
var isRunning = Input.Down("Run");
var wishSpeed = isDucking ? DuckSpeed :
isRunning ? RunSpeed : WalkSpeed;
var ragdollMul = RagdollController.Enabled ? 0f : 1f;
Controller.WishVelocity = wishDirection * wishSpeed * ragdollMul;
if (Input.Pressed("Jump") && Controller.IsOnGround)
{
Controller.Punch(-Controller.AppliedGravity.Normal * JumpStrength);
AnimationHelper?.TriggerJump();
}
if (!AnimationHelper.IsValid()) return;
IsDucking = Input.Down("Duck") ? 1f : 0f;
}
Controller.Move();
if (!AnimationHelper.IsValid()) return;
AnimationHelper.DuckLevel = IsDucking;
AnimationHelper.WithWishVelocity(Controller.WishVelocity);
AnimationHelper.WithVelocity(Controller.Velocity);
AnimationHelper.IsGrounded = Controller.IsOnGround;
}
private void LookAtSurfaceNormal(Vector3 up, Vector3 moveDirection)
{
var newRotation = Rotation.LookAt(moveDirection, up);
WorldRotation = Rotation.Lerp(WorldRotation, newRotation, Time.Delta * 10f);
}
protected override void OnUpdate()
{
base.OnUpdate();
if (Network.IsOwner)
{
EyeAngles += Input.AnalogLook;
EyeAngles = EyeAngles.WithPitch(MathX.Clamp(EyeAngles.pitch, -89f, 89f));
NetworkedEyeAngles = EyeAngles;
RotateCamera();
var targetRotation = Rotation.LookAt(Rotation.FromYaw(EyeAngles.yaw).Forward, -_directionToAxis);
var currentForward = Renderer.LocalRotation.Forward;
float angleDiff = currentForward.Angle(targetRotation.Forward);
if (angleDiff > 15f && Controller.Velocity.Length > 10f)
{
Renderer.LocalRotation = Rotation.Slerp(Renderer.LocalRotation, Rotation.FromYaw(EyeAngles.yaw), Time.Delta * 3f);
}
if ( Input.Pressed( "Use" ) )
{
var tr = Scene.Trace
.Ray( Camera.WorldPosition, Camera.WorldPosition + Camera.WorldRotation.Forward * 500f ).IgnoreGameObjectHierarchy(GameObject).Run();
if ( tr.Hit)
{
tr.GameObject.GetComponent<IInteractable>()?.OnUse();
}
}
}
else
{
EyeAngles = NetworkedEyeAngles;
Renderer.LocalRotation = Rotation.Slerp(Renderer.LocalRotation, Rotation.FromYaw(EyeAngles.yaw), Time.Delta * 5f);
}
}
void RotateCamera()
{
var cameraOffset = CameraPivot.LocalPosition + CameraPivot.LocalRotation.Backward * (CamOffsetX + EyeAngles.pitch * .5f);
Camera.LocalRotation = EyeAngles.ToRotation();
Camera.LocalPosition = cameraOffset * Camera.LocalRotation;
}
// void RotateCamera()
// {
// // 1. Задание локального вращения камеры
// Rotation camRot = EyeAngles.ToRotation();
// Camera.LocalRotation = camRot;
//
// // 2. Позиция Pivot'а в мире (нужно для трейса)
// var pivotWorldPos = CameraPivot.LocalPosition;
//
// // 3. Смещение плеча (локально → в мир)
// var shoulderOffsetWorld = Vector3.Zero;
//
// // 4. Желаемая мировая позиция камеры
// var desiredWorldPos = pivotWorldPos - camRot.Forward * 10f + shoulderOffsetWorld;
//
// // 5. Трейс от Pivot до желаемой позиции камеры
// var tr = Scene.Trace
// .Ray(pivotWorldPos, desiredWorldPos)
// .Radius(4f)
// .IgnoreGameObjectHierarchy(GameObject)
// .Run();
//
// // 6. Получаем локальную позицию относительно CameraPivot
// var finalWorldCamPos = tr.EndPosition;
// var finalLocalCamPos = CameraPivot.Transform.WorldToLocal.Transform(finalWorldCamPos);
//
// // 7. Применяем к камере
// Camera.LocalPosition = finalLocalCamPos;
// Camera.LocalRotation = camRot;
// }
}

View File

@@ -0,0 +1,17 @@
using System;
namespace Sandbox;
public class PlayerDresser : Component, Component.INetworkSpawn
{
[Property]
public SkinnedModelRenderer BodyRenderer { get; set; }
public void OnNetworkSpawn( Connection owner )
{
Log.Info( $"Hello {owner.Name}" );
var clothing = new ClothingContainer();
clothing.Deserialize( owner.GetUserData( "avatar" ) );
clothing.Apply( BodyRenderer );
}
}

View File

@@ -0,0 +1,48 @@
using Sandbox;
public sealed class RagdollController : Component
{
[Group("Setup"), Order(-100), Property] public ModelPhysics bodyPhysics { get; set; }
[Group("Setup"), Order(-100), Property] public SkinnedModelRenderer bodyRenderer { get; set; }
[Group("Config"), Order(0), Property] public bool isLocked { get; set; }
[Sync]
public new bool Enabled
{
get => bodyPhysics.Enabled;
private set
{
bodyPhysics.Enabled = value;
bodyPhysics.MotionEnabled = value;
bodyRenderer.UseAnimGraph = !value;
if ( !value )
{
WorldPosition = bodyRenderer.WorldPosition;
bodyRenderer.LocalPosition = Vector3.Zero;
}
}
}
protected override void OnUpdate()
{
if ( Network.IsOwner )
{
if (Input.Pressed( "Ragdoll" ))
{
Enabled = !Enabled;
}
}
var bodyLock = new PhysicsLock();
bodyLock.Pitch = isLocked;
bodyLock.Yaw = isLocked;
bodyLock.Roll = isLocked;
bodyLock.X = isLocked;
bodyLock.Y = isLocked;
bodyLock.Z = isLocked;
bodyPhysics.Locking = bodyLock;
bodyPhysics.MotionEnabled = !isLocked;
WorldPosition = bodyRenderer.WorldPosition;
}
}