W鍵加速, A鍵左轉,D建右轉
新建一個Cube物體, 將其命名改爲SnakeHead 給他添加tag 標籤Player, 這裏的碰撞檢測用的Trigger, 給物體一個剛體
把重力去掉, Collider 中的 Is Trigger 勾上, 添加SnakeManage 腳本
2,新建一個Cube物體, 將其命名改爲SnakeBody 給他添加tag 標籤Player
3, 將SnakeHead , SnakeBody放到 SnakeManage腳本中
3, 在新建一個Cube,將其命名改爲CubeObj, 做成預製體, 放到Resources文件下
4, 建幾個 材質球,給他們 掛上
下面 就是 腳本實現
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class SnakeManage : MonoBehaviour
{
public static SnakeManage Instance;
protected List<SnakeBody> snakeList;
public GameObject HeadObj;
public GameObject BodyObjone;
CubeFactory cubeFactory;
private void Awake()
{
Instance = this;
snakeList = new List<SnakeBody>();
SnakeBody snakeHead = new SnakeHead(null, HeadObj);
snakeList.Add(snakeHead);
SnakeBody snakeBody = new SnakeBody(snakeHead, BodyObjone);
snakeList.Add(snakeBody);
//實例化一個生產Cubu的工廠類
cubeFactory = new CubeFactory(5, 5f);
}
private void OnTriggerEnter(Collider other)
{
if (other.tag == "wall")
{
isStart = false;
}
else if (other.tag == "Player")
{
isStart = false;
}
else
{
AddSnakeBody(other.gameObject);
}
}
void AddSnakeBody(GameObject targetObj)
{
// 手動刷新一下最後一個的oldPos
snakeList[snakeList.Count - 1].RefreshPostion();
SnakeBody snakeBodytwo = new SnakeBody(snakeList[snakeList.Count - 1], targetObj);
snakeList.Add(snakeBodytwo);
//減少Cube的計數
cubeFactory.ReduceHaveCubeCount();
targetObj.GetComponent<MeshRenderer>().material.color = Color.red;
targetObj.tag = "Player";
targetObj.name = "SnakeBody";
}
// Start is called before the first frame update
void Start()
{
}
float timer;
float speedtimer = 0.2f;
bool isStart = false;
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.A))
((SnakeHead)snakeList[0]).RotionLeft();
if (Input.GetKeyDown(KeyCode.D))
((SnakeHead)snakeList[0]).RotionRight();
if (Input.GetKey(KeyCode.W))
{
speedtimer = 0f;
}
if (Input.GetKeyUp(KeyCode.W))
{
speedtimer = 0.1f;
}
if (Input.GetKeyDown(KeyCode.Space))
isStart = !isStart;
//物體的移動
if (isStart)
{
timer += Time.deltaTime;
if (timer > speedtimer)
{
timer = 0f;
snakeList[0].MoveFont();
for (int i = 1; i < snakeList.Count; i++)
{
snakeList[i].FollowBody();
}
}
}
//產生Cube
cubeFactory.UpdataBuildCube();
}
}
下面是SnakeBody類
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SnakeBody
{
//記錄上一個的物體的SnakeBody
SnakeBody snakeBody;
public GameObject owerObj;
//記錄移動前的位置
Vector3 oldPos;
public SnakeBody(SnakeBody snakeBody, GameObject obj)
{
this.snakeBody = snakeBody;
this.owerObj = obj;
oldPos = this.owerObj.transform.position;
}
public void RefreshPostion()
{
oldPos = owerObj.transform.position;
}
public void FollowBody()
{
owerObj.transform.position = snakeBody.oldPos;
snakeBody.RefreshPostion();
}
public virtual void MoveFont()
{
}
}
public class SnakeHead:SnakeBody
{
public SnakeHead(SnakeHead snakeHead, GameObject obj) : base(snakeHead, obj)
{
}
public override void MoveFont()
{
//一次 走1米, Cube的大小 爲1米
owerObj.transform.Translate(Vector3.forward);
}
public void RotionLeft()
{
Vector3 angle = owerObj.transform.localEulerAngles;
angle.y -= 90f;
owerObj.transform.localEulerAngles = angle;
}
public void RotionRight()
{
Vector3 angle = owerObj.transform.localEulerAngles;
angle.y += 90f;
owerObj.transform.localEulerAngles = angle;
}
}
下面 是產生新的 Cube 工廠類
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class CubeFactory
{
Object cubeObj;
int buildCubeCount;
protected int BuildCubeCount
{
get { return buildCubeCount; }
set { buildCubeCount = value; }
}
private int haveCubeMaxCount;
protected int HaveCubeMaxCount
{
get { return haveCubeMaxCount; }
set { haveCubeMaxCount = value; }
}
private float buildIntervalTime;
protected float BuildIntervalTime
{
get { return buildIntervalTime; }
set { buildIntervalTime = value; }
}
private float timer = 0f;
public CubeFactory(int buildMaxCubeCount,float buildIntervalTime)
{
cubeObj = Resources.Load("CubeObj");
// SnakeManage.Instance.ReduceCount = ReduceHaveCubeCount;
this.HaveCubeMaxCount = buildMaxCubeCount;
this.BuildIntervalTime = buildIntervalTime;
timer = 0;
BuildCubeCount = 0;
InitCube();
}
public void ReduceHaveCubeCount()
{
BuildCubeCount--;
}
public void UpdataBuildCube()
{
timer += Time.deltaTime;
if (timer > BuildIntervalTime&& BuildCubeCount<HaveCubeMaxCount)
{
Debug.Log(BuildCubeCount + " " + HaveCubeMaxCount);
timer = 0f;
InitCube();
}
}
void InitCube()
{
BuildCubeCount++;
GameObject obj = GameObject.Instantiate(cubeObj) as GameObject;
float posx = Random.Range(-18, 18);
float posy = Random.Range(-18, 18);
obj.transform.position = new Vector3(posx, 0, posy);
}
}