Snake Like Movement

Hello everyone here,
First time posting in this forum.

So, I am working on a snake like movement, where a number of balls follows the first ball in a line.

I modified a bit a code I found some weeks ago in youtube video, but I can not get the movement, that one ball follows the exact line. I spawn every bodypart via an Integer. Every balls (i) goes to the position of the one in front of him (i-1). This way I get the movement I was hoping for, but not exactly the way I was imagining.
The movement of the balls becomes to fluent and I would like it to be more strict. How can I accomplish this? Any suggestions?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SnakeMovement : MonoBehaviour
{
    public List<Transform> BodyParts = new List<Transform>();

    public float mindistance = 0.25f;
    public float speed = 1;
    public float rotationspeed = 50;

    public int beginSize;

    public GameObject bodyprefab;
    public GameObject mainbody;

    private float dis;
    private Transform curBodyPart;
    private Transform PrevBodypart;

   
    void Start()
    {
        for (int i = 0; i < beginSize - 1; i++) {
            AddBodyPart();
        }
    }

   
    void Update()
    {
        Move();
      
    }

    public void Move()
    {
        float curspeed = speed;
        //BodyParts[0].Translate(this.transform.position * curspeed * Time.smoothDeltaTime, Space.World);

        //for (int i = 1; i< BodyParts.Count; i++) {
        //    curBodyPart = BodyParts[i];
        //    PrevBodypart = BodyParts[i - 1];

        //    dis = Vector3.Distance(PrevBodypart.position, curBodyPart.position);

        //    Vector3 newpos = PrevBodypart.position;
        //    newpos.y = BodyParts[0].position.y;

        //    float T = Time.deltaTime * dis / mindistance * curspeed;

        //    if (T > 0.5f)
        //        T = 0.5f;
        //    curBodyPart.position = Vector3.Slerp(curBodyPart.position, newpos, T);
        //    curBodyPart.rotation = Quaternion.Slerp(curBodyPart.rotation,PrevBodypart.rotation, T);

        //}

        for (int i = 1; i < BodyParts.Count; i++) {
            curBodyPart = BodyParts[i];
            PrevBodypart = BodyParts[i - 1];

            dis = Vector3.Distance(PrevBodypart.position, curBodyPart.position);


            Vector3 newpos = PrevBodypart.position;
            float T = Time.deltaTime * dis / mindistance * curspeed;
            if (T > 0.5f)
            T = 0.5f;
            BodyParts[0].position = Vector3.Slerp(mainbody.transform.position, newpos, T);
            curBodyPart.position = Vector3.Slerp(curBodyPart.position, newpos, T);
            curBodyPart.rotation = Quaternion.Slerp(curBodyPart.rotation, PrevBodypart.rotation, T);
        }


    }

    public void AddBodyPart() {

        Transform newpart = (Instantiate(bodyprefab, BodyParts[BodyParts.Count -1].position, BodyParts[BodyParts.Count - 1].rotation) as GameObject).transform;

        newpart.SetParent(transform);

        BodyParts.Add(newpart);
    }
}

do not parent your parts so just remove the SetParent line it will work

1 Like

I tried it and it still does not look the way I want it. Maybe I can add a GIF later (my recordings are too big, like 8mb or so). For now I try to describe what is happening. While the first ball bounces, the balls near the first ball follow the movement but the last ball is only doing very small movements. And it always floates behind the other balls.

yeah that was the video I looked at some weeks ago. thanks

I tried something else. Maybe you could take a look at the way I try to solve the problem now?

I load all BodyParts of the Snake with an array move the position of every ball to the one in front of him. By storing the positions in an array I hoped to copy the exact movement of a mainbody, that bounces around. While going throught a forloop I iterate through the positions and move the array. When I Lerp the positions it works quite good.

here is the code

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SnakeMovement : MonoBehaviour
{
    public GameObject[] BodyParts;

    private Vector3[] BodyPosition;
    public GameObject BodyPref;
    //private GameObject[] NewPart;
    public int beginSize = 10;

    public float mindistance = 0.25f;

    public float rotationspeed = 50;

    private float T = 0;
    private float speed = 1;
    private Vector3 dis;

    public GameObject bodyprefab;
    public GameObject mainbody;

    public float journeyTime = 1.0f;
    private float startTime;
    public float duration = 5.0f;

    void Awake()
    {
        startTime = Time.time;
        BodyPosition = new Vector3[beginSize];
        BodyParts = new GameObject[beginSize];
        for (int i = 0; i < beginSize; i++) {
            Vector3 position = new Vector3(mindistance * i, 0, 0);
            GameObject  clone = Instantiate(BodyPref, position, Quaternion.identity);
            BodyParts[i] = clone;
        }

    }


    void Update()
    {
        float t = duration;
        for (int i = 1; i < BodyParts.Length; i++)
        {
            BodyParts[0].transform.position = Vector3.Lerp(BodyParts[0].transform.position, mainbody.transform.position, t*Time.deltaTime);
            BodyPosition[i] = mainbody.transform.position;


            BodyParts[i].transform.position = Vector3.Slerp(BodyParts[i - 1].transform.position, BodyParts[i].transform.position, t*Time.deltaTime);
            BodyPosition[i] = BodyPosition[i - 1];//verschieben des Arrays

        }

    }


}