赛道(障碍物)生成
我们在做跑酷游戏的时候要明白这几点:
赛道的生成以及消失
障碍物的生成以及消失
我们先来讲赛道的生成,什么时候生成?又什么时候消失?
解决方法是我们要用到触发器,当角色到达触发点的时候,在角色的前方自动生成赛道,这里我们要用到对象池,当我们赛道到角色的距离大于多少的时候我们就回收赛道,优化性能。
1、触发点就是我们在赛道(Trackshort)上新加一个(Trackpoint)盒型碰撞器并且勾选触发器,并且新建一个标签给它,是为了和赛道上的盒型碰撞器区分开,赛道上的盒型碰撞器不勾选触发器。
2、下面创建一个Trackcreator类来生成赛道,把脚本挂在gamemanger上
首先我们要定义几个
// An highlighted block
public List<GameObject> lists = new List<GameObject>();//对象池,对象池就是一个集合
public GameObject[] tracks;//放有赛道的数组
private static Trackcreator instance;//单例类
public static Trackcreator Instance { get { return instance; } }//单例类就是全局类
在Start里面完成单例类
// An highlighted block
void Start()
{
if (instance != null)
{
Destroy(this.gameObject);
return;
}
else
{
instance = this;
}
}
我们新写一个赛道的函数Creator()
// An highlighted block
public GameObject Creator()//函数是有返回值的,这里返回的是对象
{
if (lists.Count > 0)//判断对象池里面有没有对象
{
var lastindex = lists.Count - 1;//找到集合里面的最后一个的下标
var lastone = lists[lastindex];//取出集合里最后一个对象
lists.Remove(lastone);//移除该对象
lastone.SetActive(true);//对象激活
return lastone;//返回对象
}
else
{
var newindex = Random.Range(0, tracks.Length);//随机生成数组的大小范围内的任意一个数
var newone = Instantiate(tracks[newindex]);//实例化该对象
return newone;//返回对象
}
}
我们还要写一个回收赛道的方法Returntrack()
// An highlighted block
public void Returntrack(GameObject obj)
{
if (obj == null) return;
obj.SetActive(false);
lists.Add(obj);
}
我们还要写一个生成赛道的方法Gettrack()
// An highlighted block
public void Gettrack()
{
GameObject track = Creator();
track.GetComponent<Returntrack>().pool = this;//这里回收的时候要用到
track.transform.position = move.Instance.player.transform.position + new Vector3(0, 0, 20);
}
完整Trackcreator类代码
// An highlighted block
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Trackcreator : MonoBehaviour
{
public List<GameObject> lists = new List<GameObject>();
public GameObject[] tracks;
private static Trackcreator instance;
public static Trackcreator Instance { get { return instance; } }
void Start()
{
if (instance != null)
{
Destroy(this.gameObject);
return;
}
else
{
instance = this;
}
}
public GameObject Creator()
{
if (lists.Count > 0)
{
var lastindex = lists.Count - 1;
var lastone = lists[lastindex];
lists.Remove(lastone);
lastone.SetActive(true);
return lastone;
}
else
{
var newindex = Random.Range(0, tracks.Length);
var newone = Instantiate(tracks[newindex]);
return newone;
}
}
public void Returntrack(GameObject obj)
{
if (obj == null) return;
obj.SetActive(false);
lists.Add(obj);
}
public void Gettrack()
{
GameObject track = Creator();
track.GetComponent<Returntrack>().pool = this;
track.transform.position = move.Instance.player.transform.position + new Vector3(0, 0, 20);
}
// Update is called once per frame
void Update()
{
}
}
下面我们还要写个角色的移动代码,我们创建一个move类,简单写个
// An highlighted block
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class move : MonoBehaviour
{
public Transform player;//获取角色的位置
private static move instance;//单例类
public static move Instance { get { return instance; } }
// Start is called before the first frame update
void Start()
{
player = this.transform;
if (instance != null)
{
Destroy(this.gameObject);
return;
}
else
{
instance = this;
}
}
// Update is called once per frame
void Update()
{
if (Input.GetKey(KeyCode.W))
{
player.transform.Translate(Vector3.forward * Time.deltaTime*0.8f);
}
}
public void OnTriggerEnter(Collider collider)
{
if (collider.tag.Equals("Trackpoint"))//通过标签来触发触发器
{
Trackcreator.Instance.Gettrack();//调用赛道生成方法
}
}
public void OnTriggerStay(Collider collider)
{
}
public void OnTriggerExit(Collider collider)
{
}
}
看下效果
赛道是生成成功的,照这个思路生成我们的障碍物是没有问题的。我们在对生成赛道距离的把控,我们可以通过随机函数Random来把控。
赛道的消失
我们通过距离来判断,首先我们还是新建一个Returntrack类,把脚本挂在预制件赛道上面。
// An highlighted block
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Returntrack : MonoBehaviour
{
public Trackcreator pool;//获取Trackcreator脚本
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
var playerpos = move.Instance.player.transform.position;//角色的位置
var newpos = this.transform.position;
var distance = (playerpos - newpos).magnitude;//求两向量的距离
if (distance > 10)
{
pool.Returntrack(this.gameObject);
}
}
}
看效果
生成又回收了,说明成功了,大家可以根据这种思路去生成障碍物和回收障碍物。
主角奔跑逻辑
这可以根据我前几篇讲的游戏角色的移动控制来做,完全没问题。
后面我还会讲变颜色和动画。
我有一个半成品的变色猫,感兴趣的可以去看下,因为是连接服务器的,还没做出完,你们可以直接打开里面的主要场景运行看下效果。
链接:https://pan.baidu.com/s/19NQTqpBuOVxzfm2HJdsJDw
提取码:spvq