
前言
還一直在手搓角色控制模組?今天推薦一個 Unity 的免費插件 Starter Assets,可以輕鬆實現 【第一人稱】 和 【第三人稱】的角色控制,在不用書寫任何代碼的情況下,整套角色控制模組就包括了【基本移動奔跑跳躍】、【相機跟隨】、【角色動畫】、【腳步聲】、【物理系統】和【移動端支援】等功能,如果你的專案對角色控制要求不高,我很推薦你使用它,可以快速開始你的第一個人稱專案。
本篇文章將帶你了解 【模組應用】 與 【應用場景】,並分享 【實用技巧】,讓你快速上手,輕鬆打造專業級的角色控制系統!

Unity Starter Assets 插件介紹
Starter Assets 作為一款由 Unity 官方提供的角色控制模組,能幫助開發者【快速搭建角色控制系統】、【簡化輸入處理】,省去繁瑣的邏輯實作,專注於【遊戲內容】與【玩法設計】,讓角色操作更順暢自然。
Starter Assets 角色控制插件內建了【移動】、【跳躍】、【衝刺】及【攝影機跟隨】等功能,並支援【鍵盤】、【滑鼠】與【手把】操作,不論是【FPS】、【動作冒險】還是【開放世界】遊戲,都能輕鬆適用。


功能特色
- 內建完整角色控制系統
提供【第一】和【第三】人稱角色控制,包含【移動】、【跳躍】、【衝刺】、【相機跟隨】等功能,無需撰寫額外代碼即可使用。 - 多設備輸入支援
內建 Unity Input System,支援【鍵盤】、【滑鼠】、【手把控制】,適用於【PC】及【主機遊戲】開發。 - 流暢相機跟隨
內建相機控制模組,提供【視角靈敏度調整】、【視角鎖定】,提升遊戲【操作體驗】與【沉浸感】。
適用場景
- FPS 及第三人稱動作遊戲
適用於【射擊】、【動作冒險】等需要順暢角色操作的遊戲類型。 - 開放世界與沙盒遊戲
支援【自由視角控制】、【角色移動與交互】,適合開放世界探索型遊戲。 - 快速原型開發
適合獨立遊戲【開發者】及【團隊】用於快速搭建角色控制系統,省去繁瑣的基礎開發工作。

Unity Starter Assets 第三人稱
1、下載資產
Asset Store下載連結:Starter Assets - ThirdPerson

2、限制

3、導入

4、使用
開啟示範場景,就可以使用了,按住 shift 就是跑。

5.替換模型
換上新模型,調整大小。

刪除本身模型。

換一個骨骼。

效果如下。

Unity Starter Assets 第一人稱
1、資產下載
Asset Store下載連結:Starter Assets - FirstPerson

2、限制

3、使用
開啟示範場景,就可以使用了,按住 shift 就是跑。

Unity Starter Assets 行動端支持
開啟虛擬搖桿 UI 即可。



Unity Starter Assets 瞄準射擊
1.新增瞄準相機
複製一個第三人稱虛擬相機出來,做我們的瞄準相機,修改參數。

2、綁定按鈕輸入控制
我們新增一個跟控制跑一樣的按鈕。


修改 StarterAssetsInputs 程式碼,直接參考 sprint,做一樣的事情就行了。



3.相機切換
新增腳本 ThirdPersonShooterController,控制第三人稱瞄準相機切換。

實際測試。

現在相機切換過渡太慢了,可以修改相機轉換時間加快。

4.靈敏度配置
目前預設狀態和瞄準狀態視角下的靈敏度一樣,這明顯不是我們要的,我們希望瞄準狀態下視角靈敏度低一些,方便我們射擊擊中目標
修改 ThirdPersonController 程式碼,新增控制相機靈敏度變數。



修改 ThirdPersonshooterController,實現不同狀態下不同靈敏度配置。

5.瞄準輔助十字形圖標
這個很簡單,只要在螢幕中心放置一個圖示 UI 就可以了,這裡就不多介紹了。
準心圖片開始。

準心圖結束。

6.射線檢測
修改 ThirdPersonshooterController,用射線偵測像螢幕中心點前發射射線,偵測碰撞的物體。

製作一個瞄準球體做顯示點。

效果如下。

記得刪除測試球體的碰撞體。

7.瞄準遠處的問題
例如我們瞄準天空,就是失去目標了。

當然這裡我們可以選擇最簡單粗暴的方式就是給天上加入空氣牆就可以了
或者可以設定為遠離視野的點 Camera.main.transform.position + Camera.main.transform.forward * 100f,這樣就不需要添加空氣牆
碰撞器了。(記得下面的其他步驟也要記得更改)
// 發射射線並檢測碰撞
if (Physics.Raycast(ray, out RaycastHit raycastHit, 999f, aimColliderLayerMask))
{
// 在調試Transform的位置上設置擊中點
debugTransform.position = raycastHit.point;
}
else
{
// 或者可以設置為一個遠離視野的點,例如:
debugTransform.position = Camera.main.transform.position + Camera.main.transform.forward * 100f;
}
8.瞄準角色朝向
瞄準模式下,角色應該要一直面向瞄準方向。
修改 ThirdPersonshooterController,優化程式碼。


但是移動起來,還是出問題,因為移動時角色也試圖旋轉到對應的方向。
修改 ThirdPersonController,新增變數禁止腳本上的旋轉。



修改 ThirdPersonshooterController,瞄準狀態禁止腳本上的旋轉。

效果如下。

9、實體子彈射擊
參考文章:【unity实战】实现实体子弹射击
新增子彈預製體。

新增子彈腳本 BulletProjectile,掛載在前面的子彈預製體上。
public class BulletProjectile : MonoBehaviour {
private Rigidbody bulletRigidbody;
private void Awake() {
bulletRigidbody = GetComponent<Rigidbody>();
}
private void Start() {
float speed = 50f;
bulletRigidbody.velocity = transform.forward * speed;
}
private void OnTriggerEnter(Collider other) {
Destroy(gameObject);
}
}
綁定設計按鈕,這裡主要是滑鼠左鍵點擊射擊。

修改 StarterAssetsInputs,監聽射擊按鈕輸入。



修改 ThirdPersonShooterController,定義子彈和子彈生成位置,射擊功能。


10.添加擊中特效效果
擊中特效就大家自己去實現和製作吧。
public class BulletProjectile : MonoBehaviour {
[SerializeField] private Transform vfxHitGreen;
[SerializeField] private Transform vfxHitRed;
private Rigidbody bulletRigidbody;
private void Awake() {
bulletRigidbody = GetComponent<Rigidbody>();
}
private void Start() {
float speed = 50f;
bulletRigidbody.velocity = transform.forward * speed;
}
private void OnTriggerEnter(Collider other) {
if (other.GetComponent<BulletTarget>() != null) {
// Hit target
Instantiate(vfxHitGreen, transform.position, Quaternion.identity);
} else {
// Hit something else
Instantiate(vfxHitRed, transform.position, Quaternion.identity);
}
Destroy(gameObject);
}
}

11、使用射線投射實現射擊
參考文章:【unity实战】一个通用的FPS枪支不同武器射击控制脚本
修改 ThirdPersonShooterController。


效果,開槍會立即擊中目標。

12、兩種射擊的問題
隔著牆壁射擊,子彈射擊會被牆壁擋住,而射線投射不會。


這裡並沒有說使用哪種方式更好,具體選擇看自己的需求,見仁見智。
13、瞄準動畫
我們新增動畫圖層,透過改變這個層權重實現瞄準效果。

修改 ThirdPersonShooterController 程式碼。

效果如下。

14.最終程式碼 ThirdPersonShooterController
這裡貼出 ThirdPersonShooterController 參考程式碼。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;
using StarterAssets;
using UnityEngine.InputSystem;
public class ThirdPersonShooterController : MonoBehaviour {
[SerializeField] private CinemachineVirtualCamera aimVirtualCamera; // 瞄准虚拟相机
[SerializeField] private float normalSensitivity; // 普通灵敏度
[SerializeField] private float aimSensitivity; // 瞄准灵敏度
[SerializeField] private LayerMask aimColliderLayerMask = new LayerMask(); // 瞄准碰撞层
[SerializeField] private Transform debugTransform; // 调试用的Transform,用于显示射线击中点
[SerializeField] private Transform pfBulletProjectile; // 子弹预制体
[SerializeField] private Transform spawnBulletPosition; // 发射子弹的位置
[SerializeField] private Transform vfxHitGreen; // 击中目标效果(绿色)
[SerializeField] private Transform vfxHitRed; // 击中其他物体效果(红色)
private ThirdPersonController thirdPersonController; // 第三人称控制器组件
private StarterAssetsInputs starterAssetsInputs; // 输入控制组件
private Animator animator; // 动画控制器
private void Awake() {
// 初始化组件
thirdPersonController = GetComponent<ThirdPersonController>();
starterAssetsInputs = GetComponent<StarterAssetsInputs>();
animator = GetComponent<Animator>();
}
private void Update() {
Vector3 mouseWorldPosition = Vector3.zero; // 鼠标在世界中的位置
// 计算屏幕中心点的射线
Vector2 screenCenterPoint = new Vector2(Screen.width / 2f, Screen.height / 2f);
Ray ray = Camera.main.ScreenPointToRay(screenCenterPoint);
Transform hitTransform = null;
// 发射射线并检查是否击中物体
if (Physics.Raycast(ray, out RaycastHit raycastHit, 999f, aimColliderLayerMask)) {
// 射线击中物体
debugTransform.position = raycastHit.point; // 更新调试Transform位置
mouseWorldPosition = raycastHit.point; // 鼠标位置设置为击中点
hitTransform = raycastHit.transform; // 记录击中的物体
} else {
// 射线没有击中任何物体
mouseWorldPosition = Camera.main.transform.position + Camera.main.transform.forward * 100f; // 默认鼠标位置在前方远处
}
if (starterAssetsInputs.aim) {
// 进入瞄准模式
aimVirtualCamera.gameObject.SetActive(true); // 启用瞄准相机
thirdPersonController.SetSensitivity(aimSensitivity); // 设置瞄准灵敏度
thirdPersonController.SetRotateOnMove(false); // 瞄准时禁用移动旋转
animator.SetLayerWeight(1, Mathf.Lerp(animator.GetLayerWeight(1), 1f, Time.deltaTime * 13f)); // 平滑过渡动画层权重
Vector3 worldAimTarget = mouseWorldPosition;
worldAimTarget.y = transform.position.y; // 保持瞄准目标与玩家在同一水平面上
Vector3 aimDirection = (worldAimTarget - transform.position).normalized; // 计算瞄准方向
// 平滑地旋转玩家朝向瞄准方向
transform.forward = Vector3.Lerp(transform.forward, aimDirection, Time.deltaTime * 20f);
} else {
// 退出瞄准模式
aimVirtualCamera.gameObject.SetActive(false); // 禁用瞄准相机
thirdPersonController.SetSensitivity(normalSensitivity); // 恢复普通灵敏度
thirdPersonController.SetRotateOnMove(true); // 恢复移动旋转
animator.SetLayerWeight(1, Mathf.Lerp(animator.GetLayerWeight(1), 0f, Time.deltaTime * 13f)); // 平滑过渡动画层权重
}
if (starterAssetsInputs.shoot) {
/*
//实体子弹射击
if (hitTransform != null) {
// 击中目标
if (hitTransform.GetComponent<BulletTarget>() != null) {
// 击中目标对象
Instantiate(vfxHitGreen, mouseWorldPosition, Quaternion.identity); // 实例化绿色击中效果
} else {
// 击中其他物体
Instantiate(vfxHitRed, mouseWorldPosition, Quaternion.identity); // 实例化红色击中效果
}
}
//*/
//*
// Projectile Shoot(射线投射物射击)
Vector3 aimDir = (mouseWorldPosition - spawnBulletPosition.position).normalized; // 计算投射物方向
Instantiate(pfBulletProjectile, spawnBulletPosition.position, Quaternion.LookRotation(aimDir, Vector3.up)); // 实例化子弹并设置其朝向
//*/
starterAssetsInputs.shoot = false; // 重置射击输入
}
}
}
Unity Starter Assets 文章參考影片
Awesome Third Person Shooter Controller! (Unity Tutorial)
徒手搓第三人称控制器?我劝你对自己好一点!
Unity Starter Assets 相關介紹 & 教學影片
Starter Assets overview | Unity
Unity Starter Assets In-Depth Overview | 1st & 3rd Person Controller w/ Input System & Cinemachine
UNITY | THIRD PERSON CHARACTER CONTROLLER - STARTER ASSETS
Unity Starter Assets 角色控制模組相關網站 & 插件下載點
【Starter Assets】
Asset Store下載連結:Starter Assets - ThirdPerson
Asset Store下載連結:Starter Assets - FirstPerson
————————————————
更多好用插件:【Unity 好用插件推薦】持續更新,一起讓遊戲開發事半功倍!
本文原創(或整理)於亞洲電玩通,未經作者與本站同意不得隨意引用、轉載、改編或截錄。
特約作家簡介
支持贊助 / DONATE
亞洲電玩通只是很小的力量,但仍希望為復甦台灣遊戲研發貢獻一點動能,如果您喜歡亞洲電玩通的文章,或是覺得它們對您有幫助,歡迎給予一些支持鼓勵,不論是按讚追蹤或是贊助,讓亞洲電玩通持續產出,感謝。
BTC |
![]() |
352Bw8r46rfXv6jno8qt9Bc3xx6ptTcPze |
|
ETH |
![]() |
0x795442E321a953363a442C76d39f3fbf9b6bC666 |
|
TRON |
![]() |
TCNcVmin18LbnXfdWZsY5pzcFvYe1MoD6f |