輸入系統(tǒng)
上一章角色可以做不同的動(dòng)作了闲擦,但是還是原地動(dòng)作慢味,現(xiàn)在我們讓他真正的動(dòng)起來。
控制角色移動(dòng)需要輸入設(shè)備墅冷,PC上一般是用鍵盤控制纯路,手機(jī)用觸摸屏(軟搖桿),其它硬件也有不同的配套輸入設(shè)備,我們要給每種設(shè)備都寫一套事件響應(yīng)邏輯嗎寞忿?顯然不是一個(gè)好主意驰唬,Unity為我們提供了封裝。
以前的Unity版本中有Input,InputManager分別提供了讀取設(shè)備輸入值腔彰,以及通過虛擬軸映射游戲事件的作用叫编,新版本提供了一套新的輸入系統(tǒng)InputSystem.我們就介紹一下新輸入系統(tǒng)的使用方法。
首先打開包管理器: Window->Package Manager,選擇Input System進(jìn)行安裝:
隨后彈出的對(duì)話框中選Yes.
Unity將重新啟動(dòng)并禁用舊版Input Api霹抛,啟用新版Input System.即使這里沒有選Yes搓逾,我們也可以手動(dòng)去切換輸入系統(tǒng),方法是打開項(xiàng)目設(shè)置: Edit->Project Setting->Player->Active Input Handling,選擇Input System Package(New):
遇到問題
好了杯拐,輸入系統(tǒng)切換完成霞篡,運(yùn)行項(xiàng)目,發(fā)現(xiàn)UI不響應(yīng)了端逼,又發(fā)生了什么朗兵?
其實(shí)這是因?yàn)閁I默認(rèn)采用的是老版輸入系統(tǒng)作為其輸入,我們只需要一個(gè)簡(jiǎn)單的設(shè)置就可以解決它顶滩。
在Hierarchy面板選中EventSystem,點(diǎn)擊Inspector面板的 Replace with InputSystemUIInputModule.然后再運(yùn)行項(xiàng)目,UI又恢復(fù)響應(yīng)了余掖。
控制角色
新輸入系統(tǒng)準(zhǔn)備好了,現(xiàn)在要開始控制角色了.
控制角色有多種方式礁鲁,可以用物理引擎控制浊吏,可以用Untiy提供的CharacterController來控制,我們?yōu)榱藢W(xué)習(xí)救氯,嘗試自己實(shí)現(xiàn)一個(gè)簡(jiǎn)單的:
先給角色加一個(gè)Player Input組件:
在紅框位置有一個(gè)CreateActions的按鈕找田,按一下,選擇文件位置着憨,會(huì)創(chuàng)建一個(gè)Input Action Assets墩衙,同時(shí)會(huì)打開左邊的面板。這里面定義好了一些Action,以及對(duì)輸入設(shè)備的映射甲抖。
寫邏輯的時(shí)候漆改,只要處理Action就好了,而不用管具體的是鍵盤輸入的准谚,還是手柄搖桿挫剑,達(dá)到了輸入和邏輯相分離的目的。
邏輯代碼和Action關(guān)聯(lián)的方式有多種柱衔,可以通過Player Input組件的Behavior來控制,它表示當(dāng)有動(dòng)作觸發(fā)時(shí)的響應(yīng)方式:
- Send Messages
- Broadcast Messages
- Unity Events
- CSharp Events
這四種觸發(fā)模式樊破,從效率上看愉棱,Broadcast Messsages < Send Messages < Unity Events < Csharp Events。
前兩種很好接入哲戚,只要在腳本中添加 On{ActionName}()函數(shù)就可以奔滑。
Unity Events 要在 Inspector 中分配各種回調(diào)函數(shù),可視化操作顺少,對(duì)新手友好朋其,但在函數(shù)和動(dòng)作邏輯較多時(shí)比較麻煩。
最后一個(gè)比較高效脆炎,但是所有的動(dòng)作共享同一個(gè)回調(diào)事件 event Action<InputAction.CallbackContext> onActionTriggerd梅猿,需要在這個(gè)函數(shù)中自行區(qū)分具體的觸發(fā)動(dòng)作。
具體的接入方式可以參考Input System提供的Demo: 打開包管理器秒裕,選中Input System,在右邊面板選中要查看的Demo,然后點(diǎn)擊Import按鈕(非必須):
現(xiàn)在我們來創(chuàng)建自己的角色控制邏輯袱蚓,創(chuàng)建一個(gè)名為SimpleActorController的腳本,掛載到角色身上簇爆,代碼如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class SimpleActorController : MonoBehaviour
{
public float moveSpeed; //角色移動(dòng)速度
private InputAction m_MoveAction;
private Animator animator;
private Vector3 rotationVector;
private Vector2 m_Move;
// Start is called before the first frame update
void Start()
{
animator = GetComponent<Animator>();
if (m_MoveAction == null)
{
PlayerInput input = GetComponent<PlayerInput>();
m_MoveAction = input.actions["move"];
}
}
private void Update()
{
MoveActor();
}
//移動(dòng)角色
public void MoveActor()
{
bool isMoving = false;
if (m_MoveAction != null && m_MoveAction.IsPressed())
{
m_Move = m_MoveAction.ReadValue<Vector2>();
if(m_Move.sqrMagnitude > 0.1f)
{
Vector2 moveVector = m_Move * (moveSpeed * Time.deltaTime);
//求前進(jìn)的方向
Vector3 dir = Camera.main.transform.localToWorldMatrix.MultiplyVector(new Vector3(moveVector.x, 0, moveVector.y));
dir.y = 0f;
dir = dir.normalized;
//把角色轉(zhuǎn)向前進(jìn)方向
transform.forward = Vector3.SmoothDamp(transform.forward, dir, ref rotationVector, 0.1f);
transform.position = transform.position + dir * moveVector.magnitude;
isMoving = true;
}
}
animator.SetFloat("speed", isMoving ? moveSpeed : 0.0f);
}
}
可以看到癞松,我們用最簡(jiǎn)便快捷的方式,在Update函數(shù)中直接檢測(cè)Action是否被按下入蛆,實(shí)際項(xiàng)目中不建議這么做响蓉。
然后在Inspector面板中設(shè)置移動(dòng)速度為5左右,現(xiàn)在運(yùn)行程序哨毁,并嘗試按方向按鈕或者ASDW鍵枫甲,可以看到角色動(dòng)起來了。
再遇問題
角色是可以移動(dòng)了扼褪,但是好像反應(yīng)遲鈍想幻,先滑步好長(zhǎng)距離,才開始跑步话浇,停下的時(shí)候也原地踏步半天才停下脏毯,這是什么原因呢?
我們?cè)趯?shí)際項(xiàng)目中經(jīng)常會(huì)遇到類似的狀況幔崖,明明覺得該做的都做了食店,但總會(huì)出現(xiàn)一些意外。這就要考驗(yàn)大家知識(shí)掌握的是否扎實(shí)赏寇,或者經(jīng)驗(yàn)是否老到吉嫩。你可能會(huì)記起在學(xué)習(xí)Animator Controller的時(shí)候,有個(gè)Has Exit Time的選項(xiàng)嗅定,用來控制角色是否一定要播完上一個(gè)動(dòng)作自娩,再切換到下一個(gè)動(dòng)作,目前這個(gè)現(xiàn)象很像是勾選了這個(gè)選項(xiàng)造成的渠退,打開我們的RoleController,點(diǎn)擊Idle狀態(tài)忙迁,在Inspector面板中查看脐彩,果然是勾選狀態(tài),去掉勾選动漾。
我們還要能夠舉一反三丁屎,想想還有沒有類似的問題荠锭,好像子狀態(tài)機(jī)里面還有狀態(tài)旱眯,好打開后進(jìn)行同樣的操作,保存再試.
"果然好了证九,不那么遲鈍了删豺。可是為什么攝像機(jī)不跟著角色走呀愧怜?"
因?yàn)槲覀冞€沒有寫攝像機(jī)控制的代碼呀呀页,游戲界有個(gè)名詞叫 "3C" 就是 "Character Camera Control(角色、相機(jī)拥坛、控制)" 三個(gè)單詞的縮寫, 它的好壞直接影響到游戲體驗(yàn)蓬蝶,是游戲中十分重要的功能,我們的SimpleActorController是幫助大家入門猜惋,所以寫的越簡(jiǎn)單越好丸氛,真正項(xiàng)目中要復(fù)雜的多,就等你去完善了著摔。
說到攝像機(jī)控制缓窜,我們下章再來實(shí)現(xiàn)吧。
同樣給出本章項(xiàng)目連接 角色控制系統(tǒng)
返回主目錄
【轉(zhuǎn)載請(qǐng)注明出處】