跳到主要内容

3D 游戏开发

Unity 最初就是作为 3D 引擎诞生的,其 3D 开发功能非常强大。本章将介绍 3D 游戏开发的核心概念。

3D 基础概念

坐标系

Unity 使用左手坐标系:

  • X 轴:水平方向(右为正)
  • Y 轴:垂直方向(上为正)
  • Z 轴:深度方向(前为正)
        Y (上)

│ Z (前)
│ ╱
│ ╱
│ ╱
└────────── X (右)

3D 对象基础组件

每个 3D 对象通常包含:

GameObject
├── Transform - 位置、旋转、缩放
├── Mesh Filter - 网格数据
├── Mesh Renderer - 渲染器
└── Collider - 碰撞器(可选)

3D 模型

支持的模型格式

格式说明
FBX推荐格式,支持动画、材质
OBJ简单格式,仅几何体
3DS3ds Max 格式
DAE (COLLADA)交换格式
GLTF/GLB现代 Web 格式

导入设置

选中模型文件,Inspector 中的关键设置:

Model 标签:

  • Scale Factor:缩放系数
  • Mesh Compression:网格压缩级别
  • Read/Write Enabled:允许代码读写网格
  • Generate Colliders:自动生成碰撞器

Rig 标签(动画):

  • Animation Type:动画类型
    • None - 无动画
    • Legacy - 旧版动画
    • Generic - 通用动画(非人形)
    • Humanoid - 人形动画(可重定向)

Materials 标签:

  • Extract Materials:提取材质到项目
  • Texture Import:纹理导入设置

Mesh(网格)

Mesh 是 3D 物体的几何形状,由顶点、边和面组成。

Mesh Filter 和 Mesh Renderer

public class MeshManipulation : MonoBehaviour
{
public MeshFilter meshFilter;
public MeshRenderer meshRenderer;

void Start()
{
// 更换网格
meshFilter.mesh = someOtherMesh;

// 修改材质
meshRenderer.material = newMaterial;
meshRenderer.material.color = Color.red;

// 启用/禁用渲染
meshRenderer.enabled = false;
}
}

程序化生成 Mesh

public class ProceduralMesh : MonoBehaviour
{
void Start()
{
Mesh mesh = new Mesh();

// 定义顶点
Vector3[] vertices = new Vector3[]
{
new Vector3(0, 0, 0),
new Vector3(1, 0, 0),
new Vector3(0, 1, 0),
new Vector3(1, 1, 0)
};

// 定义三角形(顺时针为正面)
int[] triangles = new int[]
{
0, 2, 1, // 第一个三角形
2, 3, 1 // 第二个三角形
};

// 定义 UV
Vector2[] uv = new Vector2[]
{
new Vector2(0, 0),
new Vector2(1, 0),
new Vector2(0, 1),
new Vector2(1, 1)
};

mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.uv = uv;

// 重新计算法线
mesh.RecalculateNormals();

GetComponent<MeshFilter>().mesh = mesh;
}
}

材质与纹理

Material(材质)

材质定义了物体表面的外观属性。

常用 Shader

Shader用途
StandardPBR 物理渲染,最常用
Standard (Specular)高光工作流程
Unlit不受光照影响,用于 UI、特效
Particles粒子效果
Skybox天空盒

PBR 材质属性

public class MaterialController : MonoBehaviour
{
public Material material;

void Start()
{
// 基础颜色
material.SetColor("_Color", Color.white);

// 金属度 (0-1)
material.SetFloat("_Metallic", 0.5f);

// 光滑度 (0-1)
material.SetFloat("_Glossiness", 0.5f);

// 法线贴图强度
material.SetFloat("_BumpScale", 1f);
}
}

纹理类型

纹理说明
Albedo/Diffuse基础颜色
Normal Map法线贴图,模拟表面凹凸
Metallic金属度贴图
Roughness/Smoothness粗糙度/光滑度贴图
Occlusion环境光遮蔽
Emission自发光

光照系统

光源类型

// 代码创建光源
public class LightController : MonoBehaviour
{
void CreateLight()
{
GameObject lightGO = new GameObject("MyLight");
Light light = lightGO.AddComponent<Light>();

light.type = LightType.Point; // 点光源
light.color = Color.yellow;
light.intensity = 1.5f;
light.range = 10f;
}
}
光源类型特点
Directional平行光,模拟太阳光,无位置只有方向
Point点光源,向四面八方发光,如灯泡
Spot聚光灯,圆锥形光照,如手电筒
Area区域光,矩形发光面,仅烘焙可用

光照模式

  • Realtime:实时光照,动态计算
  • Mixed:混合模式,部分烘焙部分实时
  • Baked:完全烘焙,性能最好但不动态

全局光照(GI)

Window > Rendering > Lighting
  • Baked GI:预计算静态物体的光照
  • Realtime GI:实时全局光照
  • Reflection Probes:反射探头,捕捉环境反射

3D 物理

Rigidbody 3D

public class Physics3DController : MonoBehaviour
{
public Rigidbody rb;

void Start()
{
// 设置质量
rb.mass = 2f;

// 设置阻力
rb.drag = 0.5f;

// 使用重力
rb.useGravity = true;

// 是否受物理影响
rb.isKinematic = false;
}

void Update()
{
// 施加力
rb.AddForce(Vector3.forward * 10f);

// 施加扭矩(旋转)
rb.AddTorque(Vector3.up * 5f);

// 直接设置速度
rb.velocity = new Vector3(0, 5, 0);

// 爆炸效果
rb.AddExplosionForce(1000f, explosionPos, 10f);
}
}

3D 碰撞器

碰撞器用途
Box Collider立方体碰撞
Sphere Collider球体碰撞
Capsule Collider胶囊体碰撞
Mesh Collider网格碰撞(精确但性能低)
Terrain Collider地形碰撞
Wheel Collider车轮碰撞(载具专用)

物理材质

创建 Physic Material 控制摩擦和弹性:

属性说明
Dynamic Friction动态摩擦系数
Static Friction静态摩擦系数
Bounciness弹性(0-1)
Friction Combine摩擦组合方式
Bounce Combine弹性组合方式

地形系统(Terrain)

创建地形

  1. GameObject > 3D Object > Terrain
  2. 在 Inspector 中使用地形工具

地形工具

工具功能
Raise/Lower升高/降低地形
Paint Height绘制特定高度
Smooth Height平滑地形
Paint Texture绘制纹理图层
Paint Trees种植树木
Paint Details绘制草和细节
Settings地形设置

地形组件代码

public class TerrainModifier : MonoBehaviour
{
public Terrain terrain;

void ModifyTerrain()
{
TerrainData terrainData = terrain.terrainData;

// 获取高度图
float[,] heights = terrainData.GetHeights(0, 0,
terrainData.heightmapResolution,
terrainData.heightmapResolution);

// 修改高度
heights[50, 50] = 0.5f; // 0-1 范围

// 应用修改
terrainData.SetHeights(0, 0, heights);
}
}

相机系统

Camera 组件

public class CameraController3D : MonoBehaviour
{
public Camera cam;
public Transform target;

void Start()
{
// 设置背景色
cam.backgroundColor = Color.black;

// 设置视场角
cam.fieldOfView = 60f;

// 设置裁剪面
cam.nearClipPlane = 0.3f;
cam.farClipPlane = 1000f;

// 正交模式(2.5D 游戏常用)
cam.orthographic = false;
cam.orthographicSize = 5f;
}

// 第三人称跟随
void LateUpdate()
{
Vector3 offset = new Vector3(0, 5, -10);
transform.position = target.position + offset;
transform.LookAt(target);
}
}

多相机设置

public class MultiCameraSetup : MonoBehaviour
{
public Camera mainCamera;
public Camera minimapCamera;

void SetupCameras()
{
// 主相机
mainCamera.depth = 0;
mainCamera.rect = new Rect(0, 0, 1, 1);

// 小地图相机
minimapCamera.depth = 1;
minimapCamera.rect = new Rect(0.7f, 0.7f, 0.25f, 0.25f);
minimapCamera.clearFlags = CameraClearFlags.Depth;
}
}

天空盒与雾效

天空盒设置

public class EnvironmentSetup : MonoBehaviour
{
public Material skyboxMaterial;

void Start()
{
// 设置天空盒
RenderSettings.skybox = skyboxMaterial;

// 设置环境光
RenderSettings.ambientMode = UnityEngine.Rendering.AmbientMode.Skybox;
RenderSettings.ambientIntensity = 1f;

// 设置雾
RenderSettings.fog = true;
RenderSettings.fogMode = FogMode.Exponential;
RenderSettings.fogColor = Color.gray;
RenderSettings.fogDensity = 0.01f;
}
}

实践:简单的 3D 第三人称控制器

public class ThirdPersonController : MonoBehaviour
{
[Header("移动")]
public float moveSpeed = 5f;
public float rotationSpeed = 10f;

[Header("跳跃")]
public float jumpForce = 8f;
public LayerMask groundLayer;

[Header("组件")]
public Rigidbody rb;
public Transform cameraTransform;
public Transform groundCheck;

private bool isGrounded;
private Vector3 moveDirection;

void Update()
{
// 地面检测
isGrounded = Physics.CheckSphere(groundCheck.position, 0.3f, groundLayer);

// 获取输入
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");

// 计算移动方向(相对于相机)
Vector3 forward = cameraTransform.forward;
Vector3 right = cameraTransform.right;
forward.y = 0;
right.y = 0;
forward.Normalize();
right.Normalize();

moveDirection = forward * vertical + right * horizontal;

// 跳跃
if (Input.GetButtonDown("Jump") && isGrounded)
{
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
}

// 旋转角色
if (moveDirection != Vector3.zero)
{
Quaternion targetRotation = Quaternion.LookRotation(moveDirection);
transform.rotation = Quaternion.Slerp(transform.rotation,
targetRotation, rotationSpeed * Time.deltaTime);
}
}

void FixedUpdate()
{
// 应用移动
rb.MovePosition(rb.position + moveDirection * moveSpeed * Time.fixedDeltaTime);
}
}

下一步

掌握 3D 开发基础后,你可以:

  1. 学习 动画系统 制作角色动画
  2. 了解 渲染管线 优化画面效果
  3. 探索 Shader 基础 创建自定义材质
  4. 学习 光照与阴影 提升场景氛围