unity中第三人称下使用手柄控制角色移动
本文建议结合这一篇文章观看:
https://blog.csdn.net/qq_45919090/article/details/109393562
unity2017及以上的版本在插入手柄时unity会自动识别手柄,其默认的输入方式及按键配置可以在Edit–>Project Settings–>Input中的Inspector面板中找到并可进行自定义修改,为了与键盘及鼠标的输入方式区分,我们做如下设置:
左摇杆:
右摇杆:
十字键:
LT和RT:
其按键若不清楚其代号,可以通过以下脚本进行按键检测:
public class GetKeyValue : MonoBehaviour {
public float speed = 10.0F;
public float rotationSpeed = 100.0F;
void Update()
{
detectPressedKeyOrButton();
}
public void detectPressedKeyOrButton()
{
foreach (KeyCode kcode in System.Enum.GetValues(typeof(KeyCode)))
{
if (Input.GetKeyDown(kcode))
Debug.Log("KeyCode down: " + kcode);
}
}
}
可以得到:
按键 | 代号 | 按键 | 代号 |
---|---|---|---|
A | JoystickButton0 | RB | JoystickButton5 |
B | JoystickButton1 | Back | JoystickButton6 |
X | JoystickButton2 | Start | JoystickButton7 |
Y | JoystickButton3 | 左摇杆按下 | JoystickButton8 |
LB | JoystickButton4 | 右摇杆按下 | JoystickButton9 |
实现角色按摇杆方向移动
(注:以下脚本的绑定对象为游戏角色即Charactor)
对于场景中的角色Charactor,想要改变其移动的方向,就需要改变其旋转角度,这里可以用局部欧拉角LocalEulerAngles。但如果直接把摇杆返回的向量(L_H,0,L_V)赋值给charactor.forward会在镜头发生旋转后方向错乱,这里使用的方法是创建一个空物体forward,使forwa.position等于charactor.position,再把手柄返回的向量赋值给forward的前方向。
在文章开头放出的帖子中,可以得到用于控制相机的的两个父物体Empty和Position,为了实现旋转,可以做如下设置。
定义一个方法,使forward的位置等于角色的位置,使forward的forward方向等于手柄的向量,最后让角色的LocalEulerAngles等于empty的局部欧拉角加上forward的局部欧拉角
private void ApplyRotate()
{
forward.position = transform.position;
//forward.forward = new Vector3(L_H, 0, L_V);
forward.forward = Vector3.Lerp(forward.forward, new Vector3(L_H, 0, L_V), 0.3f);
transform.localEulerAngles = empty.localEulerAngles + forward.localEulerAngles;
}
接着获取手柄向量使角色移动,在角色的状态机中做如下设置:
方法不唯一,切换条件可以根据自己的动画进行设置,也可以直接使用混合树进行计算
Move方法如下,写法也不唯一,此处是为了让手柄的左摇杆按下时角色可以在行走及奔跑状态间切换
void Move()
{
if (Mathf.Abs(L_H) > 0.02f || Mathf.Abs(L_V) > 0.02f)
{
if (Input.GetKeyDown(KeyCode.JoystickButton8))
{
if (anim.GetFloat("Speed") < 2)
{
anim.SetFloat("Speed", 5);
ApplyRotate();
shift = true;
anim.SetBool("IsShift", shift);
}
else if (anim.GetFloat("Speed") > 4.8f)
{
anim.SetFloat("Speed", 1.4f);
ApplyRotate();
shift = false;
anim.SetBool("IsShift", shift);
}
}
else
{
if (anim.GetFloat("Speed") > 4.8f)
{
anim.SetFloat("Speed", 5);
ApplyRotate();
shift = true;
anim.SetBool("IsShift", shift);
}
else if (anim.GetFloat("Speed") < 2)
{
anim.SetFloat("Speed", 1.4f);
ApplyRotate();
shift = false;
anim.SetBool("IsShift", shift);
}
}
}
else
{
anim.SetFloat("Speed", 0);
}
}
在Update中调用方法即可
void Update()
{
L_H = Input.GetAxis("Horizontal_Left");
L_V = Input.GetAxis("Vertical_Left");
shift = false;
Move();
}