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);
}
}