[英]How do I access the custom class by knowing a variable from that class?
我创建了一个自定义类:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Obstacle {
public GameObject gameObj;
public Color color;
public GameObject starExplosion;
public GameObject regular_Trail;
[HideInInspector]
public bool firstCollistion = true;
public static Vector3 SpawnLocation()
{
int positionQuadran = Random.Range(1, 3);
switch (positionQuadran)
{
//spawn above the player
case 1:
return new Vector3(Random.Range(1.5f, -1.5f),
Random.Range(4f - SpawnStars.closerToPlayer, 4.5f),
Random.Range(1, -3.2f));
//spawn benith the player
case 2:
return new Vector3(Random.Range(1.5f, -1.5f),
Random.Range(-0.5f, SpawnStars.closerToPlayer),
Random.Range(1f, -3.2f));
}
return Vector3.zero;
}
}
现在,如您在该类中看到的,有一个变量public GameObject gameObj;
现在,在另一个脚本中,我需要访问此gameObj
实例所在的Obstacle
类的实例。我正在尝试这样做:
private void OnCollisionEnter(Collision collision)
{
collision.collider. //what do I do next?
}
由于某些原因,我不想让Obstacle
类从MonoBehaviour
。 由于无法从场景中的另一个GameObject
访问此类,因此如何仅通过知道gameObj
变量来访问gameObj
?
更新,我将添加用于生成Obstacle类的脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpawnStars : MonoBehaviour
{
[SerializeField]
private List<Obstacle> obstacles;
[HideInInspector]
public List<Obstacle> normalStarsPool = new List<Obstacle>();
[SerializeField]
private List<Obstacle> otherObstacles;
[HideInInspector]
public List<Obstacle> otherObstaclesPool;
[SerializeField]
private int spawnNumber = 2;
private Obstacle nextObstacleToSpawn;
[SerializeField]
public GameObject panel;
public static bool spawnNow = true;
public static bool first_find_star = true;
public static float starSpeed;
/* this variables will make the stars to spawn closer and closer to the player as
the score is progresing*/
public static float closerToPlayer;
private float spawnPositionZ;
private void Start()
{
first_find_star = true;
spawnNow = true;
GeneratePrefabs(spawnNumber, obstacles, normalStarsPool);
StartCoroutine(ShuffleList(normalStarsPool));
GeneratePrefabs(2, otherObstacles, otherObstaclesPool);
StartCoroutine(ShuffleList(otherObstaclesPool));
}
private void LateUpdate()
{
if (spawnNow)
{
spawnNow = false;
if (first_find_star)
{
nextObstacleToSpawn = FindStar(normalStarsPool);
first_find_star = false;
}
//spawn the current star
int randomNumber = Random.Range(0, 100);
if(randomNumber >= 20){
nextObstacleToSpawn = FindStar(normalStarsPool);
}
else{
Debug.Log("corrupt star");
nextObstacleToSpawn = FindStar(otherObstacles);
}
SpawnStar(nextObstacleToSpawn);
}
}
void GeneratePrefabs(int how_many, List<Obstacle> prefabList, List<Obstacle> poolList)
{
foreach (Obstacle prefab in prefabList)
{
for (int i = 0; i <= how_many; i++)
{
Obstacle go = new Obstacle
{
gameObj = Instantiate(prefab.gameObj)
};
go.regular_Trail = go.gameObj.transform.GetChild(1).gameObject;
go.starExplosion = go.gameObj.transform.GetChild(0).gameObject;
go.color = prefab.color;
go.gameObj.SetActive(false);
//setap all the colors for the obstacle
ParticleSystem ps = go.starExplosion.GetComponent<ParticleSystem>();
ParticleSystem.MainModule psmain = ps.main;
psmain.startColor = go.color;
//setup the collor of a partycle system
ps = go.starExplosion.GetComponent<ParticleSystem>();
psmain = ps.main;
psmain.startColor = go.color;
psmain.startColor = go.color;
go.gameObj.GetComponent<Renderer>().material.color = go.color;
poolList.Add(go);
}
}
}
Obstacle FindStar(List<Obstacle> poolList)
{
while (true)
{
int randomIndex = Random.Range(0, poolList.Count);
if (!poolList[randomIndex].gameObj.activeInHierarchy)
{
Color color = poolList[randomIndex].color;
color.a = 0.5f;
panel.GetComponent<Renderer>().material.color = color;
return poolList[randomIndex];
}
else randomIndex = Random.Range(0, poolList.Count);
}
}
void SpawnStar(Obstacle star)
{
star.firstCollistion = false;
star.starExplosion.SetActive(false);
star.regular_Trail.SetActive(true);
star.gameObj.GetComponent<MeshRenderer>().enabled = true;
ScaleDifficulty();
star.gameObj.transform.position = Obstacle.SpawnLocation();
star.gameObj.SetActive(true);
}
//Shuffle a list every 4 seconds, don't pus this in an update or something cuz it's a coroutine
IEnumerator ShuffleList(List<Obstacle> list_to_Shuffle)
{
while (true)
{
yield return new WaitForSeconds(4f);
for (int i = 0; i < list_to_Shuffle.Count; i++)
{
Obstacle temp = list_to_Shuffle[i];
int randomIndex = Random.Range(i, list_to_Shuffle.Count);
list_to_Shuffle[i] = list_to_Shuffle[randomIndex];
list_to_Shuffle[randomIndex] = temp;
}
}
}
//this will scale the difficulty as the score get's higher and higher
public void ScaleDifficulty()
{
if (Menu.score < 60)
{
//the speed of the star as the score goes up
starSpeed = ((float)Menu.score / 30) + 1f;
//how close relative to the player will the stars spawn in the x and y axis?
closerToPlayer += Menu.score / 60;
// Debug.Log(starSpeed);
}
}
}
如您所见,我通过这种方法生成了Obstacle对象:
void GeneratePrefabs(int how_many, List<Obstacle> prefabList, List<Obstacle> poolList)
{
foreach (Obstacle prefab in prefabList)
{
for (int i = 0; i <= how_many; i++)
{
Obstacle go = new Obstacle
{
gameObj = Instantiate(prefab.gameObj)
};
go.regular_Trail = go.gameObj.transform.GetChild(1).gameObject;
go.starExplosion = go.gameObj.transform.GetChild(0).gameObject;
go.color = prefab.color;
go.gameObj.SetActive(false);
//setap all the colors for the obstacle
ParticleSystem ps = go.starExplosion.GetComponent<ParticleSystem>();
ParticleSystem.MainModule psmain = ps.main;
psmain.startColor = go.color;
//setup the collor of a partycle system
ps = go.starExplosion.GetComponent<ParticleSystem>();
psmain = ps.main;
psmain.startColor = go.color;
psmain.startColor = go.color;
go.gameObj.GetComponent<Renderer>().material.color = go.color;
poolList.Add(go);
}
}
}
现在,在另一个脚本中,我需要访问此gameObj实例所在的Obstacle类的实例。
给定一个Obstacle
类的实例,您怎么甚至不知道GameObject
实例完全引用了它? 或者您怎么知道它仅被一个 GameObject?
引用GameObject?
除非有双向引用GameObject
对Obstacle
的引用,而Obstacle
也对GameObject
的引用-无法确定引用Obstacle
实例的对象。
简而言之,你不能。 不是您设置的方式。 如果需要全局访问该对象,则需要全局跟踪它。 Unity提供了一种方法(本质上是Service Locator模式 ),但是您已经说过不想使用它。 因此,您将必须构建自己的。
假设您有一个Obstacle
对象的集合,例如IList<Obstacle> obstacles
,则可以通过obstacles.Where(o => o.gameObj == myLocalGameObjReference)
来获取它。 更好的解决方案,假设你有这个脚本附1:1为每个Obstacle
将是简单的注入Obstacle
到脚本。 查看类似Zenject的依赖项注入(DI)框架,以帮助配置和管理依赖项。 另一种选择是单例模式 。 就个人而言,我会选择DI而不是单例。 一开始,单例似乎比较容易,但是您很快就会遇到麻烦。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.