再unity中 前端模型怎么和c#代码结合
·
在 Unity 中,前端模型(3D模型/UI)和 C# 后端代码的结合主要通过以下几种方式:
一、核心绑定方式
1. 组件(Component)—— 最常用
这是 Unity 的核心设计哲学:模型只是一个容器,行为由挂载的脚本决定。
// 1. 创建一个脚本,挂载到模型上
public class PlateBehavior : MonoBehaviour
{
public string plateName = "青花瓷盘";
public float weight = 0.5f;
void Start()
{
// 模型加载完成后自动执行
Debug.Log($"{plateName} 已放置到桌子上");
}
void OnMouseDown()
{
// 点击模型时触发
PickUpPlate();
}
void PickUpPlate()
{
// 和UI交互
UIManager.Instance.ShowPlateInfo(plateName, weight);
}
}
层级结构:
PlateModel (FBX模型)
├── MeshRenderer (渲染模型)
├── BoxCollider (物理碰撞)
└── PlateBehavior.cs (C#脚本) ← 绑定的行为
2. 获取组件引用
// 方式1:拖拽赋值(最直观)
public class TableManager : MonoBehaviour
{
public GameObject platePrefab; // 在Inspector中拖拽预制体
public Transform spawnPoint; // 拖拽生成位置
void Start()
{
// 实例化模型
GameObject plate = Instantiate(platePrefab, spawnPoint.position, Quaternion.identity);
// 获取模型上的组件
PlateBehavior behavior = plate.GetComponent<PlateBehavior>();
behavior.plateName = "红色盘子"; // 修改属性
// 获取模型上的碰撞体
BoxCollider collider = plate.GetComponent<BoxCollider>();
collider.size = new Vector3(0.5f, 0.1f, 0.5f);
}
}
// 方式2:代码查找
void FindModelComponents()
{
// 按名称查找
GameObject model = GameObject.Find("Plate_01");
// 按标签查找
GameObject[] plates = GameObject.FindGameObjectsWithTag("Tableware");
// 获取子物体中的组件
Transform child = transform.Find("ModelRoot/PlateBody");
Renderer renderer = child.GetComponent<Renderer>();
}
3. 事件回调(碰撞、触发)
public class PlateCollision : MonoBehaviour
{
// 碰撞事件(物理接触)
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Table"))
{
Debug.Log("盘子碰到桌子了");
PlaySound("plate_put_down.wav");
}
}
// 触发事件(穿透检测)
void OnTriggerEnter(Collider other)
{
if (other.CompareTag("TrashArea"))
{
Destroy(gameObject); // 盘子掉进垃圾桶
ScoreManager.Instance.AddScore(-10);
}
}
// 鼠标事件
void OnMouseDown()
{
// 点击模型
DragAndDrop.Instance.StartDragging(this);
}
void OnMouseEnter()
{
// 鼠标悬停高亮
GetComponent<Renderer>().material.color = Color.yellow;
}
}
二、模型与UI的联动
1. 模型状态驱动UI更新
public class PlateStatus : MonoBehaviour
{
public enum State { Clean, Dirty, Broken }
public State currentState = State.Clean;
// 模型状态变化时通知UI
public void SetState(State newState)
{
currentState = newState;
// 更新UI
UIManager.Instance.UpdatePlateStatusUI(gameObject.name, newState);
// 改变模型外观
switch (newState)
{
case State.Clean:
GetComponent<Renderer>().material.color = Color.white;
break;
case State.Dirty:
GetComponent<Renderer>().material.color = Color.gray;
break;
case State.Broken:
Destroy(gameObject);
break;
}
}
}
2. UI按钮控制模型
// UI按钮的OnClick事件绑定
public class ModelController : MonoBehaviour
{
public GameObject targetModel; // 要控制的3D模型
// UI按钮点击时调用
public void RotateModel(float angle)
{
targetModel.transform.Rotate(Vector3.up, angle);
}
public void ChangeModelColor(Color color)
{
targetModel.GetComponent<Renderer>().material.color = color;
}
public void ResetModelPosition()
{
targetModel.transform.position = Vector3.zero;
}
}
三、实战:中餐厅摆台系统的代码结构
// 1. 餐具模型基类
public abstract class Tableware : MonoBehaviour
{
public string itemName;
public Sprite icon; // UI图标
public abstract void PlaceOnTable(Vector3 position);
public abstract void PickUp();
}
// 2. 具体的盘子类
public class Plate : Tableware
{
public override void PlaceOnTable(Vector3 position)
{
transform.position = position;
transform.rotation = Quaternion.identity;
// 播放放置动画
GetComponent<Animator>().SetTrigger("Place");
// 更新UI状态
WorkbenchUI.Instance.RemoveItem(this);
}
public override void PickUp()
{
// 添加到UI工作台
WorkbenchUI.Instance.AddItem(this);
Destroy(gameObject); // 移除3D模型
}
}
// 3. 管理所有模型和UI的交互
public class TableManager : MonoBehaviour
{
public GameObject[] tablewarePrefabs; // 所有餐具预制体
public Transform tableSurface; // 桌子表面
public void SpawnFromUI(string itemName)
{
// 从UI拖拽生成3D模型
foreach (var prefab in tablewarePrefabs)
{
if (prefab.GetComponent<Tableware>().itemName == itemName)
{
GameObject instance = Instantiate(prefab, tableSurface);
instance.transform.localPosition = GetRandomTablePosition();
break;
}
}
}
}
四、模型与代码结合的几种模式
|
模式 |
适用场景 |
实现方式 |
|---|---|---|
|
挂载式 |
单个物体有独立行为 |
脚本直接挂到模型上 |
|
管理器式 |
多个同类物体统一管理 |
一个Manager脚本控制所有模型 |
|
事件驱动 |
模型间交互复杂 |
使用UnityEvent或委托 |
|
MVC模式 |
大型项目 |
Model(数据) - View(模型) - Controller(逻辑) |
五、最佳实践建议
-
预制体(Prefab)是关键
// 做好一个模型+脚本的预制体 public GameObject platePrefab; // 包含PlateBehavior脚本 // 运行时实例化 GameObject plate = Instantiate(platePrefab, spawnPos, Quaternion.identity); -
使用接口(Interface)解耦
public interface IInteractable { void OnInteract(); string GetInfo(); } // 任何模型只要实现这个接口就能被交互 public class Plate : MonoBehaviour, IInteractable { ... } public class Chair : MonoBehaviour, IInteractable { ... } -
通过Inspector可视化绑定
-
模型拖拽到脚本的公开变量
-
使用
[SerializeField]私有变量也能在Inspector显示
-
总结
Unity中模型和C#代码的结合本质上是:
-
模型 = 视觉载体(Mesh、材质、动画)
-
脚本 = 行为逻辑(移动、交互、状态)
-
组件系统 = 桥梁(GetComponent、AddComponent)
一句话:把脚本拖到模型上,或者用代码 AddComponent,模型就有了生命。
更多推荐
所有评论(0)