unity 陶艺制作模拟
·
using UnityEngine;
using System.Collections.Generic;
/// ============================================================================
/// 陶艺制作器 - PotteryMaker.cs
/// ============================================================================
///
/// 【功能概述】
/// 专业的3D陶器建模工具,支持实时交互式陶器制作和编辑
///
/// 【主要特性】
/// ✅ 智能网格生成 - 自动创建底部、外壁、顶部、内壁和内底网格
/// ✅ 双模式操作 - 左键扩大陶器,右键缩小陶器
/// ✅ 高度补偿系统 - 壁扩大时自动变矮,壁缩小时自动变高
/// ✅ 实时碰撞器 - 动态更新网格碰撞器,支持触发器模式
/// ✅ 调试可视化 - 显示影响范围和操作目标点
/// ✅ 多输入支持 - 同时支持鼠标和触控输入
///
/// 【操作指南】
/// 1. 左键拖拽:扩大陶器形状
/// 2. 右键拖拽:缩小陶器形状
/// 3. 垂直拖拽:调整整体高度
/// 4. 参数调整:在Inspector中修改模型参数
///
/// 【快捷键】
/// • 左键 + 水平拖拽:半径调整
/// • 右键 + 水平拖拽:反向半径调整
/// • 任何键 + 垂直拖拽:高度调整
///
/// 【注意事项】
/// • 确保已分配陶艺材质
/// • 碰撞器默认启用,可根据需要调整
/// • 调试信息可在编辑器中查看操作效果
///
/// ============================================================================
/// <summary>
/// 陶艺制作器 - 用于创建和编辑3D陶器模型
/// 功能包括:网格生成、交互变形、碰撞器管理、调试可视化
/// </summary>
public class PotteryMaker : MonoBehaviour
{
[Header("模型参数")]
[Tooltip("细节数量(水平分段),值越高模型越平滑")]
public int Details = 24; // 细节数量(水平分段)
[Tooltip("层数(垂直分段),值越高模型高度方向细节越多")]
public int LayerCount = 20; // 层数(垂直分段)
[Tooltip("每层的高度,控制陶器的高度精度")]
public float LayerHeight = 0.1f; // 层高
[Tooltip("陶器的初始外径尺寸")]
public float Radius = 1.0f; // 外径尺寸
[Tooltip("陶器壁的厚度")]
public float Thickness = 0.2f; // 壁厚度
[Tooltip("陶器允许的最小半径")]
public float MinRadius = 0.5f; // 最小半径
[Tooltip("陶器允许的最大半径")]
public float MaxRadius = 2.0f; // 最大半径
[Header("交互参数")]
[Tooltip("操作影响的层数,值越大影响范围越广")]
public int InfluenceLayer = 3; // 操作影响的层数
[Tooltip("操作力度,控制变形速度")]
public float TouchPower = 0.01f; // 操作力度
[Tooltip("左键操作力度乘数")]
public float LeftClickPowerMultiplier = 1.0f;
[Tooltip("右键操作力度乘数")]
public float RightClickPowerMultiplier = -1.0f;
[Header("渲染设置")]
[Tooltip("陶艺材质,用于渲染陶器表面")]
public Material PotteryMaterial; // 陶艺材质
[Tooltip("射线检测层掩码,用于精确点击检测")]
public LayerMask PotteryLayerMask = -1; // 射线检测层掩码
[Header("碰撞器设置")]
[Tooltip("是否启用碰撞器更新")]
public bool EnableCollider = true;
[Tooltip("碰撞器是否为触发器")]
public bool ColliderIsTrigger = true;
[Header("调试设置")]
[Tooltip("是否显示调试信息")]
public bool ShowDebugInfo = true;
[Tooltip("影响范围可视化颜色")]
public Color InfluenceRangeColor = Color.green;
[Tooltip("目标点标记颜色")]
public Color TargetPointColor = Color.red;
[Header("高度补偿设置")]
[Tooltip("高度补偿强度,控制壁变化时的高度调整幅度")]
public float HeightCompensationStrength = 0.1f;
[Tooltip("最大高度补偿量,限制高度变化幅度")]
public float MaxHeightCompensation = 0.05f;
[Tooltip("最小允许高度,防止陶器变得过扁")]
public float MinAllowedHeight = 0.1f;
// 内部变量
private Mesh theMesh;
private MeshFilter meshFilter;
private MeshRenderer meshRenderer;
private MeshCollider meshCollider;
private bool isShaping = false;
private Vector3 targetWorldPos;
private Vector3 lastScreenPos;
private int SplitIndex; // 区分内外表面的顶点索引
private bool isRightClick = false; // 标记是否为右键操作
// 计算属性
private float SqrMaxOuterRadius => MaxRadius * MaxRadius;
private float SqrMinOuterRadius => MinRadius * MinRadius;
private float SqrMaxInnerRadius => (MaxRadius - Thickness) * (MaxRadius - Thickness);
private float SqrMinInnerRadius => (MinRadius - Thickness) * (MinRadius - Thickness);
/// <summary>
/// 初始化函数,在游戏开始时调用
/// </summary>
void Start()
{
InitializeMesh();
GeneratePottery();
if (EnableCollider)
{
AddCollider();
}
Debug.Log("陶艺制作器初始化完成!");
Debug.Log("使用说明:左键扩大,右键缩小,垂直拖拽调整高度");
}
/// <summary>
/// 每帧更新函数,处理用户输入
/// </summary>
void Update()
{
HandleInput();
// 在编辑器中绘制调试信息
if (ShowDebugInfo && Application.isEditor)
{
DebugDrawInfluenceRange();
}
}
/// <summary>
/// 在场景视图中绘制Gizmos
/// </summary>
private void OnDrawGizmos()
{
if (ShowDebugInfo && Application.isPlaying)
{
// 绘制影响范围
Gizmos.color = InfluenceRangeColor;
Gizmos.DrawWireSphere(targetWorldPos, InfluenceLayer * LayerHeight);
// 绘制目标点十字标记
Gizmos.color = TargetPointColor;
float crossSize = 0.1f;
Gizmos.DrawLine(targetWorldPos - Vector3.right * crossSize, targetWorldPos + Vector3.right * crossSize);
Gizmos.DrawLine(targetWorldPos - Vector3.up * crossSize, targetWorldPos + Vector3.up * crossSize);
Gizmos.DrawLine(targetWorldPos - Vector3.forward * crossSize, targetWorldPos + Vector3.forward * crossSize);
}
}
/// <summary>
/// 初始化网格组件
/// </summary>
private void InitializeMesh()
{
meshFilter = gameObject.GetComponent<MeshFilter>();
if (meshFilter == null)
meshFilter = gameObject.AddComponent<MeshFilter>();
meshRenderer = gameObject.GetComponent<MeshRenderer>();
if (meshRenderer == null)
meshRenderer = gameObject.AddComponent<MeshRenderer>();
// 检查材质是否已赋值,如果没有则创建默认材质
if (PotteryMaterial == null)
{
Debug.LogWarning("陶艺材质未赋值,正在创建默认材质...");
CreateDefaultMaterial();
}
meshRenderer.material = PotteryMaterial;
theMesh = new Mesh();
theMesh.name = "Pottery";
meshFilter.mesh = theMesh;
}
/// <summary>
/// 创建默认材质(当用户未指定材质时使用)
/// </summary>
private void CreateDefaultMaterial()
{
// 创建默认的陶艺材质
Shader standardShader = Shader.Find("Standard");
if (standardShader != null)
{
PotteryMaterial = new Material(standardShader);
PotteryMaterial.name = "DefaultPotteryMaterial";
PotteryMaterial.color = new Color(0.8f, 0.6f, 0.4f, 1.0f); // 陶土色
PotteryMaterial.SetFloat("_Glossiness", 0.3f); // 设置光泽度
Debug.Log("已创建默认陶艺材质: " + PotteryMaterial.name);
}
else
{
Debug.LogError("无法找到Standard着色器,请确保项目中包含Standard着色器!");
// 创建最简单的材质作为备选
PotteryMaterial = new Material(Shader.Find("Diffuse"));
if (PotteryMaterial != null)
{
PotteryMaterial.color = Color.gray;
Debug.LogWarning("使用Diffuse着色器作为备选材质");
}
else
{
Debug.LogError("无法创建任何材质,渲染可能不正常!");
}
}
}
/// <summary>
/// 添加网格碰撞器
/// </summary>
public void AddCollider()
{
// 移除旧的碰撞器
MeshCollider[] oldColliders = GetComponents<MeshCollider>();
foreach (var collider in oldColliders)
{
DestroyImmediate(collider);
}
// 添加新的网格碰撞器
meshCollider = gameObject.AddComponent<MeshCollider>();
meshCollider.sharedMesh = theMesh;
meshCollider.convex = false; // 非凸碰撞器,适合复杂形状
meshCollider.isTrigger = ColliderIsTrigger; // 设置为触发器避免物理交互冲突
Debug.Log("陶器碰撞器已添加,触发器模式: " + ColliderIsTrigger);
}
/// <summary>
/// 更新碰撞器以匹配当前网格
/// </summary>
public void UpdateCollider()
{
if (meshCollider != null && EnableCollider)
{
meshCollider.sharedMesh = null; // 先清空引用
meshCollider.sharedMesh = theMesh; // 重新赋值以更新碰撞器
}
}
/// <summary>
/// 生成陶器网格
/// </summary>
private void GeneratePottery()
{
List<Vector3> vertices = new List<Vector3>();
List<int> triangles = new List<int>();
List<Vector2> uvs = new List<Vector2>();
float deltaAngle = 2 * Mathf.PI / Details;
// 生成各部分
CreateBottom(deltaAngle, vertices, triangles, uvs);
CreateOuter(deltaAngle, vertices, triangles, uvs);
CreateTop(deltaAngle, vertices, triangles, uvs);
CreateInner(deltaAngle, vertices, triangles, uvs);
CreateInnerBottom(deltaAngle, vertices, triangles, uvs);
// 设置网格数据
theMesh.vertices = vertices.ToArray();
theMesh.triangles = triangles.ToArray();
theMesh.uv = uvs.ToArray();
theMesh.RecalculateBounds();
theMesh.RecalculateNormals();
SmoothNormals();
// 记录内外表面的分界点
SplitIndex = Details + 1 + (LayerCount + 1) * (Details + 1);
Debug.Log("陶器生成完成,顶点数: " + vertices.Count + ", 三角形数: " + triangles.Count / 3);
}
/// <summary>
/// 创建底部网格
/// </summary>
private void CreateBottom(float deltaAngle, List<Vector3> vertices, List<int> triangles, List<Vector2> uvs)
{
// 外底中心点作为整个模型的第一个顶点
vertices.Add(Vector3.zero);
uvs.Add(new Vector2(0.25f, 0.25f));
int index = 1;
for (int i = 0; i < Details; ++i)
{
float angle = i * deltaAngle;
float cosAngle = Mathf.Cos(angle);
float sinAngle = Mathf.Sin(angle);
Vector3 v = new Vector3(Radius * cosAngle, 0, Radius * sinAngle);
vertices.Add(v);
// 添加三角形
triangles.Add(index);
triangles.Add((index >= Details) ? 1 : index + 1);
triangles.Add(0);
// 计算UV
Vector2 u = new Vector2(0.25f + 0.25f * cosAngle, 0.25f + 0.25f * sinAngle);
uvs.Add(u);
++index;
}
}
/// <summary>
/// 创建外壁网格
/// </summary>
private void CreateOuter(float deltaAngle, List<Vector3> vertices, List<int> triangles, List<Vector2> uvs)
{
for (int layer = 0; layer <= LayerCount; ++layer)
{
float height = layer * LayerHeight;
int vIndex = vertices.Count;
int lastIndex = vIndex - Details - 1;
int vIndexAddOne = vIndex + 1;
int lastIndexAddOne = lastIndex + 1;
float v = ((float)layer / LayerCount) * 0.4f + 0.5f;
for (int i = 0; i <= Details; ++i)
{
float angle = (i == Details) ? 0 : i * deltaAngle;
float cosAngle = Mathf.Cos(angle);
float sinAngle = Mathf.Sin(angle);
Vector3 vo = new Vector3(Radius * cosAngle, height, Radius * sinAngle);
vertices.Add(vo);
if (layer > 0 && i < Details)
{
triangles.Add(vIndex + i);
triangles.Add(vIndexAddOne + i);
triangles.Add(lastIndex + i);
triangles.Add(lastIndex + i);
triangles.Add(vIndexAddOne + i);
triangles.Add(lastIndexAddOne + i);
}
float u = (float)i / Details;
Vector2 uv = new Vector2(u, v);
uvs.Add(uv);
}
}
}
/// <summary>
/// 创建顶部网格
/// </summary>
private void CreateTop(float deltaAngle, List<Vector3> vertices, List<int> triangles, List<Vector2> uvs)
{
float inner = Radius - Thickness;
for (int h = 0; h < 2; ++h)
{
float height = (LayerCount - h) * LayerHeight;
int vIndex = vertices.Count;
int lastIndex = vIndex - Details - 1;
int vIndexAddOne = vIndex + 1;
int lastIndexAddOne = lastIndex + 1;
float v = 0.95f + h * 0.05f;
for (int i = 0; i <= Details; ++i)
{
float angle = (i == Details) ? 0 : i * deltaAngle;
float cosAngle = Mathf.Cos(angle);
float sinAngle = Mathf.Sin(angle);
Vector3 vo = new Vector3(inner * cosAngle, height, inner * sinAngle);
vertices.Add(vo);
if (i < Details)
{
triangles.Add(vIndex + i);
triangles.Add(vIndexAddOne + i);
triangles.Add(lastIndex + i);
triangles.Add(lastIndex + i);
triangles.Add(vIndexAddOne + i);
triangles.Add(lastIndexAddOne + i);
}
float u = (float)i / Details;
Vector2 uv = new Vector2(u, v);
uvs.Add(uv);
}
}
}
/// <summary>
/// 创建内壁网格
/// </summary>
private void CreateInner(float deltaAngle, List<Vector3> vertices, List<int> triangles, List<Vector2> uvs)
{
float inner = Radius - Thickness;
int count = LayerCount - 1;
for (int layer = 0; layer < count; ++layer)
{
float height = (LayerCount - layer - 1) * LayerHeight;
int vIndex = vertices.Count;
int lastIndex = vIndex - Details - 1;
int vIndexAddOne = vIndex + 1;
int lastIndexAddOne = lastIndex + 1;
float v = 0.5f - ((float)layer / count) * 0.5f;
for (int i = 0; i <= Details; ++i)
{
float angle = (i == Details) ? 0 : i * deltaAngle;
float cosAngle = Mathf.Cos(angle);
float sinAngle = Mathf.Sin(angle);
Vector3 vo = new Vector3(inner * cosAngle, height, inner * sinAngle);
vertices.Add(vo);
if (layer > 0 && i < Details)
{
triangles.Add(vIndex + i);
triangles.Add(vIndexAddOne + i);
triangles.Add(lastIndex + i);
triangles.Add(lastIndex + i);
triangles.Add(vIndexAddOne + i);
triangles.Add(lastIndexAddOne + i);
}
float u = (float)i / Details * 0.5f + 0.5f;
Vector2 uv = new Vector2(u, v);
uvs.Add(uv);
}
}
}
/// <summary>
/// 创建内底网格
/// </summary>
private void CreateInnerBottom(float deltaAngle, List<Vector3> vertices, List<int> triangles, List<Vector2> uvs)
{
int index = vertices.Count;
float inner = Radius - Thickness;
for (int i = 0; i < Details; ++i)
{
float angle = i * deltaAngle;
float cosAngle = Mathf.Cos(angle);
float sinAngle = Mathf.Sin(angle);
Vector3 v = new Vector3(inner * cosAngle, LayerHeight, inner * sinAngle);
vertices.Add(v);
triangles.Add(index + Details);
triangles.Add((i >= Details - 1) ? index : index + i + 1);
triangles.Add(index + i);
Vector2 u = new Vector2(0.75f + 0.25f * cosAngle, 0.25f + 0.25f * sinAngle);
uvs.Add(u);
}
vertices.Add(new Vector3(0, LayerHeight, 0));
uvs.Add(new Vector2(0.75f, 0.25f));
}
/// <summary>
/// 处理用户输入
/// </summary>
private void HandleInput()
{
// 检测鼠标右键按下
if (Input.GetMouseButtonDown(1))
{
isRightClick = true;
lastScreenPos = Input.mousePosition;
if (Physics.Raycast(Camera.main.ScreenPointToRay(lastScreenPos), out RaycastHit hit, 1000f, PotteryLayerMask))
{
// 验证点击的是当前游戏对象
if (hit.collider.gameObject == this.gameObject)
{
targetWorldPos = hit.point;
isShaping = true;
Debug.Log("右键操作开始 - 缩小模式");
}
}
else
{
isShaping = false;
}
}
else if (Input.GetMouseButtonUp(1))
{
isRightClick = false;
isShaping = false;
}
// 检测鼠标左键按下
if (Input.GetMouseButtonDown(0))
{
isRightClick = false;
lastScreenPos = Input.mousePosition;
if (Physics.Raycast(Camera.main.ScreenPointToRay(lastScreenPos), out RaycastHit hit, 1000f, PotteryLayerMask))
{
// 验证点击的是当前游戏对象
if (hit.collider.gameObject == this.gameObject)
{
targetWorldPos = hit.point;
isShaping = true;
Debug.Log("左键操作开始 - 扩大模式");
}
}
else
{
isShaping = false;
}
}
else if (Input.GetMouseButtonUp(0))
{
isShaping = false;
}
// 处理鼠标移动操作
if (isShaping && (Input.GetMouseButton(0) || Input.GetMouseButton(1)))
{
Vector3 currPos = Input.mousePosition;
ShapeIt(currPos - lastScreenPos);
lastScreenPos = currPos;
}
// 如果检测到触控用触控,否则用鼠标
if (Input.touchCount == 1)
{
Touch touch = Input.GetTouch(0);
if (touch.phase == TouchPhase.Began)
{
if (Physics.Raycast(Camera.main.ScreenPointToRay(touch.position), out RaycastHit hit, 1000f, PotteryLayerMask))
{
// 验证点击的是当前游戏对象
if (hit.collider.gameObject == this.gameObject)
{
targetWorldPos = hit.point;
isShaping = true;
}
}
else
{
isShaping = false;
}
}
else if (isShaping && (touch.phase == TouchPhase.Moved))
{
ShapeIt(touch.deltaPosition);
}
else if (touch.phase == TouchPhase.Ended)
{
isShaping = false;
}
}
}
/// <summary>
/// 形状变形处理
/// </summary>
/// <param name="deltaPos">鼠标/触控移动增量</param>
private void ShapeIt(Vector3 deltaPos)
{
bool bHorizontal = false;
bool bVertical = false;
float dirRate = 0, scale = 0;
if (Mathf.Abs(deltaPos.x) > 0.01f)
{
// 根据左右键选择操作方向
float powerMultiplier = isRightClick ? RightClickPowerMultiplier : LeftClickPowerMultiplier;
dirRate = IsInRight() ? Mathf.Sign(deltaPos.x) : -Mathf.Sign(deltaPos.x);
dirRate *= powerMultiplier;
bHorizontal = true;
}
if (Mathf.Abs(deltaPos.y) > 0.02f)
{
scale = Mathf.Sign(deltaPos.y) * 0.001f;
bVertical = true;
}
if (bHorizontal)
{
Vector3 targetPos = transform.InverseTransformPoint(targetWorldPos);
Vector3[] vertices = theMesh.vertices;
int maxVerticesIndex = vertices.Length - 1;
float Range = InfluenceLayer * LayerHeight;
// 记录原始平均高度,用于高度补偿
float originalAverageHeight = CalculateAverageHeight(vertices);
for (int i = 1; i < maxVerticesIndex; ++i)
{
float max, min;
if (i < SplitIndex)
{
max = SqrMaxOuterRadius;
min = SqrMinOuterRadius;
}
else
{
max = SqrMaxInnerRadius;
min = SqrMinInnerRadius;
}
float dis = Mathf.Abs(targetPos.y - vertices[i].y);
if (dis < Range)
{
Vector3 dir = vertices[i];
dir.y = 0;
if ((dirRate > 0 && dir.sqrMagnitude < max) || (dirRate < 0 && dir.sqrMagnitude > min))
vertices[i] += dir.normalized * dirRate * TouchPower * (1f - dis / Range);
}
}
// 应用高度补偿:壁扩大时变矮,壁缩小时变高
ApplyHeightCompensation(vertices, originalAverageHeight, dirRate);
theMesh.vertices = vertices;
theMesh.RecalculateBounds();
theMesh.RecalculateNormals();
SmoothNormals();
// 更新碰撞器
UpdateCollider();
}
if (bVertical)
{
Vector3 sc = transform.localScale;
sc.y = Mathf.Clamp(sc.y + scale, 0.5f, 1.5f);
transform.localScale = sc;
}
}
/// <summary>
/// 计算网格的平均高度
/// </summary>
private float CalculateAverageHeight(Vector3[] vertices)
{
float totalHeight = 0f;
int count = 0;
for (int i = 1; i < vertices.Length; i++)
{
// 只计算外壁和内壁的顶点,排除底部中心点
if (vertices[i].y > 0)
{
totalHeight += vertices[i].y;
count++;
}
}
return count > 0 ? totalHeight / count : 0f;
}
/// <summary>
/// 应用高度补偿:壁扩大时变矮,壁缩小时变高
/// </summary>
private void ApplyHeightCompensation(Vector3[] vertices, float originalAverageHeight, float dirRate)
{
// 计算高度变化量(壁扩大时高度降低,壁缩小时高度增加)
float heightChange = -dirRate * HeightCompensationStrength; // 负号表示反向关系
// 限制高度变化幅度
heightChange = Mathf.Clamp(heightChange, -MaxHeightCompensation, MaxHeightCompensation);
// 应用高度补偿到所有相关顶点
for (int i = 1; i < vertices.Length; i++)
{
// 只调整外壁和内壁的顶点高度,保持底部不变
if (vertices[i].y > 0)
{
vertices[i].y += heightChange;
// 确保高度不会低于最小值
vertices[i].y = Mathf.Max(vertices[i].y, MinAllowedHeight);
}
}
if (ShowDebugInfo)
{
Debug.Log($"高度补偿应用: 方向={dirRate}, 变化量={heightChange:F3}, 强度={HeightCompensationStrength}");
}
}
/// <summary>
/// 判断目标点是否在右侧
/// </summary>
/// <returns>true如果在右侧,否则false</returns>
private bool IsInRight()
{
Transform camera = Camera.main.transform;
Vector3 target = camera.InverseTransformPoint(targetWorldPos);
Vector3 pottery = camera.InverseTransformPoint(transform.position);
return target.x > pottery.x;
}
/// <summary>
/// 平滑法线
/// </summary>
private void SmoothNormals()
{
Vector3[] normals = theMesh.normals;
int step = Details + 1;
int start = step;
int end = start + (LayerCount + 3) * step;
for (int i = start; i < end; i += step)
{
int index1 = i;
int index2 = i + Details;
Vector3 normal = ((normals[index1] + normals[index2]) / 2f).normalized;
normals[index1] = normal;
normals[index2] = normal;
}
theMesh.normals = normals;
}
/// <summary>
/// 调试绘制影响范围
/// </summary>
private void DebugDrawInfluenceRange()
{
if (isShaping)
{
// 绘制影响范围球体
DebugDrawWireSphere(targetWorldPos, InfluenceLayer * LayerHeight, InfluenceRangeColor);
// 绘制目标点十字标记
DebugDrawCross(targetWorldPos, 0.1f, TargetPointColor);
// 显示操作信息
string operationType = isRightClick ? "缩小" : "扩大";
Debug.Log($"当前操作: {operationType}, 影响半径: {InfluenceLayer * LayerHeight:F2}");
}
}
/// <summary>
/// 调试绘制线框球体
/// </summary>
private void DebugDrawWireSphere(Vector3 center, float radius, Color color)
{
int segments = 16;
float angleIncrement = 360f / segments;
for (int i = 0; i < segments; i++)
{
float angle = i * angleIncrement * Mathf.Deg2Rad;
float nextAngle = (i + 1) * angleIncrement * Mathf.Deg2Rad;
Vector3 start = center + new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)) * radius;
Vector3 end = center + new Vector3(Mathf.Cos(nextAngle), 0, Mathf.Sin(nextAngle)) * radius;
Debug.DrawLine(start, end, color);
start = center + new Vector3(Mathf.Cos(angle), Mathf.Sin(angle), 0) * radius;
end = center + new Vector3(Mathf.Cos(nextAngle), Mathf.Sin(nextAngle), 0) * radius;
Debug.DrawLine(start, end, color);
start = center + new Vector3(0, Mathf.Cos(angle), Mathf.Sin(angle)) * radius;
end = center + new Vector3(0, Mathf.Cos(nextAngle), Mathf.Sin(nextAngle)) * radius;
Debug.DrawLine(start, end, color);
}
}
/// <summary>
/// 调试绘制十字标记
/// </summary>
private void DebugDrawCross(Vector3 center, float size, Color color)
{
Debug.DrawLine(center - Vector3.right * size, center + Vector3.right * size, color);
Debug.DrawLine(center - Vector3.up * size, center + Vector3.up * size, color);
Debug.DrawLine(center - Vector3.forward * size, center + Vector3.forward * size, color);
}
/// <summary>
/// 调试用:显示法线
/// </summary>
private void ShowNormals()
{
Vector3[] vertices = theMesh.vertices;
Vector3[] normals = theMesh.normals;
for (int i = 0; i < vertices.Length; i++)
{
Debug.DrawRay(transform.TransformPoint(vertices[i]), transform.TransformDirection(normals[i]) * 0.1f, Color.red);
}
}
/// <summary>
/// 重新生成陶器(公开方法,可用于重置)
/// </summary>
public void RegeneratePottery()
{
GeneratePottery();
if (EnableCollider)
{
UpdateCollider();
}
}
/// <summary>
/// 设置陶器参数并重新生成
/// </summary>
public void SetParameters(int details, int layerCount, float radius, float thickness)
{
Details = details;
LayerCount = layerCount;
Radius = radius;
Thickness = thickness;
RegeneratePottery();
}
}
参考:https://blog.csdn.net/sdhexu/article/details/117991357?spm=1001.2014.3001.5502
更多推荐
所有评论(0)