Here's the script for the player's head :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class playerScript : MonoBehaviour
{
public bool isMoving;
private Vector3 originPos, targetPos;
public Vector3 lastDirection;
public float moveTime = 0.15f;
private float elapsedTime;
public const float Vel = 9f;
public List<Vector3> positionHistory = new List<Vector3>();
public List<snakeBodyScript> bodySegments = new List<snakeBodyScript>();
public List<Vector3> directionHistory = new List<Vector3>();
public int moveCount;
public GameObject bodyPrefab;
void Update()
{
Move();
SetBodyTarget();
if (Input.GetKeyDown(KeyCode.Space))
{
Grow();
}
}
private void Move()
{
if (isMoving) return;
if (Input.GetKey(KeyCode.W))
{
lastDirection = Vector3.up;
StartCoroutine(MovePlayer(lastDirection));
transform.rotation = Quaternion.Euler(0f, 0f, 0f);
}
else if (Input.GetKey(KeyCode.S))
{
lastDirection = Vector3.down;
StartCoroutine(MovePlayer(lastDirection));
transform.rotation = Quaternion.Euler(0f, 0f, 180f);
}
else if (Input.GetKey(KeyCode.A))
{
lastDirection = Vector3.left;
StartCoroutine(MovePlayer(lastDirection));
transform.rotation = Quaternion.Euler(0f, 0f, 90f);
}
else if (Input.GetKey(KeyCode.D))
{
lastDirection = Vector3.right;
StartCoroutine(MovePlayer(lastDirection));
transform.rotation = Quaternion.Euler(0f, 0f, -90f);
}
}
private IEnumerator MovePlayer(Vector3 direction)
{
isMoving = true;
originPos = transform.position;
targetPos = originPos + direction;
directionHistory.Add(direction);
elapsedTime = 0f;
while (elapsedTime < moveTime)
{
transform.position = Vector3.Lerp(originPos, targetPos, elapsedTime / moveTime);
elapsedTime += Time.deltaTime;
yield return null;
}
transform.position = targetPos;
isMoving = false;
}
private void SetBodyTarget()
{
if (bodySegments.Count > 0)
{
bodySegments[0].GetComponent<snakeBodyScript>().SetTargetPosition(transform.position);
for (int index = bodySegments.Count - 1; index > 0; index --)
{
bodySegments[index].GetComponent<snakeBodyScript>().SetTargetPosition(bodySegments[index - 1].transform.position);
}
}
}
public void Grow()
{
if (positionHistory.Count == 0)
{
for (int i = 0; i < 3; i++)
positionHistory.Add(transform.position);
}
Vector3 spawnPos = positionHistory[positionHistory.Count - 1];
GameObject bodyPart = Instantiate(bodyPrefab, spawnPos, Quaternion.identity);
snakeBodyScript bodyScript = bodyPart.GetComponent<snakeBodyScript>();
bodyScript.player = this;
bodySegments.Add(bodyScript);
}
}
Here's the script for the body/tail :
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class snakeBodyScript : MonoBehaviour
{
public playerScript player;
private Vector3 nextBodyPos;
private int waitPreviousParts;
private int itemCount = 0;
private void Start()
{
}
private void Update()
{
if (player.bodySegments.Count > 0)
{
foreach (snakeBodyScript i in player.bodySegments)
{
if (player.bodySegments.Count == itemCount)
{
itemCount = -1;
}
itemCount += 1;
foreach (Vector3 v in player.directionHistory)
{
player.bodySegments[itemCount].transform.position = Vector3.Lerp(transform.position, v, playerScript.Vel);
}
}
}
}
public void WaitHeadUpdateCycle(int value)
{
waitPreviousParts = value;
}
public void SetTargetPosition(Vector3 targetPosition)
{
if (waitPreviousParts > 0)
{
waitPreviousParts--;
return;
}
nextBodyPos = targetPosition;
}
}