This commit is contained in:
Oscar
2025-05-28 17:15:12 +03:00
parent 37173c8b39
commit 77c1704cd6
35 changed files with 80065 additions and 851 deletions

View File

@@ -0,0 +1,15 @@
using Sandbox;
public sealed partial class Dedugan
{
void UpdateCustomAnimations()
{
if ( Network.IsOwner )
{
// IsDancing = Input.Down( "Dance" );
}
Log.Info(IsDancing);
Renderer.Set( "test_dance", IsDancing );
}
}

View File

@@ -10,9 +10,19 @@
}
else
{
// Camera.LocalRotation = EyeAngles.ToRotation();
// var offset = CameraPivot.LocalPosition + CameraPivot.LocalRotation.Backward * CamOffsetX;
// Camera.LocalPosition = offset * Camera.LocalRotation;
Camera.LocalRotation = EyeAngles.ToRotation();
var offset = CameraPivot.LocalPosition + CameraPivot.LocalRotation.Backward * (CamOffsetX + EyeAngles.pitch * .5f);
Camera.LocalPosition = offset * Camera.LocalRotation;
var pivotOffset = CameraPivot.LocalRotation.Backward * CamOffsetX;
var localPitchOffset = Camera.LocalRotation.Down * MathF.Max( 0f, EyeAngles.pitch ) * 0.32f +
Camera.LocalRotation.Backward * MathF.Max( 0f, EyeAngles.pitch ) * 0.7f +
Camera.LocalRotation.Up * MathF.Min( 0f, EyeAngles.pitch ) * 0.5f +
Camera.LocalRotation.Backward * MathF.Min( 0f, EyeAngles.pitch ) * 0.8f;
var offset = (CameraPivot.LocalPosition + pivotOffset ) * EyeAngles.ToRotation() + localPitchOffset;
Camera.LocalPosition = offset;
}
}
}

View File

@@ -1,302 +1,219 @@
public sealed partial class Dedugan
using Sandbox;
using Sandbox.Utility;
using Sandbox.Diagnostics;
using System.Linq;
public sealed partial class Dedugan : Component
{
public Component Pressed { get; set; }
public bool EnablePressing { get; set; } = true;
public Component Hovered { get; set; }
public Component Pressed { get; set; }
public bool EnablePressing { get; set; } = true;
public Component Hovered { get; set; }
[Sync( SyncFlags.Interpolate )]
public Vector3 TracedHitPos { get; set; }
[Sync]
public bool CameraTraceIsHit { get; set; }
public Vector3 TracedHitNormal { get; set; }
[Sync(SyncFlags.Interpolate)]
public Vector3 TracedHitPos { get; set; }
[Sync]
public bool CameraTraceIsHit { get; set; }
public Vector3 TracedHitNormal { get; set; }
private GameObject interactionPanel;
private static GameObject interactionPanelPrefab;
// private TimeSince HoldTime = 0;
// private bool Holding = false;
// private bool HoldingInteractionHappened = false;
private TimeSince holdTimer;
private bool isHolding;
private bool triggered;
void InteractionsUpdate()
{
if (!EnablePressing)
{
// Holding = false;
// HoldingInteractionHappened = false;
return;
}
private const string InteractionPrefabPath = "prefabs/InteractionPanel.prefab";
if (Pressed.IsValid())
{
UpdatePressed();
}
else
{
UpdateHovered();
}
}
public void UpdateLookAt()
{
if ( EnablePressing )
{
if ( Pressed.IsValid() )
{
UpdatePressed();
}
else
{
UpdateHovered();
}
}
}
private void UpdatePressed()
{
bool flag = Input.Down("use");
private void UpdatePressed()
{
bool flag = Input.Pressed( "Use" );
if (flag && Pressed.Components.TryGet<IPressable>(out var pressable))
{
flag = pressable.Pressing(new IPressable.Event
{
Ray = new Ray(Camera.WorldPosition, EyeAngles.ToRotation().Forward),
Source = this
});
}
if ( flag && Pressed.Components.TryGet<IPressable>( out var pressable ) )
{
if ( pressable.RequiresHold )
{
if ( !isHolding )
{
holdTimer = 0;
isHolding = true;
triggered = false;
}
if (GetDistanceFromGameObject(Pressed.GameObject, Camera.WorldPosition) > InteractDistance)
{
flag = false;
}
if ( triggered ) return;
if (!flag)
{
StopPressing();
}
}
var progress = holdTimer / pressable.HoldTime;
ShowInteractionUI( TracedHitPos, pressable.DisplayText, true, progress );
private void UpdateHovered()
{
SwitchHovered(TryGetLookedAt());
if ( holdTimer > pressable.HoldTime )
{
triggered = true;
pressable.Pressing( new IPressable.Event
{
Ray = new Ray( Camera.WorldPosition, EyeAngles.ToRotation().Forward ),
Source = this
} );
}
}
else
{
flag = pressable.Pressing( new IPressable.Event
{
Ray = new Ray( Camera.WorldPosition, EyeAngles.ToRotation().Forward ),
Source = this
} );
}
}
if (Hovered is IPressable pressable)
{
pressable.Look(new IPressable.Event
{
Ray = new Ray(Camera.WorldPosition, EyeAngles.ToRotation().Forward),
Source = this
});
}
if ( GetDistanceFromGameObject( Pressed.GameObject, Camera.WorldPosition ) > InteractDistance )
{
flag = false;
}
if (Input.Down("use"))
{
StartPressing(Hovered);
}
}
if ( !flag )
{
StopPressing();
}
}
public void StartPressing(Component obj)
{
StopPressing();
if (!obj.IsValid())
{
ISceneEvent<PlayerController.IEvents>.PostToGameObject(GameObject, x => x.FailPressing());
return;
}
private void UpdateHovered()
{
SwitchHovered( TryGetLookedAt() );
var component = obj.Components.Get<IPressable>(FindMode.EnabledInSelfAndDescendants);
if (component != null)
{
var pressEvent = new IPressable.Event
{
Ray = new Ray(Camera.WorldPosition, EyeAngles.ToRotation().Forward),
Source = this
};
if ( Hovered is IPressable pressable )
{
pressable.Look( new IPressable.Event
{
Ray = new Ray( Camera.WorldPosition, EyeAngles.ToRotation().Forward ),
Source = this
} );
if (!component.CanPress(pressEvent))
{
ISceneEvent<PlayerController.IEvents>.PostToGameObject(GameObject, x => x.FailPressing());
return;
}
ShowInteractionUI( TracedHitPos, pressable.DisplayText );
}
else
{
ClearInteractionUI();
}
component.Press(pressEvent);
}
if ( Input.Pressed( "use" ) )
{
StartPressing( Hovered );
}
}
Pressed = obj;
public void StartPressing( Component obj )
{
StopPressing();
if (Pressed.IsValid())
{
ISceneEvent<PlayerController.IEvents>.PostToGameObject(GameObject, x => x.StartPressing(Pressed));
}
}
if ( !obj.IsValid() )
{
ISceneEvent<PlayerController.IEvents>.PostToGameObject( GameObject, x => x.FailPressing() );
return;
}
public void StopPressing()
{
if (Pressed.IsValid())
{
ISceneEvent<PlayerController.IEvents>.PostToGameObject(GameObject, x => x.StopPressing(Pressed));
var component = obj.Components.Get<IPressable>( FindMode.EnabledInSelfAndDescendants );
if (Pressed is IPressable pressable)
{
pressable.Release(new IPressable.Event
{
Ray = new Ray(Camera.WorldPosition, EyeAngles.ToRotation().Forward),
Source = this
});
}
if ( component != null )
{
if ( !component.CanPress( new IPressable.Event
{
Ray = new Ray( Camera.WorldPosition, EyeAngles.ToRotation().Forward ),
Source = this
} ) )
{
ISceneEvent<PlayerController.IEvents>.PostToGameObject( GameObject, x => x.FailPressing() );
return;
}
Pressed = null;
}
}
component.Press( new IPressable.Event
{
Ray = new Ray( Camera.WorldPosition, EyeAngles.ToRotation().Forward ),
Source = this
} );
}
private void SwitchHovered(Component obj)
{
var e = new IPressable.Event
{
Ray = new Ray(Camera.WorldPosition, EyeAngles.ToRotation().Forward),
Source = this
};
Pressed = obj;
if (Hovered == obj)
{
if (Hovered is IPressable pressable)
pressable.Look(e);
return;
}
if ( Pressed.IsValid() )
{
ISceneEvent<PlayerController.IEvents>.PostToGameObject( GameObject, x => x.StartPressing( Pressed ) );
}
}
if (Hovered is IPressable oldPressable)
oldPressable.Blur(e);
private Component TryGetLookedAt()
{
for ( float num = 0f; num <= 4f; num += 2f )
{
var from = Scene.Camera.WorldPosition + Scene.Camera.WorldRotation.Forward;
var to = from + Scene.Camera.WorldRotation.Forward * (InteractDistance - num);
var eyeTrace = Scene.Trace.Ray( from, to ).IgnoreGameObjectHierarchy( GameObject ).Radius( num ).Run();
Hovered = obj;
TracedHitPos = eyeTrace.Hit ? eyeTrace.HitPosition : eyeTrace.EndPosition;
CameraTraceIsHit = eyeTrace.Hit;
TracedHitNormal = eyeTrace.Normal;
if (Hovered is IPressable newPressable)
{
newPressable.Hover(e);
newPressable.Look(e);
}
}
if ( !eyeTrace.Hit || !eyeTrace.GameObject.IsValid() )
continue;
private Component TryGetLookedAt()
{
for (float num = 0f; num <= 4f; num += 2f)
{
var from = Scene.Camera.WorldPosition + Scene.Camera.WorldRotation.Forward;
var to = from + Scene.Camera.WorldRotation.Forward * (InteractDistance - num);
var trace = Scene.Trace.Ray(from, to).IgnoreGameObjectHierarchy(GameObject).Radius(num).Run();
Component foundComponent = null;
TracedHitPos = trace.Hit ? trace.HitPosition : trace.EndPosition;
CameraTraceIsHit = trace.Hit;
TracedHitNormal = trace.Normal;
ISceneEvent<PlayerController.IEvents>.PostToGameObject( GameObject, x =>
{
foundComponent = x.GetUsableComponent( eyeTrace.GameObject ) ?? foundComponent;
} );
if (!trace.Hit || !trace.GameObject.IsValid()) continue;
if ( foundComponent.IsValid() )
return foundComponent;
Component foundComponent = null;
foreach ( var component in eyeTrace.GameObject.Components.GetAll<IPressable>() )
{
if ( component.CanPress( new IPressable.Event
{
Ray = new Ray( Camera.WorldPosition, EyeAngles.ToRotation().Forward ),
Source = this
} ) )
{
return component as Component;
}
}
}
ISceneEvent<PlayerController.IEvents>.PostToGameObject(GameObject, x =>
{
foundComponent = x.GetUsableComponent(trace.GameObject) ?? foundComponent;
});
return null;
}
if (foundComponent.IsValid()) return foundComponent;
public void StopPressing()
{
if ( Pressed.IsValid() )
{
ISceneEvent<PlayerController.IEvents>.PostToGameObject( GameObject, x => x.StopPressing( Pressed ) );
foreach (var component in trace.GameObject.Components.GetAll<IPressable>())
{
if (component.CanPress(new IPressable.Event
{
Ray = new Ray(Camera.WorldPosition, EyeAngles.ToRotation().Forward),
Source = this
}))
{
return component as Component;
}
}
}
if ( Pressed is IPressable pressable )
{
pressable.Release( new IPressable.Event
{
Ray = new Ray( Camera.WorldPosition, EyeAngles.ToRotation().Forward ),
Source = this
} );
}
return null;
}
Pressed = null;
}
private float GetDistanceFromGameObject(GameObject obj, Vector3 point)
{
Vector3 closest = obj.WorldPosition;
float minDist = Vector3.DistanceBetween(closest, point);
isHolding = false;
triggered = false;
ClearInteractionUI();
}
foreach (var col in Pressed.GetComponentsInChildren<Collider>())
{
Vector3 cp = col.FindClosestPoint(point);
float dist = Vector3.DistanceBetween(cp, point);
if (dist < minDist)
minDist = dist;
}
private void SwitchHovered( Component obj )
{
var e = new IPressable.Event
{
Ray = new Ray( Camera.WorldPosition, EyeAngles.ToRotation().Forward ),
Source = this
};
if ( Hovered == obj )
{
if ( Hovered is IPressable pressable )
{
pressable.Look( e );
}
return;
}
if ( Hovered is IPressable pressable2 )
{
pressable2.Blur( e );
Hovered = null;
}
Hovered = obj;
if ( Hovered is IPressable pressable3 )
{
pressable3.Hover( e );
pressable3.Look( e );
}
}
private float GetDistanceFromGameObject( GameObject obj, Vector3 point )
{
var a = obj.WorldPosition;
var b = Camera.WorldPosition;
float minDist = Vector3.DistanceBetween( a, b );
foreach ( var collider in Pressed.GetComponentsInChildren<Collider>() )
{
var closest = collider.FindClosestPoint( Camera.WorldPosition );
var dist = Vector3.DistanceBetween( closest, Camera.WorldPosition );
if ( dist < minDist )
{
minDist = dist;
}
}
return minDist;
}
private void ShowInteractionUI( Vector3 position, string text, bool showProgress = false, float progress = 0f )
{
if ( interactionPanelPrefab == null )
{
interactionPanelPrefab = GameObject.GetPrefab( InteractionPrefabPath );
if ( interactionPanelPrefab == null ) return;
}
if ( !interactionPanel.IsValid() )
{
interactionPanel = interactionPanelPrefab.Clone( GameObject.Scene );
}
interactionPanel.Transform.Position = position;
interactionPanel.Transform.Rotation = Rotation.LookAt( Camera.WorldPosition - position );
var panel = interactionPanel.GetComponent<PanelComponent>()?.GetPanel();
if ( panel is not null )
{
panel.SetProperty( "InteractionString", text );
panel.SetProperty( "IsHoldInteraction", showProgress );
panel.SetProperty( "ProgressionHold", progress );
}
}
private void ClearInteractionUI()
{
if ( interactionPanel.IsValid() )
{
interactionPanel.Destroy();
interactionPanel = null;
}
}
return minDist;
}
}

View File

@@ -7,9 +7,10 @@ public sealed partial class Dedugan : Component
{
[RequireComponent] public ShrimpleCharacterController.ShrimpleCharacterController Controller { get; set; }
[RequireComponent] public CitizenAnimationHelper AnimationHelper { get; set; }
// [Property] public SkinnedModelRenderer Anim {get; set;}
public SkinnedModelRenderer Renderer { get; set; }
public GameObject Camera { get; set; }
[Property] public GameObject Camera { get; set; }
[Property] public GameObject CameraPivot { get; set; }
[Property][Range(1f, 200f, 1f)] public float CamOffsetX { get; set; }
@@ -22,7 +23,7 @@ public sealed partial class Dedugan : Component
[Sync] public Angles NetworkedEyeAngles { get; set; }
public Angles EyeAngles { get; set; }
[Sync] private float IsDucking { get; set; } = 0f;
[Sync] public bool IsDancing { get; set; } = false;
private RagdollController RagdollController { get; set; }
public Vector3 OverrideGravity { get; set; } = Vector3.Zero;
@@ -38,13 +39,11 @@ public sealed partial class Dedugan : Component
RagdollController = Components.Get<RagdollController>();
Renderer = Components.Get<SkinnedModelRenderer>(FindMode.EverythingInSelfAndDescendants);
var cameraComponent = Camera.GetComponent<CameraComponent>();
cameraComponent.Enabled = false;
if (!Network.IsOwner) return;
var cameraComponent = Scene.Camera;
Camera = cameraComponent.GameObject;
Camera.SetParent(GameObject);
cameraComponent.ZFar = 32768f;
cameraComponent.FieldOfView = 100f;
cameraComponent.Enabled = true;
}
protected override void OnUpdate()
@@ -53,6 +52,7 @@ public sealed partial class Dedugan : Component
{
EyeAngles += Input.AnalogLook;
EyeAngles = EyeAngles.WithPitch(MathX.Clamp(EyeAngles.pitch, -89f, 89f));
NetworkedEyeAngles = EyeAngles;
var targetRotation = Rotation.LookAt(Rotation.FromYaw(EyeAngles.yaw).Forward, -_directionToAxis);
var currentForward = Renderer.LocalRotation.Forward;
@@ -60,19 +60,39 @@ public sealed partial class Dedugan : Component
if (angleDiff > 15f && Controller.Velocity.Length > 10f)
{
NetworkedEyeAngles = EyeAngles;
Renderer.LocalRotation = Rotation.Slerp(Renderer.LocalRotation, Rotation.FromYaw(EyeAngles.yaw), Time.Delta * 3f);
}
RotateCamera();
UpdateLookAt();
// UpdatePressed();
InteractionsUpdate();
}
else
{
EyeAngles = NetworkedEyeAngles;
Renderer.LocalRotation = Rotation.Slerp(Renderer.LocalRotation, Rotation.FromYaw(EyeAngles.yaw), Time.Delta * 5f);
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);
}
// Renderer.LocalRotation = Rotation.Slerp(Renderer.LocalRotation, Rotation.FromYaw(EyeAngles.yaw), Time.Delta * 5f);
Camera.LocalRotation = EyeAngles.ToRotation();
var pivotOffset = CameraPivot.LocalRotation.Backward * CamOffsetX;
var localPitchOffset = Camera.LocalRotation.Down * MathF.Max( 0f, EyeAngles.pitch ) * 0.32f +
Camera.LocalRotation.Backward * MathF.Max( 0f, EyeAngles.pitch ) * 0.7f +
Camera.LocalRotation.Up * MathF.Min( 0f, EyeAngles.pitch ) * 0.5f +
Camera.LocalRotation.Backward * MathF.Min( 0f, EyeAngles.pitch ) * 0.8f;
var offset = (CameraPivot.LocalPosition + pivotOffset ) * EyeAngles.ToRotation() + localPitchOffset;
Camera.LocalPosition = offset;
}
UpdateCustomAnimations();
}
protected override void OnFixedUpdate()