diff --git a/VRCTrailFX.Prefab b/VRCTrailFX.Prefab deleted file mode 100644 index a126739..0000000 --- a/VRCTrailFX.Prefab +++ /dev/null @@ -1,520 +0,0 @@ -using System; -using UnityEngine; -using VRC.SDK3.Avatars.Components; -using VRC.SDK3.Avatars.ScriptableObjects; - -public class VRCTrailFX : MonoBehaviour -{ - [SerializeField] private VRCTrailFXSettings settings; - [SerializeField] private VRCExpressionParameters expressionParameters; - [SerializeField] private VRCAvatarDescriptor avatarDescriptor; - - private Animator animator; - private AudioSource audioSource; - private float[] fftSpectrum; - - private void Start() - { - try - { - SetupComponents(); - SetupAudio(); - SetupFFTSpectrum(); - RunSelfDiagnostics(); - } - catch (Exception ex) - { - LogError($"Failed to setup VRCTrailFX: {ex.Message}"); - enabled = false; - } - } - - private void SetupComponents() - { - animator = GetComponentInParent(); - if (animator == null) - { - throw new InvalidOperationException("Animator component not found on the avatar."); - } - - if (expressionParameters == null) - { - throw new InvalidOperationException("VRCExpressionParameters is not assigned."); - } - - if (avatarDescriptor == null) - { - throw new InvalidOperationException("VRCAvatarDescriptor is not assigned."); - } - - foreach (string boneName in settings.boneNames) - { - SetupLineRenderer(boneName); - } - } - - private void SetupLineRenderer(string boneName) - { - try - { - LineRenderer lineRenderer = Instantiate(settings.lineRendererPrefab); - Transform boneTransform = animator.GetBoneTransform(HumanBodyBones.Hips)?.Find(boneName); - - if (boneTransform != null) - { - lineRenderer.transform.SetParent(boneTransform, false); - lineRenderer.transform.localPosition = Vector3.zero; - lineRenderer.transform.localRotation = Quaternion.identity; - - // Apply lighting settings for Poiyomi/lilToon shaders - ApplyLightingSettings(lineRenderer); - } - else - { - LogWarning($"Bone '{boneName}' not found. Skipping LineRenderer setup."); - Destroy(lineRenderer.gameObject); - } - } - catch (Exception ex) - { - LogError($"Failed to setup LineRenderer for bone '{boneName}': {ex.Message}"); - } - } - - private void ApplyLightingSettings(LineRenderer lineRenderer) - { - try - { - Shader shader = Shader.Find("Poiyomi/Toon") ?? Shader.Find("lilToon"); - if (shader != null) - { - lineRenderer.material.shader = shader; - lineRenderer.material.SetFloat("_ShadowReceive", 1f); - lineRenderer.material.SetFloat("_ShadowStrength", 0.5f); - lineRenderer.material.SetFloat("_LightColorAttenuation", 0.8f); - lineRenderer.material.SetFloat("_IndirectLightIntensity", 0.8f); - } - else - { - LogWarning("Poiyomi/lilToon shader not found. Using default shader."); - } - } - catch (Exception ex) - { - LogError($"Failed to apply lighting settings: {ex.Message}"); - } - } - - private void SetupAudio() - { - try - { - audioSource = gameObject.AddComponent(); - audioSource.clip = settings.trailSound; - audioSource.loop = true; - audioSource.playOnAwake = false; - audioSource.spatialBlend = 1f; - } - catch (Exception ex) - { - LogError($"Failed to setup audio: {ex.Message}"); - } - } - - private void SetupFFTSpectrum() - { - try - { - fftSpectrum = new float[settings.fftSize]; - } - catch (Exception ex) - { - LogError($"Failed to setup FFT spectrum: {ex.Message}"); - } - } - - private void RunSelfDiagnostics() - { - if (settings == null) - { - throw new InvalidOperationException("VRCTrailFXSettings is not assigned."); - } - - if (settings.lineRendererPrefab == null) - { - throw new InvalidOperationException("LineRenderer prefab is not assigned in VRCTrailFXSettings."); - } - - if (settings.trailSound == null) - { - LogWarning("Trail sound is not assigned in VRCTrailFXSettings."); - } - - if (expressionParameters == null) - { - LogWarning("VRCExpressionParameters is not assigned. Dynamic color changes will not work."); - } - - if (avatarDescriptor == null) - { - LogWarning("VRCAvatarDescriptor is not assigned. Avatar-specific settings will not work."); - } - } - - private void Update() - { - if (!enabled) - { - return; - } - - try - { - UpdateTrails(); - UpdateAudio(); - ProcessAudioSpectrum(); - } - catch (Exception ex) - { - LogError($"An error occurred during VRCTrailFX update: {ex.Message}"); - } - } - - private void UpdateTrails() - { - try - { - foreach (string boneName in settings.boneNames) - { - UpdateTrail(boneName); - } - - if (UnityEngine.Random.value < 0.01f) - { - UpdateTrailParameters(); - } - } - catch (Exception ex) - { - LogError($"Failed to update trails: {ex.Message}"); - } - } - - private void UpdateTrail(string boneName) - { - try - { - LineRenderer lineRenderer = GetLineRendererForBone(boneName); - if (lineRenderer == null) - { - return; - } - - Vector3 bonePosition = GetBonePosition(boneName); - int maxPoints = CalculateMaxTrailPoints(); - UpdateLineRendererPositions(lineRenderer, bonePosition, maxPoints); - } - catch (Exception ex) - { - LogError($"Failed to update trail for bone '{boneName}': {ex.Message}"); - } - } - - private LineRenderer GetLineRendererForBone(string boneName) - { - try - { - Transform boneTransform = animator.GetBoneTransform(HumanBodyBones.Hips)?.Find(boneName); - return boneTransform != null ? boneTransform.GetComponentInChildren() : null; - } - catch (Exception ex) - { - LogError($"Failed to get LineRenderer for bone '{boneName}': {ex.Message}"); - return null; - } - } - - private Vector3 GetBonePosition(string boneName) - { - try - { - Transform boneTransform = animator.GetBoneTransform(HumanBodyBones.Hips)?.Find(boneName); - return boneTransform != null ? boneTransform.position : Vector3.zero; - } - catch (Exception ex) - { - LogError($"Failed to get bone position for '{boneName}': {ex.Message}"); - return Vector3.zero; - } - } - - private int CalculateMaxTrailPoints() - { - try - { - float trailDuration = Mathf.Lerp(settings.minTrailDuration, settings.maxTrailDuration, Mathf.PerlinNoise(Time.time * 0.1f, 0f)); - return Mathf.CeilToInt(trailDuration * settings.trailDurationMultiplier * 60f); - } - catch (Exception ex) - { - LogError($"Failed to calculate max trail points: {ex.Message}"); - return 0; - } - } - - private void UpdateLineRendererPositions(LineRenderer lineRenderer, Vector3 bonePosition, int maxPoints) - { - try - { - lineRenderer.positionCount = Mathf.Min(lineRenderer.positionCount + 1, maxPoints); - lineRenderer.SetPosition(lineRenderer.positionCount - 1, bonePosition); - - if (lineRenderer.positionCount >= maxPoints) - { - for (int i = 0; i < lineRenderer.positionCount - 1; i++) - { - lineRenderer.SetPosition(i, lineRenderer.GetPosition(i + 1)); - } - lineRenderer.positionCount--; - } - } - catch (Exception ex) - { - LogError($"Failed to update LineRenderer positions: {ex.Message}"); - } - } - - private void UpdateTrailParameters() - { - try - { - float trailWidth = Mathf.Lerp(settings.minTrailWidth, settings.maxTrailWidth, Mathf.PerlinNoise(Time.time * 0.1f, 0f)); - - foreach (string boneName in settings.boneNames) - { - LineRenderer lineRenderer = GetLineRendererForBone(boneName); - if (lineRenderer != null) - { - lineRenderer.startWidth = trailWidth * settings.trailWidthMultiplier; - lineRenderer.endWidth = trailWidth * settings.trailWidthMultiplier; - lineRenderer.colorGradient = GetCurrentColorGradient(); - } - } - - settings.fftSize = Mathf.RoundToInt(settings.fftSize * settings.fftSizeMultiplier); - if (fftSpectrum == null || fftSpectrum.Length != settings.fftSize) - { - fftSpectrum = new float[settings.fftSize]; - } - } - catch (Exception ex) - { - LogError($"Failed to update trail parameters: {ex.Message}"); - } - } - - private Gradient GetCurrentColorGradient() - { - try - { - Gradient gradient = new Gradient(); - gradient.SetKeys(settings.defaultTrailColorGradient.colorKeys, settings.defaultTrailColorGradient.alphaKeys); - - if (expressionParameters != null) - { - float hueOffset = GetExpressionParameterValue("VRCTrailFXHueOffset"); - float colorVariation = GetExpressionParameterValue("VRCTrailFXColorVariation"); - float hue = (hueOffset + UnityEngine.Random.Range(-colorVariation, colorVariation)) % 1f; - Color color = Color.HSVToRGB(hue, 1f, 1f); - - GradientColorKey[] colorKeys = { new GradientColorKey(color, 0f), new GradientColorKey(color, 1f) }; - gradient.SetKeys(colorKeys, gradient.alphaKeys); - } - - return gradient; - } - catch (Exception ex) - { - LogError($"Failed to get current color gradient: {ex.Message}"); - return settings.defaultTrailColorGradient; - } - } - - private void UpdateAudio() - { - try - { - if (audioSource != null && settings.trailSound != null) - { - if (!audioSource.isPlaying) - { - audioSource.Play(); - } - - float armVelocity = CalculateArmVelocity(); - float normalizedVelocity = NormalizeVelocity(armVelocity); - float pitch = Mathf.Lerp(settings.minPitch, settings.maxPitch, normalizedVelocity); - audioSource.pitch = pitch; - } - } - catch (Exception ex) - { - LogError($"Failed to update audio: {ex.Message}"); - } - } - - private float CalculateArmVelocity() - { - try - { - Vector3 rightHand = GetBonePosition("RightHand"); - Vector3 rightLowerArm = GetBonePosition("RightLowerArm"); - return Vector3.Distance(rightHand, rightLowerArm); - } - catch (Exception ex) - { - LogError($"Failed to calculate arm velocity: {ex.Message}"); - return 0f; - } - } - - private float NormalizeVelocity(float velocity) - { - try - { - return Mathf.Clamp01(velocity / 5f); - } - catch (Exception ex) - { - LogError($"Failed to normalize velocity: {ex.Message}"); - return 0f; - } - } - - private void ProcessAudioSpectrum() - { - try - { - if (audioSource != null && settings.trailSound != null) - { - audioSource.GetSpectrumData(fftSpectrum, 0, FFTWindow.Blackman); - float normalizedSpectrum = CalculateNormalizedSpectrum(); - - if (normalizedSpectrum > settings.noiseThreshold) - { - float hue = Mathf.Lerp(0f, 1f, normalizedSpectrum); - SetExpressionParameterValue("VRCTrailFXHueOffset", hue); - - float colorVariation = Mathf.Lerp(0f, 1f, Mathf.PerlinNoise(Time.time * 0.1f, normalizedSpectrum)); - SetExpressionParameterValue("VRCTrailFXColorVariation", colorVariation); - } - } - } - catch (Exception ex) - { - LogError($"Failed to process audio spectrum: {ex.Message}"); - } - } - - private float CalculateNormalizedSpectrum() - { - try - { - if (fftSpectrum == null || fftSpectrum.Length == 0) - { - return 0f; - } - - float sum = 0f; - for (int i = 0; i < fftSpectrum.Length; i++) - { - sum += fftSpectrum[i]; - } - return sum / fftSpectrum.Length; - } - catch (Exception ex) - { - LogError($"Failed to calculate normalized spectrum: {ex.Message}"); - return 0f; - } - } - - private float GetExpressionParameterValue(string parameterName) - { - try - { - if (expressionParameters == null) - { - return 0f; - } - - VRCExpressionParameters.Parameter parameter = expressionParameters.FindParameter(parameterName); - return parameter != null ? parameter.defaultValue : 0f; - } - catch (Exception ex) - { - LogError($"Failed to get expression parameter value for '{parameterName}': {ex.Message}"); - return 0f; - } - } - - private void SetExpressionParameterValue(string parameterName, float value) - { - try - { - if (expressionParameters == null) - { - return; - } - - VRCExpressionParameters.Parameter parameter = expressionParameters.FindParameter(parameterName); - if (parameter != null) - { - parameter.defaultValue = Mathf.Clamp01(value); - } - } -Copy - - -Claude does not have the ability to run the code it generates yet. -B -続けて必要なことはすべて書きだせ - -catch (Exception ex) -{ -LogError($"Failed to set expression parameter value for '{parameterName}': {ex.Message}"); -} -} - - -Copy code -private void LogError(string message) -{ - Debug.LogError($"[VRCTrailFX] {message}"); -} - -private void LogWarning(string message) -{ - Debug.LogWarning($"[VRCTrailFX] {message}"); -} -} - -[CreateAssetMenu(fileName = "VRCTrailFXSettings", menuName = "VRCTrailFX/Settings", order = 1)] -public class VRCTrailFXSettings : ScriptableObject -{ -public LineRenderer lineRendererPrefab; -public float minTrailDuration = 0.3f; -public float maxTrailDuration = 0.7f; -public float minTrailWidth = 0.005f; -public float maxTrailWidth = 0.015f; -public Gradient defaultTrailColorGradient; -public AudioClip trailSound; -public float minPitch = 0.8f; -public float maxPitch = 1.2f; -public int fftSize = 256; -public float noiseThreshold = 0.1f; -public float trailDurationMultiplier = 1f; -public float trailWidthMultiplier = 1f; -public float fftSizeMultiplier = 1f; -public string[] boneNames; -} \ No newline at end of file