Help with Snake like movement algorithm.

Hi all!

i’m trying to create snake like movement that act more like cars convoy then a snake.
below the code i came with. it works well as snake but i can’t figure out how to keep distance between body parts and keep the movement smooth (like car movement):

this part create a “hidden” snake and take care of controlling it.

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

public class MovementController : MonoBehaviour {

	public int ConvoyLength=3;
	public GameObject HeadObj;
	public GameObject SpacerObj;
	public GameObject temp;
	public static List<Member> Convoy = new List<Member>();
	private Vector3 pos;
	private float Speed = 10f;
	private float xDir;
	private float zDir;

	private int direction=4;
	private float timer;
	public float deltaTimer=1f;

	// Use this for initialization
	void Start () {
		xDir=Speed;
		HeadObj= Resources.Load ("Prefabs/test/Body") as GameObject;
		SpacerObj= Resources.Load ("Prefabs/test/Spacer") as GameObject;

		//Convoy.Add (HeadObj);
		if(ConvoyLength>1){
			Debug.Log ("adding more body");
			AddConvoyMembers();
		}
		pos= new Vector3(0f,0f,0f);
	

	
	}
	
	// Update is called once per frame
	void Update () {
		timer+=Time.deltaTime;
		//Convoy[0].transform.position=pos;
		if(Input.GetKey(KeyCode.UpArrow) ){
			xDir= 0f;
			zDir=Speed;
			direction= 1;
		}
		if(Input.GetKey(KeyCode.DownArrow) ){
			xDir= 0f;
			zDir= -Speed;
			direction=3;
		}
		if(Input.GetKey(KeyCode.LeftArrow) ){
			xDir= -Speed;
			zDir= 0f;
			direction=2;
		}
		if(Input.GetKey(KeyCode.RightArrow) ){
			xDir= Speed;
			zDir= 0f;
			direction=4;
		}
//		if(Input.GetKeyDown(KeyCode.Space) ){
//			ConvoyLength+=1;
//			Convoy.Add (BodyObj);
//			Convoy[ConvoyLength]= Instantiate (BodyObj,pos,Quaternion.identity) as GameObject;		
//		}


		//Convoy[0].posX = Convoy[0].posX + xDir* Time.deltaTime;
		//Convoy[0].posZ = Convoy[0].posZ + zDir* Time.deltaTime;
		if(timer > deltaTimer){
			Convoy[0].posX = Convoy[0].posX + xDir* Time.deltaTime;
			Convoy[0].posZ = Convoy[0].posZ + zDir* Time.deltaTime;
			Convoy[0].Dir = direction;
			MoveConvoy();	
			timer-=deltaTimer;
		}
	}

	void AddConvoyMembers(){
		float tempPos=0;
		Vector3 tempPos2 = new Vector3(tempPos,0f,0f);
		for(int i=0;i<ConvoyLength;i++ ){
			Convoy.Add (new Member());
		}


		temp = Instantiate (SpacerObj,tempPos2,Quaternion.identity) as GameObject;
		temp.tag="0";
		for(int i=1;i<ConvoyLength;i++ ){
			Convoy *= new Member();*

_ //Convoy*.posX = tempPos;_
_
if(i%2==0){temp = Instantiate (HeadObj,tempPos2,Quaternion.identity) as GameObject;_
_
temp.tag=i.ToString ();_
_
}_
_
}_
_
}_
_
void MoveConvoy(){_
_
for(int index=ConvoyLength-1;index>0;index–){*_

* Convoy[index].posX = Convoy[index-1].posX;*
* Convoy[index].posZ = Convoy[index-1].posZ;*
* Convoy[index].Dir = Convoy[index-1].Dir;*

* }*

* }*
then i have this code for the body parts, the idea that when i spawn new part with specific tag number it snap to it place on the hidden snake. it also make sure it rotate nicely to the current direction.
using UnityEngine;
using System.Collections;

public class MemberController : MonoBehaviour {
* private int TagNumber;*
* private GameObject nextMember;*
* private Vector3 pos;*
* public float TurnSpeed;*
* // Use this for initialization*
* void Start () {*
* TagNumber= int.Parse(this.tag);*
* //this.transform.position=MovementController.Convoy[TagNumber].transform.position;*
* }*

* // Update is called once per frame*
* void Update () {*
* pos= new Vector3(MovementController.Convoy[TagNumber].posX,0f,MovementController.Convoy[TagNumber].posZ);*
_ this.transform.position= Vector3.Lerp (this.transform.position,pos,TurnSpeed* Time.deltaTime) ;
* //this.transform.position= pos;*
* if(MovementController.Convoy[TagNumber].Dir==2){*
* Quaternion target = Quaternion.Euler(0, 180f, 0f);*
transform.rotation = Quaternion.Slerp(transform.rotation, target, TurnSpeed * Time.deltaTime);
* }*
* if(MovementController.Convoy[TagNumber].Dir==4){*
* Quaternion target = Quaternion.Euler(0, 0f, 0f);*
transform.rotation = Quaternion.Slerp(transform.rotation, target, TurnSpeed *Time.deltaTime);_

* }*
* if(MovementController.Convoy[TagNumber].Dir==1){*
* Quaternion target = Quaternion.Euler(0, -90f, 0f);*
_ transform.rotation = Quaternion.Slerp(transform.rotation, target, TurnSpeed *Time.deltaTime);_

* }*
* if(MovementController.Convoy[TagNumber].Dir==3){*
* Quaternion target = Quaternion.Euler(0, 90f, 0f);*
_ transform.rotation = Quaternion.Slerp(transform.rotation, target, TurnSpeed *Time.deltaTime);_

* }*
* //this.transform.position=MovementController.Convoy[TagNumber].transform.position;*
* }*
}
and this public class for the body hidden parts:
public class Member{
* public float posX{ get; set;}*
* public float posZ{ get; set;}*
* public int Dir{ get; set;}*
}
that’s it. not very complected. in the main script i have the variable “Speed” if i set it to high number i do get gaps between parts but the snake moves too fast for my needs.
i tried to implement timing to slow it down but then it create jumpy movement.
i’m open to your suggestions…
thanks!!

while waiting for answer i kept digging and find this link:

with some changes and tweaks it appear to be a much better solution then my.
with this i can control the gaps, the body follow nicely and i even made nice rotation for each body part…