视锥剔除
This commit is contained in:
parent
f0f5812b70
commit
448c52083e
|
|
@ -244,7 +244,7 @@ PrefabInstance:
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: -7511558181221131132, guid: 51c3521496de1854697d5682cc43afe5, type: 3}
|
- target: {fileID: -7511558181221131132, guid: 51c3521496de1854697d5682cc43afe5, type: 3}
|
||||||
propertyPath: m_Enabled
|
propertyPath: m_Enabled
|
||||||
value: 0
|
value: 1
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 919132149155446097, guid: 51c3521496de1854697d5682cc43afe5, type: 3}
|
- target: {fileID: 919132149155446097, guid: 51c3521496de1854697d5682cc43afe5, type: 3}
|
||||||
propertyPath: m_Name
|
propertyPath: m_Name
|
||||||
|
|
@ -252,7 +252,7 @@ PrefabInstance:
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 919132149155446097, guid: 51c3521496de1854697d5682cc43afe5, type: 3}
|
- target: {fileID: 919132149155446097, guid: 51c3521496de1854697d5682cc43afe5, type: 3}
|
||||||
propertyPath: m_IsActive
|
propertyPath: m_IsActive
|
||||||
value: 1
|
value: 0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
m_RemovedComponents: []
|
m_RemovedComponents: []
|
||||||
m_SourcePrefab: {fileID: 100100000, guid: 51c3521496de1854697d5682cc43afe5, type: 3}
|
m_SourcePrefab: {fileID: 100100000, guid: 51c3521496de1854697d5682cc43afe5, type: 3}
|
||||||
|
|
@ -319,7 +319,7 @@ PrefabInstance:
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: -7511558181221131132, guid: 0fc9aae39f3b8fd45959b9f2e382a854, type: 3}
|
- target: {fileID: -7511558181221131132, guid: 0fc9aae39f3b8fd45959b9f2e382a854, type: 3}
|
||||||
propertyPath: m_Enabled
|
propertyPath: m_Enabled
|
||||||
value: 0
|
value: 1
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 919132149155446097, guid: 0fc9aae39f3b8fd45959b9f2e382a854, type: 3}
|
- target: {fileID: 919132149155446097, guid: 0fc9aae39f3b8fd45959b9f2e382a854, type: 3}
|
||||||
propertyPath: m_Name
|
propertyPath: m_Name
|
||||||
|
|
@ -327,7 +327,7 @@ PrefabInstance:
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 919132149155446097, guid: 0fc9aae39f3b8fd45959b9f2e382a854, type: 3}
|
- target: {fileID: 919132149155446097, guid: 0fc9aae39f3b8fd45959b9f2e382a854, type: 3}
|
||||||
propertyPath: m_IsActive
|
propertyPath: m_IsActive
|
||||||
value: 1
|
value: 0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
m_RemovedComponents: []
|
m_RemovedComponents: []
|
||||||
m_SourcePrefab: {fileID: 100100000, guid: 0fc9aae39f3b8fd45959b9f2e382a854, type: 3}
|
m_SourcePrefab: {fileID: 100100000, guid: 0fc9aae39f3b8fd45959b9f2e382a854, type: 3}
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ RectTransform:
|
||||||
m_AnchorMin: {x: 0, y: 1}
|
m_AnchorMin: {x: 0, y: 1}
|
||||||
m_AnchorMax: {x: 1, y: 1}
|
m_AnchorMax: {x: 1, y: 1}
|
||||||
m_AnchoredPosition: {x: 0, y: 0.00018310547}
|
m_AnchoredPosition: {x: 0, y: 0.00018310547}
|
||||||
m_SizeDelta: {x: 0, y: 0}
|
m_SizeDelta: {x: -236, y: 12}
|
||||||
m_Pivot: {x: 0, y: 1}
|
m_Pivot: {x: 0, y: 1}
|
||||||
--- !u!114 &235241195840539889
|
--- !u!114 &235241195840539889
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
|
|
@ -633,7 +633,7 @@ RectTransform:
|
||||||
m_AnchorMin: {x: 0, y: 1}
|
m_AnchorMin: {x: 0, y: 1}
|
||||||
m_AnchorMax: {x: 1, y: 1}
|
m_AnchorMax: {x: 1, y: 1}
|
||||||
m_AnchoredPosition: {x: 0, y: 0}
|
m_AnchoredPosition: {x: 0, y: 0}
|
||||||
m_SizeDelta: {x: 0, y: 0}
|
m_SizeDelta: {x: 17, y: 940}
|
||||||
m_Pivot: {x: 0, y: 1}
|
m_Pivot: {x: 0, y: 1}
|
||||||
--- !u!114 &6919009669462823272
|
--- !u!114 &6919009669462823272
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
|
|
@ -900,9 +900,9 @@ RectTransform:
|
||||||
m_Father: {fileID: 5924775712395334843}
|
m_Father: {fileID: 5924775712395334843}
|
||||||
m_RootOrder: 0
|
m_RootOrder: 0
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
m_AnchorMin: {x: 0, y: 0}
|
m_AnchorMin: {x: 0, y: 1}
|
||||||
m_AnchorMax: {x: 0, y: 0}
|
m_AnchorMax: {x: 0, y: 1}
|
||||||
m_AnchoredPosition: {x: 0, y: 0}
|
m_AnchoredPosition: {x: 804, y: 0}
|
||||||
m_SizeDelta: {x: 1608, y: 940}
|
m_SizeDelta: {x: 1608, y: 940}
|
||||||
m_Pivot: {x: 0.5, y: 1}
|
m_Pivot: {x: 0.5, y: 1}
|
||||||
--- !u!222 &6109062945893642881
|
--- !u!222 &6109062945893642881
|
||||||
|
|
|
||||||
|
|
@ -5,68 +5,87 @@ using UnityEngine;
|
||||||
|
|
||||||
public class SorghumFieldController : MonoBehaviour
|
public class SorghumFieldController : MonoBehaviour
|
||||||
{
|
{
|
||||||
|
// 原有字段保持不变
|
||||||
public MeshRenderer fieldArea;
|
public MeshRenderer fieldArea;
|
||||||
//public GameObject SorghumPrefab;
|
|
||||||
public bool randomRotate = false;
|
public bool randomRotate = false;
|
||||||
public float rowDistance = 1;
|
public float rowDistance = 1;
|
||||||
public float strainDistance = 1;
|
public float strainDistance = 1;
|
||||||
public float diseasedRate = 0;
|
public float diseasedRate = 0;
|
||||||
|
|
||||||
public void InitSorghum(float RowDistance, float StrainDistance, float DiseasedRate, bool RandomRotate = false)
|
// 新增动态渲染相关字段
|
||||||
{
|
[Header("Dynamic Rendering")]
|
||||||
|
public int chunksPerAxis = 10; // 每轴区块数量
|
||||||
|
private Dictionary<Vector2Int, List<GameObject>> chunkMap = new Dictionary<Vector2Int, List<GameObject>>();
|
||||||
|
private float chunkSize;
|
||||||
|
private Bounds fieldBounds;
|
||||||
|
|
||||||
GameObject SorghumPrefab = Resources.Load<GameObject>("Prefabs/高粱预制体");
|
public void InitSorghum(float rowDistance, float strainDistance, float diseasedRate, bool randomRotate = false)
|
||||||
if (SorghumPrefab == null || fieldArea == null)
|
{
|
||||||
|
GameObject sorghumPrefab = Resources.Load<GameObject>("Prefabs/高粱预制体");
|
||||||
|
if (sorghumPrefab == null || fieldArea == null)
|
||||||
{
|
{
|
||||||
Debug.LogError("预制体或农田区域未分配!");
|
Debug.LogError("预制体或农田区域未分配!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取农田的包围盒信息
|
|
||||||
BoxCollider fieldCollider = fieldArea.GetComponent<BoxCollider>();
|
BoxCollider fieldCollider = fieldArea.GetComponent<BoxCollider>();
|
||||||
if (fieldCollider == null)
|
if (fieldCollider == null)
|
||||||
{
|
{
|
||||||
Debug.LogError("农田区域缺少BoxCollider组件");
|
Debug.LogError("农田区域缺少BoxCollider组件");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Bounds bounds = fieldCollider.bounds;
|
|
||||||
|
|
||||||
// 计算农田边界
|
// 初始化农田参数
|
||||||
float minX = bounds.min.x;
|
fieldBounds = fieldCollider.bounds;
|
||||||
float maxX = bounds.max.x;
|
chunkSize = Mathf.Max(fieldBounds.size.x, fieldBounds.size.z) / chunksPerAxis;
|
||||||
float minZ = bounds.min.z;
|
|
||||||
float maxZ = bounds.max.z;
|
|
||||||
|
|
||||||
// 获取农田表面高度(假设为平面)
|
// 预生成所有高粱并分配到区块
|
||||||
float groundY = fieldArea.transform.position.y;
|
GenerateSorghumGrid(sorghumPrefab, rowDistance, strainDistance);
|
||||||
|
ProcessDiseasedPlants(diseasedRate, randomRotate);
|
||||||
|
|
||||||
// 按行生成农作物
|
// 初始隐藏所有高粱
|
||||||
for (float x = minX; x <= maxX; x += RowDistance)
|
SetAllChunksVisibility(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerateSorghumGrid(GameObject prefab, float rowDist, float strainDist)
|
||||||
|
{
|
||||||
|
for (float x = fieldBounds.min.x; x <= fieldBounds.max.x; x += rowDist)
|
||||||
{
|
{
|
||||||
// 按植株间距生成单行作物
|
for (float z = fieldBounds.min.z; z <= fieldBounds.max.z; z += strainDist)
|
||||||
for (float z = minZ; z <= maxZ; z += StrainDistance)
|
|
||||||
{
|
{
|
||||||
// 生成位置(自动对齐地面高度)
|
Vector3 spawnPos = new Vector3(x, fieldBounds.min.y, z);
|
||||||
Vector3 spawnPos = new Vector3(x, groundY, z);
|
GameObject obj = Instantiate(prefab, spawnPos, Quaternion.identity, fieldArea.transform);
|
||||||
|
|
||||||
// 实例化并挂载到农田下
|
|
||||||
GameObject obj = Instantiate(
|
AddToChunk(obj);
|
||||||
SorghumPrefab,
|
|
||||||
spawnPos,
|
|
||||||
Quaternion.identity,
|
|
||||||
fieldArea.transform
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddToChunk(GameObject sorghum)
|
||||||
|
{
|
||||||
|
Vector2Int chunkCoord = new Vector2Int(
|
||||||
|
Mathf.FloorToInt((sorghum.transform.position.x - fieldBounds.min.x) / chunkSize),
|
||||||
|
Mathf.FloorToInt((sorghum.transform.position.z - fieldBounds.min.z) / chunkSize)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!chunkMap.ContainsKey(chunkCoord))
|
||||||
|
{
|
||||||
|
chunkMap[chunkCoord] = new List<GameObject>();
|
||||||
|
}
|
||||||
|
chunkMap[chunkCoord].Add(sorghum);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProcessDiseasedPlants(float diseasedRate, bool randomRotate)
|
||||||
|
{
|
||||||
SorghumController[] sorghumControllers = FindObjectsOfType<SorghumController>();
|
SorghumController[] sorghumControllers = FindObjectsOfType<SorghumController>();
|
||||||
int DisCount = (int)(sorghumControllers.Length * DiseasedRate);
|
int DisCount = (int)(sorghumControllers.Length * diseasedRate);
|
||||||
for (int i = 0; i < DisCount; i++)
|
for (int i = 0; i < DisCount; i++)
|
||||||
{
|
{
|
||||||
int iter = (int)(sorghumControllers.Length * UnityEngine.Random.value);
|
int iter = (int)(sorghumControllers.Length * UnityEngine.Random.value);
|
||||||
if (iter >= sorghumControllers.Length) iter = sorghumControllers.Length - 1;
|
if (iter >= sorghumControllers.Length) iter = sorghumControllers.Length - 1;
|
||||||
if (iter < 0) iter = 0;
|
if (iter < 0) iter = 0;
|
||||||
sorghumControllers[iter].Init(SorghumState.Diseased, RandomRotate);
|
sorghumControllers[iter].Init(SorghumState.Diseased, randomRotate);
|
||||||
sorghumControllers[iter] = sorghumControllers[sorghumControllers.Length - 1];
|
sorghumControllers[iter] = sorghumControllers[sorghumControllers.Length - 1];
|
||||||
SorghumController[] newArry = new SorghumController[sorghumControllers.Length - 1];
|
SorghumController[] newArry = new SorghumController[sorghumControllers.Length - 1];
|
||||||
Array.Copy(sorghumControllers, newArry, sorghumControllers.Length - 1);
|
Array.Copy(sorghumControllers, newArry, sorghumControllers.Length - 1);
|
||||||
|
|
@ -74,20 +93,73 @@ public class SorghumFieldController : MonoBehaviour
|
||||||
|
|
||||||
foreach (var item in sorghumControllers)
|
foreach (var item in sorghumControllers)
|
||||||
{
|
{
|
||||||
item.Init(SorghumState.Healthy, RandomRotate);
|
item.Init(SorghumState.Healthy, randomRotate);
|
||||||
|
item.gameObject.GetComponentInChildren<Renderer>().enabled = false; // 初始隐藏
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetAllChunksVisibility(bool visible)
|
||||||
|
{
|
||||||
|
foreach (var chunk in chunkMap.Values)
|
||||||
|
{
|
||||||
|
foreach (GameObject plant in chunk)
|
||||||
|
{
|
||||||
|
plant.GetComponentInChildren<Renderer>().enabled = visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//// Start is called before the first frame update
|
|
||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
InitSorghum(rowDistance, strainDistance, diseasedRate, randomRotate);
|
InitSorghum(rowDistance, strainDistance, diseasedRate, randomRotate);
|
||||||
|
StartCoroutine(VisibilityUpdateRoutine());
|
||||||
}
|
}
|
||||||
|
|
||||||
//// Update is called once per frame
|
IEnumerator VisibilityUpdateRoutine()
|
||||||
//void Update()
|
{
|
||||||
//{
|
WaitForSeconds wait = new WaitForSeconds(0.1f); // 每0.1秒更新一次
|
||||||
|
Plane[] frustumPlanes = new Plane[6];
|
||||||
|
Camera mainCam = Camera.main;
|
||||||
|
|
||||||
//}
|
while (true)
|
||||||
|
{
|
||||||
|
if (mainCam != null)
|
||||||
|
{
|
||||||
|
frustumPlanes = GeometryUtility.CalculateFrustumPlanes(mainCam);
|
||||||
|
|
||||||
|
foreach (var chunk in chunkMap)
|
||||||
|
{
|
||||||
|
Bounds chunkBounds = CalculateChunkBounds(chunk.Key);
|
||||||
|
bool shouldVisible = GeometryUtility.TestPlanesAABB(frustumPlanes, chunkBounds);
|
||||||
|
SetChunkVisibility(chunk.Key, shouldVisible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
yield return wait;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bounds CalculateChunkBounds(Vector2Int coord)
|
||||||
|
{
|
||||||
|
Vector3 min = new Vector3(
|
||||||
|
fieldBounds.min.x + coord.x * chunkSize,
|
||||||
|
fieldBounds.min.y,
|
||||||
|
fieldBounds.min.z + coord.y * chunkSize
|
||||||
|
);
|
||||||
|
|
||||||
|
return new Bounds(
|
||||||
|
min + new Vector3(chunkSize / 2, 0, chunkSize / 2),
|
||||||
|
new Vector3(chunkSize, fieldBounds.size.y, chunkSize)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetChunkVisibility(Vector2Int coord, bool visible)
|
||||||
|
{
|
||||||
|
if (chunkMap.TryGetValue(coord, out List<GameObject> plants))
|
||||||
|
{
|
||||||
|
foreach (GameObject plant in plants)
|
||||||
|
{
|
||||||
|
plant.GetComponentInChildren<Renderer>().enabled = visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -135,7 +135,7 @@ public class GameManager : SingletonAutoMono<GameManager>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// PPT管理类
|
/// PPT管理类
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static PPTManager PPTManager { get; private set; }
|
//public static PPTManager PPTManager { get; private set; }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -165,7 +165,7 @@ public class GameManager : SingletonAutoMono<GameManager>
|
||||||
WorkorderMgr = WorkorderMgr.Instance; //工单管理初始化
|
WorkorderMgr = WorkorderMgr.Instance; //工单管理初始化
|
||||||
FaultManager = FaultManager.Instance;
|
FaultManager = FaultManager.Instance;
|
||||||
MissionMgr = MissionMgr.Instance;
|
MissionMgr = MissionMgr.Instance;
|
||||||
PPTManager = PPTManager.Instance;
|
//PPTManager = PPTManager.Instance;
|
||||||
DataMgr.Init();
|
DataMgr.Init();
|
||||||
WorkorderMgr.Init();
|
WorkorderMgr.Init();
|
||||||
NetMgr.Init(SendGet);
|
NetMgr.Init(SendGet);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue