гигантский ассет

This commit is contained in:
2026-03-03 05:27:03 +05:00
parent d49d929924
commit c432aa9263
5899 changed files with 9806933 additions and 230 deletions

View File

@@ -0,0 +1,127 @@
using UnityEngine;
using UHFPS.Tools;
using Newtonsoft.Json.Linq;
using UnityEngine.Events;
namespace UHFPS.Runtime
{
[RequireComponent(typeof(Rigidbody), typeof(AudioSource))]
public class DraggableItem : SaveableBehaviour, IOnDragStart, IOnDragEnd
{
[Tooltip("Minimum and maximum distance to which the object can be zoomed.")]
public MinMax ZoomDistance;
[Tooltip("Maximum hold distance at which the object will be out of range and will be dropped.")]
public float MaxHoldDistance = 4f;
public bool EnableImpactSound = true;
[Tooltip("Array of the impact sounds.")]
public AudioClip[] ImpactSounds;
[Tooltip("Minimum and maximum impact volume. The impact will be played if the calculated volume is greater than the minimum impact volume.")]
public MinMax ImpactVolume;
[Tooltip("Modifier that is multiplied with the impact volume. Higher value = louder impact volume")]
public float VolumeModifier;
[Tooltip("Time at which the next impact will be detected.")]
public float NextImpact = 0.1f;
public bool EnableSlidingSound = true;
[Tooltip("Minimum angle between the collision and the motion at which the sliding is detected. Near 0 = sliding, More than 0 = static")]
public float MinSlidingFactor = 5f;
[Tooltip("Velocity range at which the sliding volume is calculated. Higher value = faster movement is required to achieve volume 1")]
public float SlidingVelocityRange = 5f;
[Tooltip("Modifier that is multiplied with the sliding volume. Higher value = louder sliding volume")]
public float SlidingVolumeModifier = 5f;
[Tooltip("Speed at which the volume is faded when the sliding stops.")]
public float VolumeFadeOffSpeed = 5f;
public UnityEvent OnDragStarted;
public UnityEvent OnDragEnded;
public bool Collision;
private Rigidbody rigid;
private AudioSource audioSource;
private float impactTime;
private int lastImpact;
private void Awake()
{
rigid = GetComponent<Rigidbody>();
audioSource = GetComponent<AudioSource>();
audioSource.volume = 0f;
audioSource.loop = true;
audioSource.spatialBlend = 1f;
audioSource.playOnAwake = false;
}
private void OnCollisionEnter(Collision collision)
{
Collision = true;
if (!EnableImpactSound) return;
float newVolume = collision.relativeVelocity.magnitude / VolumeModifier;
if (newVolume < ImpactVolume.RealMin) return;
newVolume = Mathf.Clamp(newVolume, ImpactVolume.RealMin, ImpactVolume.RealMax);
if (impactTime <= 0) OnObjectImpact(newVolume);
}
private void OnCollisionExit(Collision collision)
{
Collision = false;
}
private void OnCollisionStay(Collision collision)
{
Collision = true;
}
private void Update()
{
if (impactTime > 0) impactTime -= Time.deltaTime;
if (!EnableSlidingSound) return;
float velMagnitude = rigid.linearVelocity.magnitude;
float velMagnitudeNormalized = rigid.linearVelocity.normalized.magnitude;
if (Collision && velMagnitudeNormalized > MinSlidingFactor)
{
float slidingVolume = Mathf.InverseLerp(0f, SlidingVelocityRange, velMagnitude);
if (!audioSource.isPlaying) audioSource.Play();
audioSource.volume = Mathf.Clamp01(slidingVolume * SlidingVolumeModifier);
}
else
{
audioSource.volume = Mathf.MoveTowards(audioSource.volume, 0f, Time.deltaTime * VolumeFadeOffSpeed);
if (audioSource.isPlaying && audioSource.volume <= 0) audioSource.Stop();
}
}
private void OnObjectImpact(float volume)
{
lastImpact = GameTools.RandomUnique(0, ImpactSounds.Length, lastImpact);
AudioClip audioClip = ImpactSounds[lastImpact];
AudioSource.PlayClipAtPoint(audioClip, transform.position, volume);
}
public void OnDragStart()
{
OnDragStarted?.Invoke();
}
public void OnDragEnd()
{
OnDragEnded?.Invoke();
}
public override StorableCollection OnSave()
{
return new StorableCollection().WithTransform(transform);
}
public override void OnLoad(JToken data)
{
data.LoadTransform(transform);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d7ef03693823c604f94c979641ed99eb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,196 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using Newtonsoft.Json.Linq;
using UHFPS.Tools;
using ThunderWire.Attributes;
namespace UHFPS.Runtime
{
[Docs("https://docs.twgamesdev.com/uhfps/guides/interactions")]
public class InteractableItem : SaveableBehaviour
{
[Serializable]
public sealed class Hotspot
{
public Transform HotspotTransform;
[Tooltip("If you want the hotspot to be shown, keep this value true.")]
public bool Enabled = true;
[Tooltip("If this option is enabled, the hotspot action will be called when you put back the examined item.")]
public bool ResetHotspot = false;
[Space] public UnityEvent HotspotAction;
}
public enum InteractableTypeEnum { GenericItem, InventoryItem, ExamineItem, InventoryExpand }
public enum MessageTypeEnum { None, Hint, Alert }
public enum ExamineTypeEnum { None, GenericObject, CustomObject }
public enum ExamineRotateEnum { Static, Horizontal, Vertical, Both }
public enum DisableTypeEnum { None, Deactivate, Destroy }
public InteractableTypeEnum InteractableType = InteractableTypeEnum.GenericItem;
public MessageTypeEnum MessageType = MessageTypeEnum.None;
public ExamineTypeEnum ExamineType = ExamineTypeEnum.None;
public ExamineRotateEnum ExamineRotate = ExamineRotateEnum.Static;
public DisableTypeEnum DisableType = DisableTypeEnum.None;
public ItemProperty PickupItem;
public ItemCustomData ItemCustomData;
public GString InteractTitle;
public GString ExamineTitle;
public GString PaperText;
public GString HintMessage;
public float MessageTime = 3f;
public ushort Quantity = 1;
public ushort SlotsToExpand = 1;
public bool ExpandRows;
public bool UseInventoryTitle = true;
public bool ExamineInventoryTitle = true;
public bool ShowExamineTitle = true;
public bool ShowFloatingIcon = false;
public bool TakeFromExamine = false;
public bool AllowCursorExamine = false;
public bool IsPaper = false;
public bool AutoShortcut = false;
public bool UseExamineZooming = true;
public MinMax ExamineZoomLimits = new(0.3f, 0.4f);
public float ExamineDistance = 0.4f;
public bool UseFaceRotation;
public Vector3 FaceRotation;
public bool UseControlPoint;
public Vector3 ControlPoint = new(0, 0.1f, 0);
public List<Collider> CollidersEnable = new();
public List<Collider> CollidersDisable = new();
public Hotspot ExamineHotspot = new();
public SoundClip PickupSound;
public SoundClip ExamineSound;
public SoundClip ExamineHintSound;
public UnityEvent OnTakeEvent;
public UnityEvent OnExamineStartEvent;
public UnityEvent OnExamineEndEvent;
public bool IsExamined;
public bool IsCustomExamine => InteractableType != InteractableTypeEnum.GenericItem && ExamineType == ExamineTypeEnum.CustomObject;
/// <summary>
/// Name of the item.
/// </summary>
public string ItemName
{
get
{
string title = InteractTitle;
if (InteractableType == InteractableTypeEnum.InventoryItem && UseInventoryTitle)
{
title = PickupItem.GetItem().Title;
}
return title;
}
}
private void Awake()
{
if(IsCustomExamine)
{
foreach (var col in CollidersEnable)
{
col.enabled = false;
}
foreach (var col in CollidersDisable)
{
col.enabled = true;
}
}
}
private void Start()
{
if (InteractableType != InteractableTypeEnum.InventoryItem || !UseInventoryTitle)
InteractTitle.SubscribeGloc();
if(ExamineType != ExamineTypeEnum.None)
ExamineTitle.SubscribeGloc();
if(ExamineType != ExamineTypeEnum.None && IsPaper)
PaperText.SubscribeGloc();
if(MessageType == MessageTypeEnum.Hint)
HintMessage.SubscribeGloc();
}
public void OnInteract()
{
if (InteractableType == InteractableTypeEnum.ExamineItem)
return;
GameTools.PlayOneShot2D(transform.position, PickupSound, "PickupSound");
OnTakeEvent?.Invoke();
if (DisableType != DisableTypeEnum.None)
EnabledState(false);
}
/// <summary>
/// Use this method to interact with the object as if you were pressing the USE button on it.
/// </summary>
public void InteractWithObject()
{
if (InteractableType == InteractableTypeEnum.ExamineItem)
return;
PlayerPresenceManager.Instance.PlayerManager.InteractController.Interact(gameObject);
}
public void EnabledState(bool enabled)
{
if (!enabled && SaveGameManager.HasReference)
SaveGameManager.RemoveSaveable(gameObject);
if(DisableType == DisableTypeEnum.Deactivate)
gameObject.SetActive(enabled);
else if(DisableType == DisableTypeEnum.Destroy && !enabled)
Destroy(gameObject);
}
public override StorableCollection OnSave()
{
return new StorableCollection()
{
{ "position", transform.position.ToSaveable() },
{ "rotation", transform.eulerAngles.ToSaveable() },
{ "quantity", Quantity },
{ "enabledState", gameObject.activeSelf },
{ "hotspotEnabled", ExamineHotspot.Enabled },
{ "customData", ItemCustomData.GetJson() }
};
}
public override void OnLoad(JToken data)
{
transform.position = data["position"].ToObject<Vector3>();
transform.eulerAngles = data["rotation"].ToObject<Vector3>();
Quantity = (ushort)data["quantity"];
EnabledState((bool)data["enabledState"]);
ExamineHotspot.Enabled = (bool)data["hotspotEnabled"];
ItemCustomData.JsonData = data["customData"].ToString();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1193cc42578b51349ae91df02822e87c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,132 @@
using System.Collections;
using UnityEngine;
using UHFPS.Input;
using UHFPS.Tools;
namespace UHFPS.Runtime
{
public class MovableObject : MonoBehaviour, IStateInteract
{
public enum MoveDirectionEnum { LeftRight, ForwardBackward, AllDirections }
public AudioSource AudioSource;
public Rigidbody Rigidbody;
public Axis ForwardAxis;
public bool DrawGizmos = true;
public MoveDirectionEnum MoveDirection;
public LayerMask CollisionMask;
public Vector3 HoldOffset;
public bool AllowRotation = true;
public float HoldDistance = 2f;
public float ObjectWeight = 20f;
public float PlayerRadius = 0.3f;
public float PlayerHeight = 1.8f;
public float PlayerFeetOffset = 0f;
public float WalkMultiplier = 1f;
public float LookMultiplier = 1f;
[Range(0f, 1f)]
public float SlideVolume = 1f;
public float VolumeFadeSpeed = 1f;
public bool UseMouseLimits;
public MinMax MouseVerticalLimits;
public Transform RootMovable => Rigidbody.transform;
public MeshRenderer Renderer => RootMovable.GetComponent<MeshRenderer>();
private void Awake()
{
if(Rigidbody != null) Rigidbody.mass = ObjectWeight;
if(AudioSource != null)
{
AudioSource.playOnAwake = false;
AudioSource.spatialBlend = 1f;
AudioSource.loop = true;
AudioSource.Stop();
}
}
public void FadeSoundOut()
{
StartCoroutine(FadeSound());
}
IEnumerator FadeSound()
{
while(Mathf.Approximately(AudioSource.volume, 0f))
{
AudioSource.volume = Mathf.MoveTowards(AudioSource.volume, 0f, Time.deltaTime * SlideVolume * 10);
yield return null;
}
AudioSource.volume = 0f;
AudioSource.Stop();
}
public StateParams OnStateInteract()
{
if (!CheckOverlapping())
{
StopAllCoroutines();
return new StateParams()
{
stateKey = PlayerStateMachine.PUSHING_STATE,
stateData = new StorableCollection()
{
{ "reference", this }
}
};
}
return null;
}
private bool CheckOverlapping()
{
Vector3 forwardGlobal = ForwardAxis.Convert();
float height = PlayerHeight - 0.6f;
Vector3 position = RootMovable.TransformPoint((-forwardGlobal * HoldDistance) + HoldOffset);
Vector3 bottomPos = new(position.x, Renderer.bounds.min.y, position.z);
Vector3 playerBottom = bottomPos;
playerBottom.y += PlayerFeetOffset;
Vector3 p1 = new Vector3(position.x, playerBottom.y, position.z);
Vector3 p2 = new Vector3(position.x, playerBottom.y + height, position.z);
return Physics.CheckCapsule(p1, p2, PlayerRadius, CollisionMask);
}
private void OnDrawGizmosSelected()
{
if (!DrawGizmos)
return;
Vector3 forwardGlobal = ForwardAxis.Convert();
Vector3 forwardLocal = RootMovable.Direction(ForwardAxis);
float radius = 0.5f;
Vector3 position = RootMovable.TransformPoint((-forwardGlobal * HoldDistance) + HoldOffset);
Vector3 bottomPos = new(position.x, Renderer.bounds.min.y, position.z);
GizmosE.DrawDisc(bottomPos, radius, Color.green, Color.green.Alpha(0.01f));
GizmosE.DrawGizmosArrow(bottomPos, forwardLocal * radius);
float height = PlayerHeight - 0.6f;
Vector3 playerBottom = bottomPos;
playerBottom.y += PlayerFeetOffset;
Vector3 p1 = new(position.x, playerBottom.y, position.z);
Vector3 p2 = new(position.x, playerBottom.y + height, position.z);
Gizmos.color = Color.green;
GizmosE.DrawWireCapsule(p1, p2, PlayerRadius);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fa8537c177a53574eaed5557887213ce
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: