using UnityEngine; public class RootCrawler : MonoBehaviour { public Transform target; public float maxHeight = 2f; public float crawlingSpeed = 0.4f; public float radius = 0.5f; public float rotationSpeed = 5f; public float noiseStrength = 0.06f; public float noiseFrequency = 1.5f; public int resolution = 80; private float currentHeight = 0f; private float noiseOffset; private LineRenderer line; private float angleOffset = 0f; void Start() { line = GetComponent(); noiseOffset = Random.Range(0f, 100f); } void Update() { if (target == null) return; currentHeight += Time.deltaTime * crawlingSpeed; currentHeight = Mathf.Clamp(currentHeight, 0f, maxHeight); angleOffset += Time.deltaTime * 2f; int currentResolution = Mathf.Max(2, Mathf.RoundToInt((currentHeight / maxHeight) * resolution)); line.positionCount = currentResolution; for (int i = 0; i < currentResolution; i++) { float t = (float)i / (currentResolution - 1); float h = t * currentHeight; float angle = t * rotationSpeed * maxHeight / crawlingSpeed + angleOffset; float r = Mathf.Lerp(radius, radius * 0.5f, t); float noiseX = (Mathf.PerlinNoise(noiseOffset + h * noiseFrequency, 0f) - 0.5f) * noiseStrength; float noiseZ = (Mathf.PerlinNoise(0f, noiseOffset + h * noiseFrequency) - 0.5f) * noiseStrength; float x = Mathf.Cos(angle) * r + noiseX; float z = Mathf.Sin(angle) * r + noiseZ; line.SetPosition(i, target.position + new Vector3(x, h - 0.8f, z)); } float rotationMultiplier = 1f - (currentHeight / maxHeight); angleOffset += Time.deltaTime * 2f * (rotationMultiplier + 0.1f); } }