我在做一个没完没了的跑步游戏。我是一个编程的初学者,完成了this和this教程,所以我不能100%确定这些代码是如何工作的,这使得我很难弄清楚如何解决我的问题。代码应该使用对象池来创建平台,然后激活它们,停用它们,将它们移动到播放器前面,然后再次激活它们。(至少,我认为)这为玩家提供了无限的平台,而不必不断地实例化新的平台。下面是Platform Generator的代码:
using UnityEngine;
using System.Collections;
public class PlatformGenerator : MonoBehaviour
{
public GameObject thePlatform;
public Transform generationPoint;
public float distanceBetween;
private float platformWidth;
public float distanceBetweenMin;
public float distanceBetweenMax;
private int platformSelector;
private float[] platformWidths;
// public GameObject[] thePlatforms;
public ObjectPooler[] theObjectPools;
private float minHeight;
private float maxHeight;
public Transform maxHeightPoint;
public float maxHeightChange;
private float heightChange;
void Start ()
{
// platformWidth = thePlatform.GetComponent<BoxCollider2D> ().size.x;
platformWidths = new float[theObjectPools.Length];
for (int i = 0; i < theObjectPools.Length; i++)
{
platformWidths[i] = theObjectPools[i].pooledObject.GetComponent<BoxCollider2D>().size.x;
}
minHeight = transform.position.y;
maxHeight = maxHeightPoint.position.y;
}
void Update ()
{
if (transform.position.x < generationPoint.position.x)
{
distanceBetween = Random.Range (distanceBetweenMin, distanceBetweenMax);
platformSelector = Random.Range (0, theObjectPools.Length);
heightChange = transform.position.y + Random.Range (maxHeightChange, -maxHeightChange);
// if you want to have platforms generating outside boundries, comment out this code:
if (heightChange > maxHeight)
{
heightChange = maxHeight;
}
else if (heightChange < minHeight)
{
heightChange = minHeight;
}
transform.position = new Vector3 (transform.position.x + (platformWidths[platformSelector] / 2) + distanceBetween, heightChange, transform.position.z);
// Instantiate (/*thePlatform*/ thePlatforms[platformSelector], transform.position, transform.rotation);
GameObject newPlatform = theObjectPools[platformSelector].GetPooledObject();
newPlatform.transform.position = transform.position;
newPlatform.transform.rotation = transform.rotation;
newPlatform.SetActive (true);
transform.position = new Vector3 (transform.position.x + (platformWidths[platformSelector] / 2), transform.position.y, transform.position.z);
}
}
}下面是对象池的代码:
public class ObjectPooler : MonoBehaviour
{
public GameObject pooledObject;
public int pooledAmount;
List<GameObject> pooledObjects;
void Start ()
{
pooledObjects = new List<GameObject>();
for (int i = 0; i < pooledAmount; i++)
{
GameObject obj = (GameObject) Instantiate (pooledObject);
obj.SetActive (false);
pooledObjects.Add (obj);
}
}
public GameObject GetPooledObject()
{
for (int i = 0; i < pooledObjects.Count; i++)
{
if (!pooledObjects[i].activeInHierarchy)
{
return pooledObjects[i];
}
}
GameObject obj = (GameObject) Instantiate (pooledObject);
obj.SetActive (false);
pooledObjects.Add (obj);
return obj;
}
}脚本在几秒钟的时间内运行良好,但很快就会开始创建新的平台,这是我试图避免的。我认为发生的情况是平台没有被禁用,所以代码不能移动平台,而是创建新的平台。我相信这是一个很容易解决的问题,但我不确定该怎么办。有人知道怎么解决这个问题吗?谢谢。
发布于 2016-12-29 12:55:00
据我所知,您的代码中没有将对象返回到池中的功能。有一个函数可以从池中获取一个对象,如果需要,它会自动实例化,否则会从池中拉出,并且您在启动方法逻辑中有预池,但您从未将对象放回。您需要创建一个函数将对象返回到池中。
发布于 2016-12-29 13:20:29
函数
public GameObject GetPooledObject(){...}
如果对象在层次结构中被禁用,则返回池中的poolObject。否则,它将实例化一个新的池对象并返回该对象。
newPlatform.SetActive (true);
在update功能中,您可以将poolObject设置为活动状态,但决不能将其停用。因此,您的池子会不断生成新的对象。您需要使用object.setActive(false);来停用对象
你可以及时完成--比如每2秒对象消失一次(但对于不同的级别,你需要改变这一次),或者你可以计算对象是否已经被交叉并且远远落后,然后你可以停用它。
https://stackoverflow.com/questions/41352958
复制相似问题