using ABI.CCK.Components; using UnityEngine; using UnityEngine.Animations; namespace NAK.AvatarScaleMod; public class AvatarScaleManager : MonoBehaviour { public static AvatarScaleManager LocalAvatar { get; private set; } // List of component types to be collected and scaled private static readonly System.Type[] scaleComponentTypes = new System.Type[] { typeof(Light), typeof(AudioSource), typeof(ParticleSystem), typeof(ParentConstraint), typeof(PositionConstraint), typeof(ScaleConstraint), }; public const float MinimumHeight = 0.25f; public const float MaximumHeight = 2.5f; // Scalable Components private List _lights = new List(); private List _audioSources = new List(); //private List> _particleSystems = new List>(); private List _parentConstraints = new List(); private List _positionConstraints = new List(); private List _scaleConstraints = new List(); public float TargetHeight { get; private set; } public float InitialHeight { get; private set; } public Vector3 InitialScale { get; private set; } public float ScaleFactor { get; private set; } public void Initialize(float initialHeight, Vector3 initialScale) { // Check for zero height if (Math.Abs(initialHeight) < 1E-6) { AvatarScaleMod.Logger.Warning("Cannot initialize with a height of zero!"); return; } this.TargetHeight = 1f; this.InitialHeight = initialHeight; this.InitialScale = initialScale; UpdateScaleFactor(); } public void SetTargetHeight(float newHeight) { TargetHeight = Mathf.Clamp(newHeight, MinimumHeight, MaximumHeight); UpdateScaleFactor(); } public void UpdateScaleFactor() { // Check for zero if (Math.Abs(InitialHeight) < 1E-6) { AvatarScaleMod.Logger.Warning("InitialHeight is zero, cannot calculate ScaleFactor."); return; } this.ScaleFactor = TargetHeight / InitialHeight; } private Vector3 CalculateNewScale() { return InitialScale * ScaleFactor; } private void Awake() { // why am i caching the avatar CVRAvatar avatar = GetComponent(); if (avatar == null) { AvatarScaleMod.Logger.Error("AvatarScaleManager should be attached to a GameObject with a CVRAvatar component."); return; } // i cant believe i would stoop this low if (gameObject.layer == 8 && LocalAvatar == null) LocalAvatar = this; FindComponentsOfType(scaleComponentTypes); } private void OnDestroy() { _audioSources.Clear(); _lights.Clear(); //_particleSystems.Clear(); // fuck no _parentConstraints.Clear(); _positionConstraints.Clear(); _scaleConstraints.Clear(); // local player manager if (LocalAvatar == this) LocalAvatar = null; } private void FindComponentsOfType(params System.Type[] types) { foreach (var type in types) { var components = gameObject.GetComponentsInChildren(type, true); foreach (var component in components) { switch (component) { case AudioSource audioSource: _audioSources.Add(new ScaledAudioSource(audioSource)); break; case Light light: _lights.Add(new ScaledLight(light)); break; case ParentConstraint parentConstraint: _parentConstraints.Add(new ScaledParentConstraint(parentConstraint)); break; case PositionConstraint positionConstraint: _positionConstraints.Add(new ScaledPositionConstraint(positionConstraint)); break; case ScaleConstraint scaleConstraint: _scaleConstraints.Add(new ScaledScaleConstraint(scaleConstraint)); break; } } } } void Update() { ApplyAvatarScaling(); ApplyComponentScaling(); } void LateUpdate() { ApplyAvatarScaling(); ApplyComponentScaling(); } private void ApplyAvatarScaling() { transform.localScale = CalculateNewScale(); } private void ApplyComponentScaling() { UpdateLightScales(); UpdateAudioSourceScales(); UpdateParentConstraintScales(); UpdatePositionConstraintScales(); UpdateScaleConstraintScales(); } private void UpdateLightScales() { foreach (var scaledLight in _lights) { scaledLight.Component.range = scaledLight.InitialRange * ScaleFactor; } } private void UpdateAudioSourceScales() { foreach (var scaledAudioSource in _audioSources) { scaledAudioSource.Component.minDistance = scaledAudioSource.InitialMinDistance * ScaleFactor; scaledAudioSource.Component.maxDistance = scaledAudioSource.InitialMaxDistance * ScaleFactor; } } private void UpdateParentConstraintScales() { foreach (var scaledParentConstraint in _parentConstraints) { scaledParentConstraint.Component.translationAtRest = scaledParentConstraint.InitialTranslationAtRest * ScaleFactor; for (int i = 0; i < scaledParentConstraint.InitialTranslationOffsets.Count; i++) { scaledParentConstraint.Component.translationOffsets[i] = scaledParentConstraint.InitialTranslationOffsets[i] * ScaleFactor; } } } private void UpdatePositionConstraintScales() { foreach (var scaledPositionConstraint in _positionConstraints) { scaledPositionConstraint.Component.translationAtRest = scaledPositionConstraint.InitialTranslationAtRest * ScaleFactor; scaledPositionConstraint.Component.translationOffset = scaledPositionConstraint.InitialTranslationOffset * ScaleFactor; } } private void UpdateScaleConstraintScales() { foreach (var scaledScaleConstraint in _scaleConstraints) { scaledScaleConstraint.Component.scaleAtRest = scaledScaleConstraint.InitialScaleAtRest * ScaleFactor; scaledScaleConstraint.Component.scaleOffset = scaledScaleConstraint.InitialScaleOffset * ScaleFactor; } } }