I try to make a game like the classic snake game but on a round ground (Earth). On a plane, the script works well, but when i moved it on a sphere, the bodyparts (prefabs), are not working good as you can see in the picture ( they are going right/left, but they do not sit on the spehre and i tried already to use sphere collider, box collider, rigidbody) and i dont know really how to make it so that they will follow 100% correctly the player. Thanks for help! :/ . Here i put the script for the Player and bodyparts:
using System.Collections;
using System.Collections.Generic;
using UnityEngine; using UnityEngine.UI;
public class PlayerMovementScript : MonoBehaviour {
protected Joystick joystick;
public float speed;
[SerializeField] private float turnFactor;
[SerializeField] private Transform planet;
public List<Transform> bodyParts = new List<Transform>();
public float minDistance = 0.25f;
public int beginSize;
public float rotationSpeed = 50;
public float timeFromLastRetry;
public GameObject bodyprefabs;
public Text currentScore;
public Text scoreText;
public GameObject deadScreen;
private float dis;
private Transform curBodyPart;
private Transform PrevBodyPart;
public bool isAlive;
void Start()
{
joystick = FindObjectOfType<Joystick>();
speed = 3f;
StartLevel();
}
public void StartLevel()
{
timeFromLastRetry = Time.deltaTime;
//deadScreen.SetActive(false);
for (int i = bodyParts.Count -1; i > beginSize; i++)
{
Destroy(bodyParts[i].gameObject);
bodyParts.Remove(bodyParts[i]);
}
bodyParts[0].position = new Vector3(0, 0.5f, 0);
for (int i = 0; i < beginSize - 1; i++)
{
AddBodyPart();
}
bodyParts[0].position = new Vector3(0, 0.5f, 0);
bodyParts[0].rotation = Quaternion.identity;
currentScore.gameObject.SetActive(true);
currentScore.text = "Score: 0";
isAlive = true;
}
void Update()
{
if (isAlive)
Move();
if (Input.GetKey(KeyCode.Q))
AddBodyPart();
//RotateAroundPlanet();
var rb = GetComponent<Rigidbody>();
//rb.velocity = new Vector3(joystick.Horizontal * 100f, rb.velocity.y, joystick.Vertical * 100f);
}
public void Move()
{
float curspeed = speed;
//if (Input.GetKey(KeyCode.W))
// curspeed *= 2;
bodyParts[0].Translate(bodyParts[0].forward * curspeed * Time.smoothDeltaTime, Space.World);
if (Input.GetAxis("Horizontal") != 0)
bodyParts[0].Rotate(Vector3.up * rotationSpeed * Time.deltaTime * Input.GetAxis("Horizontal"));
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);
}
}
public void AddBodyPart()
{
Transform newpart = (Instantiate(bodyprefabs, bodyParts[bodyParts.Count - 1].position,
bodyParts[bodyParts.Count - 1].rotation) as GameObject).transform;
newpart.SetParent(transform);
bodyParts.Add(newpart);
currentScore.text = "Score: " + (bodyParts.Count - beginSize).ToString();
}
public void Die()
{
isAlive = false;
scoreText.text = "Your score was: " + (bodyParts.Count - beginSize).ToString();
currentScore.gameObject.SetActive(false);
deadScreen.SetActive(true);
}
newpos.y = bodyParts[0].position.y;
. That doesn't make sense for the type of 3D movement you're trying to achieve. \$\endgroup\$