赞
踩
管理房间的边界信息和相关操作:
这些字段定义了房间的显示属性和调整手柄的参数,比如网格颜色、手柄大小和网格间隔等。
public bool showWorldArea = true;
public bool showForbidArea = true;
public Color gizmosColor = Color.black;
public Color gizmosXColor = new Color(1 , 0 , 0 , 0.2f);
public Color gizmosYColor = new Color(0 , 1 , 0 , 0.2f);
public Color gizmosZColor = new Color(0 , 0 , 1 , 0.2f);
public float HandlesSize = 0.5f;
public Vector2Int LeftAndRightInterval = Vector2Int.one*5;
public Vector2Int TopAndBottomInterval = Vector2Int.one*5;
public Vector2Int FrontAndBackInterval = Vector2Int.one*5;
Vector3 worldLeftLocation, worldRightLocation, worldTopLocation, worldBottomLocation, worldFrontLocation, worldBackLocation;
[HideInInspector]
public Vector3 leftLocation = new Vector3(-5 , 0 , 0);
[HideInInspector]
public Vector3 rightLocation = new Vector3(5 , 0 , 0);
[HideInInspector]
public Vector3 topLocation = new Vector3(0 , 5 , 0);
[HideInInspector]
public Vector3 bottomLocation = new Vector3(0 , -5 , 0);
[HideInInspector]
public Vector3 frontLocation = new Vector3(0 , 0 , 5);
[HideInInspector]
public Vector3 backLocation = new Vector3(0 , 0 , -5);
public int CornerContagion = 1;
这些字段定义了房间各个边界的位置,使用HideInInspector属性隐藏在Inspector中,不直接显示给用户。
public Vector3 SnapToGrid(Vector3 point , SnapDirection snapDirection)
{
Vector3 localPoint = transform.InverseTransformPoint(point);
Vector3 localStart;
Vector3 localEnd;
int totalIntervals;
switch(snapDirection)
{
case SnapDirection.Front:
case SnapDirection.Back:
localStart=transform.InverseTransformPoint(worldLeftLocation);
localEnd=transform.InverseTransformPoint(worldRightLocation);
totalIntervals=FrontAndBackInterval.x-1;
localPoint.x=SnapCoordinate(localPoint.x , localStart.x , localEnd.x , totalIntervals);
localStart=transform.InverseTransformPoint(worldBottomLocation);
localEnd=transform.InverseTransformPoint(worldTopLocation);
totalIntervals=FrontAndBackInterval.y-1;
localPoint.y=SnapCoordinate(localPoint.y , localStart.y , localEnd.y , totalIntervals);
// Z轴坐标保持不变
break;
case SnapDirection.Left:
case SnapDirection.Right:
localStart=transform.InverseTransformPoint(worldFrontLocation);
localEnd=transform.InverseTransformPoint(worldBackLocation);
totalIntervals=LeftAndRightInterval.x-1;
localPoint.z=SnapCoordinate(localPoint.z , localStart.z , localEnd.z , totalIntervals);
// 与Front/Back情况相同的Y轴处理
localStart=transform.InverseTransformPoint(worldBottomLocation);
localEnd=transform.InverseTransformPoint(worldTopLocation);
totalIntervals=LeftAndRightInterval.y-1;
localPoint.y=SnapCoordinate(localPoint.y , localStart.y , localEnd.y , totalIntervals);
// X轴坐标保持不变
break;
case SnapDirection.Top:
case SnapDirection.Bottom:
localStart=transform.InverseTransformPoint(worldLeftLocation);
localEnd=transform.InverseTransformPoint(worldRightLocation);
totalIntervals=TopAndBottomInterval.x-1;
localPoint.x=SnapCoordinate(localPoint.x , localStart.x , localEnd.x , totalIntervals);
localStart=transform.InverseTransformPoint(worldFrontLocation);
localEnd=transform.InverseTransformPoint(worldBackLocation);
totalIntervals=TopAndBottomInterval.y-1;
localPoint.z=SnapCoordinate(localPoint.z , localStart.z , localEnd.z , totalIntervals);
// Y轴坐标保持不变
break;
}
return transform.TransformPoint(localPoint);
}
private float SnapCoordinate(float coordinate , float start , float end , int intervals)
{
float relativePos = (coordinate-start)/(end-start);
int intervalIndex = Mathf.RoundToInt(relativePos*intervals);
if(intervalIndex<CornerContagion)
intervalIndex=CornerContagion;
if(intervalIndex>intervals-(CornerContagion))
intervalIndex=intervals-(CornerContagion);
float lerpValue = (float)intervalIndex/intervals;
return Mathf.Lerp(start , end , lerpValue);
}
1.坐标转换:将输入点point转换到局部坐标系localPoint。
2.根据对齐方向处理:
3.调用SnapCoordinate方法:计算并返回对齐后的坐标。
4.坐标还原:将对齐后的局部坐标转换回世界坐标。
1.计算相对位置:将坐标coordinate标准化到0到1范围内。
2.确定区间索引:根据相对位置和总区间数计算所在区间索引。
3.调整区间索引:确保区间索引不超出范围,避免靠近边界的物体超出区域。
4.计算对齐坐标:使用线性插值计算最终的对齐坐标。
ResetArea(): 重置房间边界位置。
public void ResetArea()
{
leftLocation=new Vector3(-1 , 0 , 0);
rightLocation=new Vector3(1 , 0 , 0);
topLocation=new Vector3(0 , 1 , 0);
bottomLocation=new Vector3(0 , -1 , 0);
frontLocation=new Vector3(0 , 0 , 1);
backLocation=new Vector3(0 , 0 , -1);
transform.rotation=Quaternion.identity;
}
AddRoomItem(MultiMeshAreaCalculator roomItem): 添加房间内的物体。
List<MultiMeshAreaCalculator> RoomItems = new List<MultiMeshAreaCalculator>();
List<AreaData> AreaDatas = new List<AreaData>();//AreaData存储空间数据,一般为八个Vector3数据,一个方块的8个点位
public void AddRoomItem(MultiMeshAreaCalculator roomItem)
{
RoomItems.Add(roomItem);
AddItemData(roomItem);
}
void AddItemData(MultiMeshAreaCalculator roomItem)
{
AreaDatas.AddRange(roomItem.GetItemData());//roomItem.GetItemData()提供物体占用区域数据
}
RemoveAddRoomItem(MultiMeshAreaCalculator roomItem): 删除房间内的物体。
public void RemoveAddRoomItem(MultiMeshAreaCalculator roomItem)
{
RoomItems.Remove(roomItem);
AreaDatas.Clear();
foreach(var item in RoomItems)
{
AddItemData(item);
}
}
AutoAdjustEdge 方法用于自动调整房间边界的位置。这是通过在每个方向上投射射线(Ray)并检测与碰撞体的交点来实现的。
public void AutoAdjustEdge()
{
RaycastHit hit;
Ray ray = new Ray(transform.position , transform.up);
if (Physics.Raycast(ray , out hit))
topLocation = transform.InverseTransformPoint(hit.point);
ray = new Ray(transform.position , -transform.up);
if (Physics.Raycast(ray , out hit))
bottomLocation = transform.InverseTransformPoint(hit.point);
ray = new Ray(transform.position , transform.right);
if (Physics.Raycast(ray , out hit))
rightLocation = transform.InverseTransformPoint(hit.point);
ray = new Ray(transform.position , -transform.right);
if (Physics.Raycast(ray , out hit))
leftLocation = transform.InverseTransformPoint(hit.point);
ray = new Ray(transform.position , transform.forward);
if (Physics.Raycast(ray , out hit))
frontLocation = transform.InverseTransformPoint(hit.point);
ray = new Ray(transform.position , -transform.forward);
if (Physics.Raycast(ray , out hit))
backLocation = transform.InverseTransformPoint(hit.point);
}
topLocation = transform.InverseTransformPoint(hit.point);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。