У меня к Вам довольно массивный вопрос. Я делаю что-то наподобие 3д змейки. Змейка - набор кубиков которые двигаются один за одним. Змейка двигается вперед, а при нажатии 'a' и 'd' - влево и вправо. Проблема в том что я не могу сделать движение кубов тела за кубом головы. Если через MoveTorwards то части тела передвигаются напрямую к голове не проходя весь ее путь. Я пробовал сделать как-то через переменную-вектор LastTurn которая сохраняет последний поворот головы и отдельных частей тела, для головы и первой части тела это работает, но для всех других - нет. Если у Вас есть идеи как реализовать это по-другому или как исправить мой скрипт, то посоветуйте пожалуйста.
Вот код. (Простите за этот говнокод)))
Код головы: (висит на snake)
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class PlayerController : MonoBehaviour
{
public float speed;
public bool testModePC = false; //переменная для теста на пк (игра на андроид)
public Transform player; //голова + камера
public Transform playerHead; //голова
public Transform playerBodyParent; //объект с кубиками тела
private Vector3 beginCooldown; //
private Sides cooldownSide = Sides.zero; //
private bool canIturnLeft; // переменные для кулдауна - чтобы игрок не мог поворачивать слишком часто
private bool canIturnRight; //
private bool canIturnFoward; //
public Vector3 lastTurn; //сохраняет позицию последнего поворота
private void FixedUpdate() {
player.position += playerHead.forward * Time.deltaTime * speed;
CheckCooldown();
if(Input.touchCount == 1){
if(Input.GetTouch(0).position.x <= Screen.width / 2 && canIturnLeft){
if(playerHead.rotation != Quaternion.Euler(0, -90, 0)) {SetCooldown(-90); lastTurn = player.position; transform.parent.GetChild(1).GetChild(0).GetComponent<BodyController>().isIFolow = true;}
playerHead.rotation = Quaternion.Euler(0, -90, 0);
}
else if(Input.GetTouch(0).position.x >= Screen.width / 2 && canIturnRight) {
if(playerHead.rotation != Quaternion.Euler(0, 90, 0)) {SetCooldown(90); lastTurn = player.position; transform.parent.GetChild(1).GetChild(0).GetComponent<BodyController>().isIFolow = true;}
playerHead.rotation = Quaternion.Euler(0, 90, 0);
}
}
else if(testModePC == false && canIturnFoward){
if(playerHead.rotation != Quaternion.Euler(0, 0, 0)) {SetCooldown(0); lastTurn = player.position; transform.parent.GetChild(1).GetChild(0).GetComponent<BodyController>().isIFolow = true;}
playerHead.rotation = Quaternion.Euler(0, 0, 0); //fix in release
}
if(testModePC) //delete in release //from
if(Input.GetKey("a") && canIturnLeft) {
if(playerHead.rotation != Quaternion.Euler(0, -90, 0)) {SetCooldown(-90); lastTurn = player.position; transform.parent.GetChild(1).GetChild(0).GetComponent<BodyController>().isIFolow = true;}
playerHead.rotation = Quaternion.Euler(0, -90, 0);
canIturnRight = false;
}
else if(Input.GetKey("d") && canIturnRight) {
if(playerHead.rotation != Quaternion.Euler(0, 90, 0)) {SetCooldown(90); lastTurn = player.position; transform.parent.GetChild(1).GetChild(0).GetComponent<BodyController>().isIFolow = true;}
playerHead.rotation = Quaternion.Euler(0, 90, 0);
canIturnLeft = false;
}
else if (canIturnFoward) {
if(playerHead.rotation != Quaternion.Euler(0, 0, 0)) {SetCooldown(0); lastTurn = player.position; transform.parent.GetChild(1).GetChild(0).GetComponent<BodyController>().isIFolow = true;}
playerHead.rotation = Quaternion.Euler(0, 0, 0);
} //to
}
public void SetCooldown(int turnAngle){
beginCooldown = player.position;
switch(turnAngle){
case -90: cooldownSide = Sides.left; break;
case 90: cooldownSide = Sides.right; break;
case 0: cooldownSide = Sides.forward; break;
}
}
private void CheckCooldown(){
if(cooldownSide != Sides.zero){
switch(cooldownSide){
case Sides.left: if(beginCooldown.x - player.position.x >= 1) canIturnFoward = true; else canIturnFoward = false; break;
case Sides.right: if(beginCooldown.x - player.position.x <= -1) canIturnFoward = true; else canIturnFoward = false; break;
case Sides.forward:
if(beginCooldown.z - player.position.z <= -1){
canIturnLeft = true;
canIturnRight = true;
}
else{
canIturnLeft = false;
canIturnRight = false;
}
break;
}
}
else{
canIturnLeft = true;
canIturnRight = true;
canIturnFoward = true;
}
}
public enum Sides{
left, right, forward, zero
}
}
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class PlayerController : MonoBehaviour
{
public float speed;
public bool testModePC = false; //переменная для теста на пк (игра на андроид)
public Transform player; //голова + камера
public Transform playerHead; //голова
public Transform playerBodyParent; //объект с кубиками тела
private Vector3 beginCooldown; //
private Sides cooldownSide = Sides.zero; //
private bool canIturnLeft; // переменные для кулдауна - чтобы игрок не мог поворачивать слишком часто
private bool canIturnRight; //
private bool canIturnFoward; //
public Vector3 lastTurn; //сохраняет позицию последнего поворота
private void FixedUpdate() {
player.position += playerHead.forward * Time.deltaTime * speed;
CheckCooldown();
if(Input.touchCount == 1){
if(Input.GetTouch(0).position.x <= Screen.width / 2 && canIturnLeft){
if(playerHead.rotation != Quaternion.Euler(0, -90, 0)) {SetCooldown(-90); lastTurn = player.position; transform.parent.GetChild(1).GetChild(0).GetComponent<BodyController>().isIFolow = true;}
playerHead.rotation = Quaternion.Euler(0, -90, 0);
}
else if(Input.GetTouch(0).position.x >= Screen.width / 2 && canIturnRight) {
if(playerHead.rotation != Quaternion.Euler(0, 90, 0)) {SetCooldown(90); lastTurn = player.position; transform.parent.GetChild(1).GetChild(0).GetComponent<BodyController>().isIFolow = true;}
playerHead.rotation = Quaternion.Euler(0, 90, 0);
}
}
else if(testModePC == false && canIturnFoward){
if(playerHead.rotation != Quaternion.Euler(0, 0, 0)) {SetCooldown(0); lastTurn = player.position; transform.parent.GetChild(1).GetChild(0).GetComponent<BodyController>().isIFolow = true;}
playerHead.rotation = Quaternion.Euler(0, 0, 0); //fix in release
}
if(testModePC) //delete in release //from
if(Input.GetKey("a") && canIturnLeft) {
if(playerHead.rotation != Quaternion.Euler(0, -90, 0)) {SetCooldown(-90); lastTurn = player.position; transform.parent.GetChild(1).GetChild(0).GetComponent<BodyController>().isIFolow = true;}
playerHead.rotation = Quaternion.Euler(0, -90, 0);
canIturnRight = false;
}
else if(Input.GetKey("d") && canIturnRight) {
if(playerHead.rotation != Quaternion.Euler(0, 90, 0)) {SetCooldown(90); lastTurn = player.position; transform.parent.GetChild(1).GetChild(0).GetComponent<BodyController>().isIFolow = true;}
playerHead.rotation = Quaternion.Euler(0, 90, 0);
canIturnLeft = false;
}
else if (canIturnFoward) {
if(playerHead.rotation != Quaternion.Euler(0, 0, 0)) {SetCooldown(0); lastTurn = player.position; transform.parent.GetChild(1).GetChild(0).GetComponent<BodyController>().isIFolow = true;}
playerHead.rotation = Quaternion.Euler(0, 0, 0);
} //to
}
public void SetCooldown(int turnAngle){
beginCooldown = player.position;
switch(turnAngle){
case -90: cooldownSide = Sides.left; break;
case 90: cooldownSide = Sides.right; break;
case 0: cooldownSide = Sides.forward; break;
}
}
private void CheckCooldown(){
if(cooldownSide != Sides.zero){
switch(cooldownSide){
case Sides.left: if(beginCooldown.x - player.position.x >= 1) canIturnFoward = true; else canIturnFoward = false; break;
case Sides.right: if(beginCooldown.x - player.position.x <= -1) canIturnFoward = true; else canIturnFoward = false; break;
case Sides.forward:
if(beginCooldown.z - player.position.z <= -1){
canIturnLeft = true;
canIturnRight = true;
}
else{
canIturnLeft = false;
canIturnRight = false;
}
break;
}
}
else{
canIturnLeft = true;
canIturnRight = true;
canIturnFoward = true;
}
}
public enum Sides{
left, right, forward, zero
}
}
код с всех частей тела: висит на всех part
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BodyController : MonoBehaviour
{
public Vector3 targetVector;
public bool isIFolow = true;
private float speed;
public Vector3 lastTurn;
private void Awake() {
speed = transform.parent.parent.GetChild(0).GetComponent<PlayerController>().speed;
lastTurn = transform.position;
}
private void FixedUpdate() {
Transform Target;
if(transform.GetSiblingIndex() == 0){
Target = transform.parent.parent.GetChild(0);
if(transform.position != Target.GetComponent<PlayerController>().lastTurn && isIFolow){
transform.position = Vector3.MoveTowards(transform.position, Target.GetComponent<PlayerController>().lastTurn, speed * Time.deltaTime);
}
else{
if(transform.position == Target.GetComponent<PlayerController>().lastTurn) {
lastTurn = transform.position;
transform.parent.GetChild(1).GetComponent<BodyController>().isIFolow = true;
isIFolow = false;
}
transform.position = Vector3.MoveTowards(transform.position, Target.position, speed * Time.deltaTime);
}
}
else{
Target = transform.parent.GetChild(transform.GetSiblingIndex() - 1);
if(transform.position != Target.GetComponent<BodyController>().lastTurn && isIFolow){
transform.position = Vector3.MoveTowards(transform.position, Target.GetComponent<BodyController>().lastTurn, speed * Time.deltaTime);
}
else{
if(transform.position == Target.GetComponent<BodyController>().lastTurn){
lastTurn = transform.position;
isIFolow = false;
if(transform.parent.childCount != transform.GetSiblingIndex() + 1) transform.parent.GetChild(transform.GetSiblingIndex() + 1).GetComponent<BodyController>().isIFolow = true;
}
transform.position = Vector3.MoveTowards(transform.position, Target.position, speed * Time.deltaTime);
}
}
}
}
using System.Collections.Generic;
using UnityEngine;
public class BodyController : MonoBehaviour
{
public Vector3 targetVector;
public bool isIFolow = true;
private float speed;
public Vector3 lastTurn;
private void Awake() {
speed = transform.parent.parent.GetChild(0).GetComponent<PlayerController>().speed;
lastTurn = transform.position;
}
private void FixedUpdate() {
Transform Target;
if(transform.GetSiblingIndex() == 0){
Target = transform.parent.parent.GetChild(0);
if(transform.position != Target.GetComponent<PlayerController>().lastTurn && isIFolow){
transform.position = Vector3.MoveTowards(transform.position, Target.GetComponent<PlayerController>().lastTurn, speed * Time.deltaTime);
}
else{
if(transform.position == Target.GetComponent<PlayerController>().lastTurn) {
lastTurn = transform.position;
transform.parent.GetChild(1).GetComponent<BodyController>().isIFolow = true;
isIFolow = false;
}
transform.position = Vector3.MoveTowards(transform.position, Target.position, speed * Time.deltaTime);
}
}
else{
Target = transform.parent.GetChild(transform.GetSiblingIndex() - 1);
if(transform.position != Target.GetComponent<BodyController>().lastTurn && isIFolow){
transform.position = Vector3.MoveTowards(transform.position, Target.GetComponent<BodyController>().lastTurn, speed * Time.deltaTime);
}
else{
if(transform.position == Target.GetComponent<BodyController>().lastTurn){
lastTurn = transform.position;
isIFolow = false;
if(transform.parent.childCount != transform.GetSiblingIndex() + 1) transform.parent.GetChild(transform.GetSiblingIndex() + 1).GetComponent<BodyController>().isIFolow = true;
}
transform.position = Vector3.MoveTowards(transform.position, Target.position, speed * Time.deltaTime);
}
}
}
}
https://drive.google.com/file/d/1swNGiy3hfwdNLeK7sTiBGEw-Q1s0X6Iy/view?usp=sharing