我想实现:给一组坐标,轮流读取这些坐标,每次读到新坐标时物体就在此刻的坐标生成,同时上次生成的物体消失。
using UnityEngine;
public class CoordinateSpawner : MonoBehaviour
{
public GameObject Prefab;
public Vector3[] coordinates;
private GameObject lastInstance;
void Start()
{
// 循环遍历坐标数组
foreach (Vector3 coord in coordinates)
{
// 如果 lastInstance 不为空,则销毁它
if (lastInstance != null)
{
Destroy(lastInstance);
}
// 在 coord 处实例化 Prefab 的副本
lastInstance = Instantiate(Prefab, coord, Quaternion.identity);
}
}
}
望采纳
望采纳
要实现这个效果,你可以创建一个脚本,定时读取当前的坐标并创建物体。你可以使用 InvokeRepeating 方法来定时调用函数,如下所示:
using UnityEngine;
public class Spawner : MonoBehaviour
{
// 物体预制
public GameObject prefab;
// 生成物体的间隔(秒)
public float interval = 1.0f;
void Start()
{
// 每隔 interval 秒调用一次 SpawnObject 函数
InvokeRepeating("SpawnObject", 0, interval);
}
void SpawnObject()
{
// 在当前坐标生成物体
Instantiate(prefab, transform.position, Quaternion.identity);
}
}
上述代码中,我们在 Start 函数中调用 InvokeRepeating 方法来定时调用 SpawnObject 函数。每当 SpawnObject 函数被调用时,它会在当前坐标生成一个新的物体。
为了让上一次生成的物体消失,可以在生成新物体之前先销毁之前的物体。这可以通过让 SpawnObject 函数维护一个变量来存储当前生成的物体,然后在生成新物体之前销毁之前的物体,如下所示:
using UnityEngine;
public class Spawner : MonoBehaviour
{
// 物体预制
public GameObject prefab;
// 生成物体的间隔(秒)
public float interval = 1.0f;
// 当前生成的物体
private GameObject currentObject;
void Start()
{
// 每隔 interval 秒调用一次 SpawnObject 函数
InvokeRepeating("SpawnObject", 0, interval);
}
void SpawnObject()
{
// 销毁之前生成的物体
if (currentObject != null)
{
Destroy(currentObject);
}
// 在当前坐标生成物体
currentObject = Instantiate(prefab, transform.position, Quaternion.identity);
}
}
在这段代码中,我们在 SpawnObject 函数中维护了一个变量 currentObject 来存储当前生成的物体。每当 SpawnObject 函数被调用时,它会先销毁之前的物体,然后再在当前坐标生成新的物体。
unity 地图物体的随机生成
对一些2d游戏反复用一个关卡,但不希望每次的地图中物体出现的都一样,这就需要用到随机生成地图的方法;怪物也是如此;
首先要得到各种预制体;
如
public GameObject[] OutwallArray;
public GameObject[] leaArray;
public GameObject[] wallArray;
public GameObject[] foodPrefab;
public GameObject[] enemyPrefab;
public GameObject ExitPrefab;
当然我只是举个例子;
最关键的就是要定义一个队列
private List<Vector2> wallList = new List<Vector2>();
关于坐标的队列;
wallList.Clear();
for(int x=2;x<cols-2;x++)
{
for(int y=2;y<rows-2;y++)
{
wallList.Add(new Vector2(x, y));
}
}
首先要将他清空,因为每次都要用这个队列,然后就是要将你所需要产生物体的平面坐标范围内加入到队列当中;
private Vector2 RandomPosition()
{
int Index = Random.Range(0, wallList.Count);
Vector2 pos = wallList[Index];
wallList.RemoveAt(Index);
return pos;
}
这是一个从队列当中随机产生一个索引给与你想要产生的物体,这样它的坐标就会随机产生且不会重复;
例子:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class TestRoomJudget : MonoBehaviour {
#region
//摄像机朝向的目标模型
public Transform target;//玩家操控 的 人物
public GameObject BaseWall;//基础墙壁
int leng = 10;//向量坐标 长度
float posx;//物体 坐标X,Y,Z
float posy;
float posz;
float scalx;
float scaly;
float scalz;
Vector3 dirX;//6个方向的向量
Vector3 dirX_;
Vector3 dirY;
Vector3 dirY_;
Vector3 dirZ;
Vector3 dirZ_;
Vector3 A1;
Vector3 A2;
Vector3 A3;
Vector3 A4;
Vector3 B1;
Vector3 B2;
Vector3 B3;
Vector3 B4;
float unitlength1;//墙壁 的单位长度
float unitlength2;//一半 的单位长度
float Yf;
private Transform maincamera;//找到 主摄像机
#endregion
// Use this for initialization
void Start ()
{
maincamera = GameObject.Find("Main Camera").transform;//找到 主摄像机
unitlength1 = target.transform.lossyScale.x;// Debug.DrawLine(transform.position, PCube.transform.position, Color.green);//Debug.DrawLine(ray.origin, hit.point, Color.green);
unitlength2 = target.transform.lossyScale.x/2;
posx = transform.position.x; posy = transform.position.y; posz = transform.position.z;
//Debug.DrawLine(transform.position, transform.position + new Vector3(1,0,0), Color.red);
//new Vector3(maincamera.position.x,target.transform.position.y,maincamera.position.z);
dirX = new Vector3(posx + leng, posy, posz);
dirX_ = new Vector3(posx - leng, posy, posz);
dirY = new Vector3(posx, posy + leng, posz);
dirY_ = new Vector3(posx, posy - leng, posz);
dirZ = new Vector3(posx, posy, posz + leng);
dirZ_ = new Vector3(posx, posy, posz - leng);
scalx = transform.localScale.x / 2;
scaly = transform.localScale.y / 2;
scalz = transform.localScale.z / 2;
A1 = new Vector3(posx + scalx, posy + scaly, posz - scalz);
A2 = new Vector3(posx + scalx,posy + scaly, posz + scalz);
A3 = new Vector3(posx - scalx,posy + scaly, posz + scalz);
A4 = new Vector3(posx - scalx,posy + scaly, posz - scalz);
B1 = new Vector3(posx + scalx, posy - scaly, posz - scalz);
B2 = new Vector3(posx + scalx, posy - scaly, posz + scalz);
B3 = new Vector3(posx - scalx, posy - scaly, posz + scalz);
B4 = new Vector3(posx - scalx, posy - scaly, posz - scalz);
/*JudgetDirWall(dirX);
JudgetDirWall(dirX_);
JudgetDirWall(dirY);
JudgetDirWall(dirY_);
JudgetDirWall(dirZ);
JudgetDirWall(dirZ_);*/
//Test();
/*
Debug.Log("A1-A2");
InstantiateWall_XZ(A1,A2);// varv1 - varv2
Debug.Log("A2-A3");
InstantiateWall_XZ(A2,A3);// varv1 - varv2
Debug.Log("A4-A3");
InstantiateWall_XZ(A3, A4);// varv1 - varv2
Debug.Log("A1-A4");
InstantiateWall_XZ(A4, A1);// varv1 - varv2
Debug.Log("B1-B2");
InstantiateWall_XZ(B1, B2);// varv1 - varv2
Debug.Log("B2-B3");
InstantiateWall_XZ(B2, B3);// varv1 - varv2
Debug.Log("B4-B3");
InstantiateWall_XZ(B4, B3);// varv1 - varv2
Debug.Log("B1-B4");
InstantiateWall_XZ(B1, B4);// varv1 - varv2
*/
InstantiateWall_Y();
}
private void Update()
{
Debug.DrawLine(maincamera.position, target.position, Color.red);
Debug.DrawLine(new Vector3(maincamera.position.x, target.transform.position.y, maincamera.position.z), target.position, Color.green);
// Test();
}
void InstantiateWall_Y()
{
float Ynum = transform.localScale.y / unitlength1;//标记点 的 Y轴长度 / 墙壁单位长度 = Y轴生成的数量
Debug.Log("Ynum "+ Ynum);
for(int k = 0; k<Ynum;k++)
{//new Vector3(posx - scalx, posy + scaly -, posz - scalz);为最上面平面上的 A1 点
//向下每隔 一个墙壁 单位 的 Y轴长度 ,为平面 A1-A2-A3-A4 执行生成墙壁的指令
Yf = posy + scaly; //Debug.Log("Yf " + Yf); Debug.Log("unitlength1 " + unitlength1); Debug.Log("k " + k);
Vector3 YWall_1 = new Vector3(posx + scalx, Yf - (unitlength2 + k * unitlength1), posz - scalz);//unitlength1 = target.transform.lossyScale.x
Vector3 YWall_2 = new Vector3(posx + scalx, Yf - (unitlength2 + k * unitlength1), posz + scalz);
Vector3 YWall_3 = new Vector3(posx - scalx, Yf - (unitlength2 + k * unitlength1), posz + scalz);
Vector3 YWall_4 = new Vector3(posx - scalx, Yf - (unitlength2 + k * unitlength1), posz - scalz);
InstantiateWall_XZ(YWall_1, YWall_2 , k);
InstantiateWall_XZ(YWall_2, YWall_3 , k);
InstantiateWall_XZ(YWall_3, YWall_4 , k);
InstantiateWall_XZ(YWall_4, YWall_1 , k);
}//
}//
void InstantiateWall_XZ(Vector3 varv1,Vector3 varv2,int g)// varv1 - varv2 X,Z平面判断
{
Vector3 testV = varv1 - varv2;//两个点相减 的矢量V
Debug.Log("两点相减向量 varv1" + varv1 + " " + " varv2 " + varv2 + " " );
//Debug.Log("两点相减向量 testV.x" + testV.x + " " + "testV.y" + testV.y + " " + "testV.z" + testV.z);
float[] f = new float[3] { testV.x, testV.y, testV.z};//矢量V 的XYZ坐标
string[] fs = new string[3] { "testV.x", "testV.y", "testV.z" };//矢量V 的XYZ坐标 的名字
float ff;//表达 要生成 的 基础 墙壁 的数量
Vector3 v = new Vector3(1,1,1);//判断 方向 的生成 向量
if (testV.x == 0 || testV.y == 0 || testV.z == 0 )
{
// float jx = 1;
// float jy = 1;
// float jz = 1;
float jx = (float)((varv1.x - posx) / scalx);//判断大小方向
float jy = (float)((varv1.y - posy) / scaly);
float jz = (float)((varv1.z - posz) / scalz);
// Debug.Log("********testV.x " + testV.x+ "********testV.y " + testV.y+ "********testV.z " + testV.z);
if (testV.x * v.x != 0)
{
ff = Mathf.Abs(testV.x);//表达 要生成 的 基础 墙壁 的数量 绝对值
ff = Mathf.Round(ff);//表达 要生成 的 基础 墙壁 的数量 四舍五入
//float jx = (float)((varv1.x - posx) / scalx);//判断大小方向
//float jy = (float)((varv1.y - posy) / scaly);
//float jz = (float)((varv1.z - posz) / scalz);
// Debug.Log("---varv1.x" + varv1.x);
// Debug.Log("---posx" + posx);
// Debug.Log("---varv1.x - posx " + (varv1.x - posx));
// Debug.Log("---posx" + posx);
// Debug.Log("---scalx" + scalx);
//Debug.Log("墙长度 ffx" + ff + " " + "jXx" + jx + " " + "jXy" + jy + " " + "jXz" + jz);
//X方向创建 ff个
for (int j = 0; j<ff; j++)
{//varv1.y - jy * ((float)0.5 + jy * j * 1)
Debug.Log("---jy " + jy);
GameObject GO_X = Instantiate(BaseWall, new Vector3(varv1.x - jx*(unitlength2 + j * unitlength1), varv1.y, varv1.z - jz * unitlength2), Quaternion.identity);
Debug.Log("varv1.y - jy * unitlength2" + (varv1.y - jy * unitlength2) + " " );
//GO_X.transform.parent = transform;
}//
}//
if (testV.y * v.y != 0)
{
ff = Mathf.Abs(testV.y);//表达 要生成 的 基础 墙壁 的数量 绝对值
ff = Mathf.Round(ff);//表达 要生成 的 基础 墙壁 的数量 四舍五入
//float jx = (float)((varv1.x - posx) / scalx);//判断大小方向
//float jy = (float)(((varv1.y - posy) / scaly)+g * unitlength1);
//float jz = (float)((varv1.z - posz) / scalz);
/*if (jx == 0)
jx = 1;
if (jy == 0)
jy = 1;
if (jz == 0)
jz = 1;*/
// Debug.Log("墙长度 ffy" + ff + " " + "jXx" + jx + " " + "jXy" + jy + " " + "jXz" + jz);
//X方向创建 ff个
for (int j = 0; j < ff; j++)
{
GameObject GO_Y= Instantiate(BaseWall, new Vector3(varv1.x - jx * unitlength2, varv1.y, varv1.z - jz * unitlength2), Quaternion.identity);
Debug.Log("66666666 " +(varv1.y - jy * (unitlength2 + j * unitlength1)) + " ");
// GO_Y.transform.parent = transform;
}//
}//
if (testV.z * v.z != 0)
{
ff = Mathf.Abs(testV.z);//表达 要生成 的 基础 墙壁 的数量 绝对值
ff = Mathf.Round(ff);//表达 要生成 的 基础 墙壁 的数量 四舍五入
//Debug.Log("---varv1.x" + varv1.x);
//Debug.Log("---posx" + posx);
// Debug.Log("---varv1.x - posx " + (varv1.x - posx));
// Debug.Log("---posx" + posx);
// Debug.Log("---scalx" + scalx);
// Debug.Log("varv1.x - posx" + (varv1.x - posx));
// Debug.Log("墙长度 ffz" + ff + " " + "jXx" + jx + " " + "jXy" + jy + " " + "jXz" + jz);
//X方向创建 ff个
for (int j = 0; j < ff; j++)
{
GameObject GO_Z = Instantiate(BaseWall, new Vector3(varv1.x - jx * unitlength2, varv1.y, varv1.z - jz * (unitlength2 + j * unitlength1)), Quaternion.identity);
Debug.Log("varv1.y - jy * unitlength2" + (varv1.y - jy * unitlength2) + " ");
//GO_Z.transform.parent = transform;
}//
}//
}//
//new Vector3(transform.position.x + transform.localScale.x / 2, transform.position.y + transform.localScale.y / 2, transform.position.z + transform.localScale.z / 2);
//Instantiate(BaseWall, new Vector3(1, 1, 1), Quaternion.identity);
}//
void OnDrawGizmos()//画一个立方体,用于判断这个 孵化器 的范围
{
#if UNITY_EDITOR
Gizmos.color = Color.blue;//栏线
Gizmos.DrawLine(transform.position, dirX);
Gizmos.DrawLine(transform.position, dirX_);
//Gizmos.DrawSphere(A1, (float)0.5);
//Gizmos.DrawSphere(A2, (float)0.5);
Gizmos.color = Color.green;//绿线
Gizmos.DrawLine(transform.position, dirY);
Gizmos.DrawLine(transform.position, dirY_);
//Gizmos.DrawSphere(A3, (float)0.5);
// Gizmos.DrawSphere(A4, (float)0.5);
// Gizmos.DrawSphere(B4, (float)0.5);
Gizmos.color = Color.black;//黑线
Gizmos.DrawLine(transform.position, dirZ);
Gizmos.DrawLine(transform.position, dirZ_);
//Gizmos.DrawSphere(B1, (float)0.5);
//Gizmos.DrawSphere(B2, (float)0.5);
//Gizmos.DrawSphere(B3, (float)0.5);
Gizmos.color = Color.red;//红线
Gizmos.DrawSphere(transform.position, (float)0.5);//描述:用在transform.position绘制一个大小为2绘制一个球体.
Gizmos.DrawWireCube(transform.position, this.transform.localScale);// 描述:用transform.position和this.transform.localScale绘制一个线框立方体.
Handles.Label(transform.position, "Room Wall Judget");//在transform.position位置 绘制一个"Enemy Spawner"的文本
//handles.label需要下面撒谎那个行作为头文件
//#if UNITY_EDITOR
//using UnityEditor;
//#endif
#endif
}
void JudgetDirWall(Vector3 dirV)//判断6个方向的墙壁
{
RaycastHit hit;
if (Physics.Linecast(target.position, dirV, out hit))
{
string tagname = hit.collider.gameObject.tag;
if (tagname != "MainCamera" && tagname != "terrain")
{
if (tagname == "Wall")//如果 碰撞到墙壁,使其透明
{
hit.collider.gameObject.GetComponent<MeshRenderer>().enabled = false;
}//
}//
}//
}//
void Test()
{
Debug.Log("1");
RaycastHit hit1;
RaycastHit hit2;
if (Physics.Linecast(maincamera.position, target.position, out hit1))
{
string tagname1 = hit1.collider.gameObject.tag;
if (tagname1 != "MainCamera" && tagname1 != "terrain")
{
if (tagname1 == "Wall")//如果 碰撞到墙壁,使其透明
{
hit1.collider.gameObject.GetComponent<MeshRenderer>().enabled = false;
}//
}//
Vector3 CameraToTarget = new Vector3(maincamera.position.x, target.transform.position.y, maincamera.position.z);
if (Physics.Linecast(CameraToTarget, target.position, out hit2))
{
Debug.Log("111");
string tagname2 = hit2.collider.gameObject.tag;
if (tagname2 != "MainCamera" && tagname2 != "terrain")
{
if (tagname2 == "Wall")//如果 碰撞到墙壁,使其透明
{
hit2.collider.gameObject.GetComponent<MeshRenderer>().enabled = false;
}//
}//
}//
}//
}
}//