C# 如何使用range属性添加更多新的实例化对象或删除对象? 使用系统; 使用UnityEngine; 使用Random=UnityEngine.Random; 使用系统集合; 使用System.Collections.Generic; 使用System.Linq; [执行方式] 公共类克隆对象:单一行为 { 公共地形; 公共游戏对象预制; 公共游戏对象父对象; [射程(101000)] 公共物品; 公共浮动Y偏移=10f; 私有浮动地形宽度; 私人浮动平台长度; 私人浮动xTerrainPos; 私人浮动zTerrainPos; void Start() { //获取地形大小 terrainWidth=terrain.terrainData.size.x; terrainLength=terrain.terrainData.size.z; //获取地形位置 xTerrainPos=terrain.transform.position.x; zTerrainPos=地形.transform.position.z; generateObjectInterrain(); } void generateObjectInterrain() { for(int i=0;inumberOfObjects) { if(Application.isPlaying) { //由于销毁延迟完成,我们必须使用修复循环 对于(var i=parent.transform.childCount;i>numberOfObjects;i--) { 销毁(parent.transform.GetChild(0.gameObject); } } 其他的 { //但立即执行则立即如此 //在这里,我们可以直接依赖childCount while(parent.transform.childCount>numberOfObjects) { DestroyImmediate(parent.transform.GetChild(0.gameObject)); } } } while(parent.transform.childCount
我希望如果我在编辑器中以编辑模式或运行时模式移动numberOfObjects范围到右侧,添加新的实例化对象,例如,如果有100个对象,我将范围滑块向右移动到300,然后添加200多个新对象。C# 如何使用range属性添加更多新的实例化对象或删除对象? 使用系统; 使用UnityEngine; 使用Random=UnityEngine.Random; 使用系统集合; 使用System.Collections.Generic; 使用System.Linq; [执行方式] 公共类克隆对象:单一行为 { 公共地形; 公共游戏对象预制; 公共游戏对象父对象; [射程(101000)] 公共物品; 公共浮动Y偏移=10f; 私有浮动地形宽度; 私人浮动平台长度; 私人浮动xTerrainPos; 私人浮动zTerrainPos; void Start() { //获取地形大小 terrainWidth=terrain.terrainData.size.x; terrainLength=terrain.terrainData.size.z; //获取地形位置 xTerrainPos=terrain.transform.position.x; zTerrainPos=地形.transform.position.z; generateObjectInterrain(); } void generateObjectInterrain() { for(int i=0;inumberOfObjects) { if(Application.isPlaying) { //由于销毁延迟完成,我们必须使用修复循环 对于(var i=parent.transform.childCount;i>numberOfObjects;i--) { 销毁(parent.transform.GetChild(0.gameObject); } } 其他的 { //但立即执行则立即如此 //在这里,我们可以直接依赖childCount while(parent.transform.childCount>numberOfObjects) { DestroyImmediate(parent.transform.GetChild(0.gameObject)); } } } while(parent.transform.childCount,c#,unity3d,C#,Unity3d,我希望如果我在编辑器中以编辑模式或运行时模式移动numberOfObjects范围到右侧,添加新的实例化对象,例如,如果有100个对象,我将范围滑块向右移动到300,然后添加200多个新对象。 如果我将滑块向左移动,例如,有100个对象,我将其向左移动到70个,然后删除30个对象,或者如果我先将其向右移动,添加了200个对象,现在有300个,然后向左移动到221个,则删除所需数量的对象。代码中已经有一半可能的解决方案。您正在使用ExecuteAlways属性,并且正在使用for循环实例化对象。下
如果我将滑块向左移动,例如,有100个对象,我将其向左移动到70个,然后删除30个对象,或者如果我先将其向右移动,添加了200个对象,现在有300个,然后向左移动到221个,则删除所需数量的对象。代码中已经有一半可能的解决方案。您正在使用
ExecuteAlways
属性,并且正在使用for循环实例化对象。下一步是将返回的对象intance放入数组中。这样,当for循环的当前迭代结束时,对游戏对象的访问不会永远丢失
using System;
using UnityEngine;
using Random = UnityEngine.Random;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
[ExecuteAlways]
public class CloneObjects : MonoBehaviour
{
public Terrain terrain;
public GameObject prefab;
public GameObject parent;
[Range(10, 1000)]
public int numberOfObjects;
public float yOffset = 10f;
private float terrainWidth;
private float terrainLength;
private float xTerrainPos;
private float zTerrainPos;
void Start()
{
//Get terrain size
terrainWidth = terrain.terrainData.size.x;
terrainLength = terrain.terrainData.size.z;
//Get terrain position
xTerrainPos = terrain.transform.position.x;
zTerrainPos = terrain.transform.position.z;
generateObjectOnTerrain();
}
void generateObjectOnTerrain()
{
for (int i = 0; i < numberOfObjects; i++)
{
//Generate random x,z,y position on the terrain
float randX = UnityEngine.Random.Range(xTerrainPos, xTerrainPos + terrainWidth);
float randZ = UnityEngine.Random.Range(zTerrainPos, zTerrainPos + terrainLength);
float yVal = Terrain.activeTerrain.SampleHeight(new Vector3(randX, 0, randZ));
//Apply Offset if needed
yVal = yVal + yOffset;
//Generate the Prefab on the generated position
GameObject objInstance = Instantiate(prefab, new Vector3(randX, yVal, randZ), Quaternion.identity);
objInstance.name = "Waypoint";
objInstance.tag = "Waypoint";
objInstance.transform.parent = parent.transform;
}
}
}
一旦你拥有了你的GameObject[]objects
游戏对象数组,你可以在你的类的update()
方法中更新它:禁用索引大于你的numberOfObjects
的所有对象,启用其余的。由于Update()
不会在游戏未运行时每帧调用一次,而只是在场景发生变化时调用,因此您不应该出现性能问题。但当你处于游戏模式时,每帧检查多达1000个游戏对象可能需要一些时间,所以你要记住这一点。你可以这样做:
objects[i] = Instantiate(/*...*/);
objects[i].name = "Waypoint";
/*...*/
注:当问下一个答案时,请在你的回答中加入表明你在解决问题上付出了努力的内容,而不是使用
[始终执行]
和更新
,你更应该在
在Inspector中加载脚本或更改值时调用此函数(仅在编辑器中调用)
然后您需要一些东西来跟踪已经创建的对象。由于您将它们都设置为parent
的子级,因此只需检查其
父变换具有的子级数
所以你可以这样做
private void Update() {
if (!Application.isPlaying) {
//Update array
}
}
private void OnValidate()
{
if(parent.transform.childCount>numberOfObjects)
{
if(Application.isPlaying)
{
//由于销毁延迟完成,我们必须使用修复循环
对于(var i=parent.transform.childCount;i>numberOfObjects;i--)
{
销毁(parent.transform.GetChild(0.gameObject);
}
}
其他的
{
//但立即执行则立即如此
//在这里,我们可以直接依赖childCount
while(parent.transform.childCount>numberOfObjects)
{
DestroyImmediate(parent.transform.GetChild(0.gameObject));
}
}
}
while(parent.transform.childCount
private void OnValidate()
{
if(parent.transform.childCount > numberOfObjects)
{
if(Application.isPlaying)
{
// Since destroy is done delayed we have to use a fix loop
for(var i = parent.transform.childCount; i > numberOfObjects; i--)
{
Destroy(parent.transform.GetChild(0).gameObject);
}
}
else
{
// DestroyImmediate however is executed immediately so
// here we can simply rely on the childCount directly
while(parent.transform.childCount > numberOfObjects)
{
DestroyImmediate(parent.transform.GetChild(0).gameObject);
}
}
}
while(parent.transform.childCount < numberOfObjects)
{
//Generate random x,z,y position on the terrain
var randX = UnityEngine.Random.Range(xTerrainPos, xTerrainPos + terrainWidth);
var randZ = UnityEngine.Random.Range(zTerrainPos, zTerrainPos + terrainLength);
var yVal = Terrain.activeTerrain.SampleHeight(new Vector3(randX, 0, randZ));
//Apply Offset if needed
yVal = yVal + yOffset;
//Generate the Prefab on the generated position
var objInstance = Instantiate(prefab, new Vector3(randX, yVal, randZ), Quaternion.identity);
objInstance.name = "Waypoint";
objInstance.tag = "Waypoint";
objInstance.transform.parent = parent.transform;
}
}