调用 OnTriggerEnter 时为空引用?
Null Reference When Calling OnTriggerEnter?
长话短说,我正在创建一个对象池系统,在我的脚本(见下文)PickAxeTestManager 中,我在第 22 行收到错误 CS1501 "No overload for method OnTriggerEnter takes 0 arguments"。
using UnityEngine;
using System.Collections;
public class PickAxeTestManager : MonoBehaviour {
public GameObject PickAxeprefab;
void Start ()
{
PickAxePoolManager.instance.CreatePool (PickAxeprefab, 2); //CreatePool is a method in PickAxePoolManager
}
void Update ()
{
if (Input.GetKeyDown (KeyCode.A))
{
PickAxePoolManager.instance.ReuseObject(PickAxeprefab, Vector3.zero, Quaternion.identity); //ReuseObject is also a method in PickAxePoolManager
}
if (ResetByWall.instance.OnTriggerEnter()) //ERROR CS1501 is here. "No overload for method OnTriggerEnter takes 0 arguments".
{
PickAxePoolManager.instance.ReuseObject(PickAxeprefab, Vector3.zero, Quaternion.identity); // Same here...
}
}
}
这是我的 ResetByWall 脚本(如下),我有这个脚本是因为当我的 PickAxe 击中 "South Wall" 时,我希望它回到池系统(但现在,我只是 "Destroying" 哈哈,直到我弄清楚逻辑)。
using UnityEngine;
using System.Collections;
public class ResetByWall : MonoBehaviour {
public bool collided;
//NOTE:
//Singleton Pattern from lines 12 to 25 //
// ************************************
static ResetByWall _instance; // Reference to the Reset By Wall script
public static ResetByWall instance // This is the accessor
{
get
{
if(_instance == null) // Check to see if _instance is null
{
_instance = FindObjectOfType<ResetByWall>(); //Find the instance in the Reset By Wall script in the currently active scene
}
return _instance;
}
}
//public GameObject prefab;
public void OnTriggerEnter(Collider other) {
collided = true;
if (other.gameObject.tag == "Pick Axe_PoolerTest") //I tagged the prefab as "Pick Axe_PoolerTest"
{
Debug.Log("Pick Axe entered the trigger!");
Destroy(other.gameObject);
}
}
}
我的问题是:OnTriggerEnter 可以接受一个不属于 "type collider" 的参数,这样我就可以摆脱这个 "Null Reference" 吗?在我问这个问题之前我做了很多研究,但我找不到任何东西!
此外,下面是我的 PickAxePoolManager 脚本(这是我现在正在处理的所有内容的主要 backbone),但我相信您甚至可能需要查看此脚本的唯一部分是方法,CreatePool 和 ReuseObject。
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PickAxePoolManager : MonoBehaviour {
Dictionary<int,Queue<GameObject>> poolDictionary = new Dictionary<int,Queue<GameObject>>();
//NOTE:
//Singleton Pattern used from lines 12 to 25
static PickAxePoolManager _instance; // Reference to the Pool Manager script
public static PickAxePoolManager instance // This is the accessor
{
get
{
if(_instance == null) // Check to see if _instance is null
{
_instance = FindObjectOfType<PickAxePoolManager>(); //Find the instance in the Pool Manager script in the currently active scene
}
return _instance;
}
}
/// <summary>
/// Creates the pool.
/// </summary>
/// <param name="prefab">Prefab.</param>
/// <param name="poolSize">Pool size.</param>
public void CreatePool(GameObject prefab, int poolSize)
{
int poolKey = prefab.GetInstanceID (); // Unique integer for every GameObject
if (!poolDictionary.ContainsKey (poolKey)) //Make sure poolKey is not already in the Dictionary,
//if it's not then we can create the pool
{
poolDictionary.Add(poolKey, new Queue<GameObject>());
for (int i = 0; i < poolSize; i++) //Instantiate the prefabs as dictated by the "poolSize" integer
{
GameObject newObject = Instantiate (prefab) as GameObject; //Instantiate as a GameObject
newObject.SetActive(false); // Don't want it to be visible in the scene yet
poolDictionary [poolKey].Enqueue(newObject); // Add it to our Pool
}
}
}
/// <summary>
/// Reuses the object in our pool.
/// </summary>
/// <param name="prefab">Prefab.</param>
/// <param name="position">Position.</param>
/// <param name="rotation">Rotation.</param>
public void ReuseObject (GameObject prefab, Vector3 position, Quaternion rotation)
{
int poolKey = prefab.GetInstanceID (); // Get our pool key once again
if (poolDictionary.ContainsKey (poolKey)) // Quick check to make sure our pool dictionary contains the pool key
{
GameObject objectToReuse = poolDictionary[poolKey].Dequeue(); //Get the next object in the pool
poolDictionary[poolKey].Enqueue(objectToReuse); // Add the object back onto the end of the queue so it can be reused later
objectToReuse.SetActive(true); //Make sure the object was not disabled
objectToReuse.transform.position = position; // set position to applied values
objectToReuse.transform.rotation = rotation; // set rotation to applied values
}
}
}
如果您需要更多详细信息,请告诉我。谢谢! :)
第一,
if (ResetByWall.instance.OnTriggerEnter()) //ERROR CS1501 is here. "No overload for method OnTriggerEnter takes 0 arguments".
"OnTriggerEnter" 不会 return 任何东西(无效),因此在 if 块中使用它是不可行的。
第二,
My question is: can the OnTriggerEnter take an argument that is not of "type collider" so that I can rid of this "Null Reference" ?
如果你想使用Unity的内部系统,那必须是"type collider"。但是,如果你使用"OnTriggerEnter"不需要配合Unity内部的物理系统,那么你可以在C#中做函数重载。
public boolean OnTriggerEnter(){
// Internal logic
return true/false;
}
public boolean OnTriggerEnter(Collider other){
// Internal logic
return true/false;
}
public boolean OnTriggerEnter(GameObject target){
// Internal logic
return true/false;
}
长话短说,我正在创建一个对象池系统,在我的脚本(见下文)PickAxeTestManager 中,我在第 22 行收到错误 CS1501 "No overload for method OnTriggerEnter takes 0 arguments"。
using UnityEngine;
using System.Collections;
public class PickAxeTestManager : MonoBehaviour {
public GameObject PickAxeprefab;
void Start ()
{
PickAxePoolManager.instance.CreatePool (PickAxeprefab, 2); //CreatePool is a method in PickAxePoolManager
}
void Update ()
{
if (Input.GetKeyDown (KeyCode.A))
{
PickAxePoolManager.instance.ReuseObject(PickAxeprefab, Vector3.zero, Quaternion.identity); //ReuseObject is also a method in PickAxePoolManager
}
if (ResetByWall.instance.OnTriggerEnter()) //ERROR CS1501 is here. "No overload for method OnTriggerEnter takes 0 arguments".
{
PickAxePoolManager.instance.ReuseObject(PickAxeprefab, Vector3.zero, Quaternion.identity); // Same here...
}
}
}
这是我的 ResetByWall 脚本(如下),我有这个脚本是因为当我的 PickAxe 击中 "South Wall" 时,我希望它回到池系统(但现在,我只是 "Destroying" 哈哈,直到我弄清楚逻辑)。
using UnityEngine;
using System.Collections;
public class ResetByWall : MonoBehaviour {
public bool collided;
//NOTE:
//Singleton Pattern from lines 12 to 25 //
// ************************************
static ResetByWall _instance; // Reference to the Reset By Wall script
public static ResetByWall instance // This is the accessor
{
get
{
if(_instance == null) // Check to see if _instance is null
{
_instance = FindObjectOfType<ResetByWall>(); //Find the instance in the Reset By Wall script in the currently active scene
}
return _instance;
}
}
//public GameObject prefab;
public void OnTriggerEnter(Collider other) {
collided = true;
if (other.gameObject.tag == "Pick Axe_PoolerTest") //I tagged the prefab as "Pick Axe_PoolerTest"
{
Debug.Log("Pick Axe entered the trigger!");
Destroy(other.gameObject);
}
}
}
我的问题是:OnTriggerEnter 可以接受一个不属于 "type collider" 的参数,这样我就可以摆脱这个 "Null Reference" 吗?在我问这个问题之前我做了很多研究,但我找不到任何东西!
此外,下面是我的 PickAxePoolManager 脚本(这是我现在正在处理的所有内容的主要 backbone),但我相信您甚至可能需要查看此脚本的唯一部分是方法,CreatePool 和 ReuseObject。
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PickAxePoolManager : MonoBehaviour {
Dictionary<int,Queue<GameObject>> poolDictionary = new Dictionary<int,Queue<GameObject>>();
//NOTE:
//Singleton Pattern used from lines 12 to 25
static PickAxePoolManager _instance; // Reference to the Pool Manager script
public static PickAxePoolManager instance // This is the accessor
{
get
{
if(_instance == null) // Check to see if _instance is null
{
_instance = FindObjectOfType<PickAxePoolManager>(); //Find the instance in the Pool Manager script in the currently active scene
}
return _instance;
}
}
/// <summary>
/// Creates the pool.
/// </summary>
/// <param name="prefab">Prefab.</param>
/// <param name="poolSize">Pool size.</param>
public void CreatePool(GameObject prefab, int poolSize)
{
int poolKey = prefab.GetInstanceID (); // Unique integer for every GameObject
if (!poolDictionary.ContainsKey (poolKey)) //Make sure poolKey is not already in the Dictionary,
//if it's not then we can create the pool
{
poolDictionary.Add(poolKey, new Queue<GameObject>());
for (int i = 0; i < poolSize; i++) //Instantiate the prefabs as dictated by the "poolSize" integer
{
GameObject newObject = Instantiate (prefab) as GameObject; //Instantiate as a GameObject
newObject.SetActive(false); // Don't want it to be visible in the scene yet
poolDictionary [poolKey].Enqueue(newObject); // Add it to our Pool
}
}
}
/// <summary>
/// Reuses the object in our pool.
/// </summary>
/// <param name="prefab">Prefab.</param>
/// <param name="position">Position.</param>
/// <param name="rotation">Rotation.</param>
public void ReuseObject (GameObject prefab, Vector3 position, Quaternion rotation)
{
int poolKey = prefab.GetInstanceID (); // Get our pool key once again
if (poolDictionary.ContainsKey (poolKey)) // Quick check to make sure our pool dictionary contains the pool key
{
GameObject objectToReuse = poolDictionary[poolKey].Dequeue(); //Get the next object in the pool
poolDictionary[poolKey].Enqueue(objectToReuse); // Add the object back onto the end of the queue so it can be reused later
objectToReuse.SetActive(true); //Make sure the object was not disabled
objectToReuse.transform.position = position; // set position to applied values
objectToReuse.transform.rotation = rotation; // set rotation to applied values
}
}
}
如果您需要更多详细信息,请告诉我。谢谢! :)
第一,
if (ResetByWall.instance.OnTriggerEnter()) //ERROR CS1501 is here. "No overload for method OnTriggerEnter takes 0 arguments".
"OnTriggerEnter" 不会 return 任何东西(无效),因此在 if 块中使用它是不可行的。
第二,
My question is: can the OnTriggerEnter take an argument that is not of "type collider" so that I can rid of this "Null Reference" ?
如果你想使用Unity的内部系统,那必须是"type collider"。但是,如果你使用"OnTriggerEnter"不需要配合Unity内部的物理系统,那么你可以在C#中做函数重载。
public boolean OnTriggerEnter(){
// Internal logic
return true/false;
}
public boolean OnTriggerEnter(Collider other){
// Internal logic
return true/false;
}
public boolean OnTriggerEnter(GameObject target){
// Internal logic
return true/false;
}