当障碍物与边界发生碰撞时,如何编写障碍物以返回我的对象池?
How to Code Obstacle to Go Back Into My Object Pooler When They Collide With a Boundary?
请不要被我的长问题吓到,我确定我只是用措辞怪异哈哈。我遵循了 Mike Geig 关于在 Unity 中使用对象池的优秀教程,并且我很好地理解了这个概念。我只是有一个问题,这个问题让我头痛了将近一个星期。当它与南墙(标记为 "SouthWall")碰撞时,我如何使它回到我的对象池中?我有一张照片和我的脚本:alt text
(下面的脚本是我的通用 Pooler 脚本,我从对象池教程中稍微改动了一下)
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PoolerTestScript : MonoBehaviour
{
public static PoolerTestScript current;
public GameObject spikeWall;
public int wallPooledAmount = 20;
public bool willGrow = true; // This will be false in the inspector and the game, but here I will keep it true so I dont mess anything up.
private List<GameObject> wallPooledObjects;
void Awake ()
{
current = this;
}
void Start ()
{
wallPooledObjects = new List<GameObject>();
for(int i = 0; i < wallPooledAmount; i++)
{
GameObject obj = (GameObject)Instantiate(spikeWall);
obj.SetActive(false);
wallPooledObjects.Add(obj);
}
}
public GameObject GetPooledObject()
{
for(int i = 0; i< wallPooledObjects.Count; i++)
{
if(!wallPooledObjects[i].activeInHierarchy)
{
return wallPooledObjects[i];
}
}
if (willGrow)
{
GameObject obj = (GameObject)Instantiate(spikeWall);
wallPooledObjects.Add(obj);
return obj;
}
return null;
}
}
(下面的脚本会产生障碍,我从 Space 射手教程中得到它并对其进行了一些修改!)
using UnityEngine;
using System.Collections;
[System.Serializable]
public class Obstacle2 // Spike Wall Obstacle
{
public GameObject wall; // The second obstacle gameobject. This is attached in the inspector.
public Vector3 spawnWPosValues; // Position where the second obstacle will be spawned at on the X,Y,Z plane.
public int wCount; // This is the count of the second obstacle in a given wave.
public float wSpawnWait; // Time in seconds between next wave of obstacle 2.
public float wStartGameWait; // Time in seconds between when the game starts and when the second obstacle start spawning.
public float wWaveSpawnWait; // Time in seconds between waves when the next wave of obstacle 2 will spawn.
}
public class SpawnWalls : MonoBehaviour {
public Obstacle2 obstacle2;
void Start () {
StartCoroutine (SpawnWall ());
//InvokeRepeating ("Spawn", 1, 1);
//Get reference to rigidbody, and set the speed
}
IEnumerator SpawnWall () {
yield return new WaitForSeconds(obstacle2.wStartGameWait);
while (true)
{
for (int i = 0; i < obstacle2.wCount; i++) {
Vector3 spawnPosition_2 = new Vector3 (Random.Range(-obstacle2.spawnWPosValues.x, obstacle2.spawnWPosValues.x),
obstacle2.spawnWPosValues.y,
obstacle2.spawnWPosValues.z);
Quaternion spawnRotation_2 = Quaternion.Euler(0,270,0); // was 90, 0, 90
Instantiate (obstacle2.wall, spawnPosition_2, spawnRotation_2);
yield return new WaitForSeconds(obstacle2.wSpawnWait);
}
yield return new WaitForSeconds (obstacle2.wWaveSpawnWait);
}
}
}
(下面的脚本是移动障碍的原因)
using UnityEngine;
using System.Collections;
public class WallObstacleMover : MonoBehaviour {
private Rigidbody rb; //Reference to Rigidbody Component
public float speed; //Speed, updated through script
public float acceleration; //Every second, the speed will increase by this much
//Executes once, when object is spawned / scene loaded
void Start() {
//Get reference to rigidbody, and set the speed
rb = GetComponent<Rigidbody> ();
rb.velocity = -transform.right * speed;
}
//Executes every frame
void Update() {
//Add acceleration to speed, make sure it's not above topSpeed)
speed += Time.deltaTime * acceleration;
//Set object velocity
rb.velocity = -transform.right * speed;
}
}
你不用你的 pooler 来实例化障碍,你只需在协程中实例化它。您需要使用 PoolerTestScript 中的 GetPooledObject() 来合并障碍物。
然后在碰撞时,不是破坏游戏对象,而是调用一些您还需要创建的 GoBackToPool() 方法(当然,池化对象需要一种方法来找到它所属的池,因此要么保留引用,要么进行一些场景管理提供静态访问 - 代表将是另一种选择)
请不要被我的长问题吓到,我确定我只是用措辞怪异哈哈。我遵循了 Mike Geig 关于在 Unity 中使用对象池的优秀教程,并且我很好地理解了这个概念。我只是有一个问题,这个问题让我头痛了将近一个星期。当它与南墙(标记为 "SouthWall")碰撞时,我如何使它回到我的对象池中?我有一张照片和我的脚本:alt text
(下面的脚本是我的通用 Pooler 脚本,我从对象池教程中稍微改动了一下)
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PoolerTestScript : MonoBehaviour
{
public static PoolerTestScript current;
public GameObject spikeWall;
public int wallPooledAmount = 20;
public bool willGrow = true; // This will be false in the inspector and the game, but here I will keep it true so I dont mess anything up.
private List<GameObject> wallPooledObjects;
void Awake ()
{
current = this;
}
void Start ()
{
wallPooledObjects = new List<GameObject>();
for(int i = 0; i < wallPooledAmount; i++)
{
GameObject obj = (GameObject)Instantiate(spikeWall);
obj.SetActive(false);
wallPooledObjects.Add(obj);
}
}
public GameObject GetPooledObject()
{
for(int i = 0; i< wallPooledObjects.Count; i++)
{
if(!wallPooledObjects[i].activeInHierarchy)
{
return wallPooledObjects[i];
}
}
if (willGrow)
{
GameObject obj = (GameObject)Instantiate(spikeWall);
wallPooledObjects.Add(obj);
return obj;
}
return null;
}
}
(下面的脚本会产生障碍,我从 Space 射手教程中得到它并对其进行了一些修改!)
using UnityEngine;
using System.Collections;
[System.Serializable]
public class Obstacle2 // Spike Wall Obstacle
{
public GameObject wall; // The second obstacle gameobject. This is attached in the inspector.
public Vector3 spawnWPosValues; // Position where the second obstacle will be spawned at on the X,Y,Z plane.
public int wCount; // This is the count of the second obstacle in a given wave.
public float wSpawnWait; // Time in seconds between next wave of obstacle 2.
public float wStartGameWait; // Time in seconds between when the game starts and when the second obstacle start spawning.
public float wWaveSpawnWait; // Time in seconds between waves when the next wave of obstacle 2 will spawn.
}
public class SpawnWalls : MonoBehaviour {
public Obstacle2 obstacle2;
void Start () {
StartCoroutine (SpawnWall ());
//InvokeRepeating ("Spawn", 1, 1);
//Get reference to rigidbody, and set the speed
}
IEnumerator SpawnWall () {
yield return new WaitForSeconds(obstacle2.wStartGameWait);
while (true)
{
for (int i = 0; i < obstacle2.wCount; i++) {
Vector3 spawnPosition_2 = new Vector3 (Random.Range(-obstacle2.spawnWPosValues.x, obstacle2.spawnWPosValues.x),
obstacle2.spawnWPosValues.y,
obstacle2.spawnWPosValues.z);
Quaternion spawnRotation_2 = Quaternion.Euler(0,270,0); // was 90, 0, 90
Instantiate (obstacle2.wall, spawnPosition_2, spawnRotation_2);
yield return new WaitForSeconds(obstacle2.wSpawnWait);
}
yield return new WaitForSeconds (obstacle2.wWaveSpawnWait);
}
}
}
(下面的脚本是移动障碍的原因)
using UnityEngine;
using System.Collections;
public class WallObstacleMover : MonoBehaviour {
private Rigidbody rb; //Reference to Rigidbody Component
public float speed; //Speed, updated through script
public float acceleration; //Every second, the speed will increase by this much
//Executes once, when object is spawned / scene loaded
void Start() {
//Get reference to rigidbody, and set the speed
rb = GetComponent<Rigidbody> ();
rb.velocity = -transform.right * speed;
}
//Executes every frame
void Update() {
//Add acceleration to speed, make sure it's not above topSpeed)
speed += Time.deltaTime * acceleration;
//Set object velocity
rb.velocity = -transform.right * speed;
}
}
你不用你的 pooler 来实例化障碍,你只需在协程中实例化它。您需要使用 PoolerTestScript 中的 GetPooledObject() 来合并障碍物。 然后在碰撞时,不是破坏游戏对象,而是调用一些您还需要创建的 GoBackToPool() 方法(当然,池化对象需要一种方法来找到它所属的池,因此要么保留引用,要么进行一些场景管理提供静态访问 - 代表将是另一种选择)