c# - 如何在 Unity 运行时使用新的输入系统切换动作映射?
问题描述
我目前有一个设置,玩家可以使用 WASD 向前、向左、向右和向后移动。基本的东西。
public class Player : MonoBehaviour
{
public InputMaster controls;
private float playerSpeed = 4f;
{
controls = new InputMaster();
controls.PlayerN.Movement.performed += ctx => Movement(ctx.ReadValue<Vector2>());
controls.PlayerN.Movement.performed += ctx => move = ctx.ReadValue<Vector2>();
controls.PlayerN.Movement.canceled += ctx => move = Vector2.zero;
}
void Update()
{
Vector2 inputVector = controls.PlayerN.Movement.ReadValue<Vector2>();
inputVector = new Vector2(move.x, move.y) * Time.deltaTime * playerSpeed;
Vector3 finalVector = new Vector3();
finalVector.x = inputVector.x;
finalVector.z = inputVector.y;
transform.Translate(finalVector, Space.World);
private void OnEnable()
{
controls.Enable();
}
private void OnDisable()
{
controls.Disable();
}
}
}
以上是我一直在称运动的方式。你可能会注意到 actionmap 被称为PlayerN
,那是因为我总共有 4 个 action map,我希望玩家在相机围绕玩家旋转 90 度时切换到下一个(北、东、南、西方)。例如,我的名为“PlayerE”的动作图在 W 上向左移动,在 S 上向右移动,在 A 上向下移动,在 D 上向上移动。我只是重新调整了 WASD 键的方向。
我目前不知道如何切换到不同的动作图。我查看了新输入系统的文档,但找不到任何好的信息。
我有一个关于如何解决这个问题的想法,但我不知道我是否走在正确的轨道上。我有一个 switch 循环,它检查另一个名为 的脚本中的 int camDirection
,我将这部分放在我的void Update()
函数中。
switch (refScript.camDirection)
{
case -3:
Debug.Log("Facing East");
break;
case -2:
Debug.Log("Facing South");
break;
case -1:
Debug.Log("Facing West");
break;
case 0:
Debug.Log("Facing North");
break;
case 1:
Debug.Log("Facing East");
break;
case 2:
Debug.Log("Facing South");
break;
case 3:
Debug.Log("Facing West");
break;
}
无论如何,我目前坚持这一点,所以如果有人有任何想法如何解决这个问题,我会非常感激。
解决方案
好的,我将按照您在评论中的要求发布一个计算 3D 空间中玩家移动的代码。
首先,假设我们在同一个坐标系中:X - 左(-X 是右) Y - 上(-Y = 下) Z - 前(-Z = 后)。然后你需要有 3 个字段(类级别的变量):
//Actual position of the player in 3d space
Vector3 _playerPosition;
// The point in 3d space at which the player is looking right now
// If he can move only horizontally - the Y coordinate can be locked.
Vector3 _playerLooksAt;
// Last known mouse position
Vector2 _lastMousePosition;
然后在您的 Update 方法中执行以下操作:
void Update()
{
// You need to where the Player should be moved, like that:
// Vector2 inputVector = controls.PlayerN.Movement.ReadValue<Vector2>();
// But I do not know what did you have there, so usually I read them from
// AWSD keys:
float x = 0, z = 0;
var pressedKey = Keyboard.GetPressedKey(); // depends on your platform
if (pressedKey == "W") // move forward
{
z = 1;
}
if (pressedKey == "A") // move left
{
x = 1;
}
// and for remaining keys similar code, but assign -1 accordingly.
var inputVectorForMovement = new Vector3(x, 0, z);
// Then you have to get rotation angle, again I do not know how you do it,
// but it is usually obtained from mouse movement:
var currentMousePosition = Mouse.GetPosition(); // depends on your platform
// I just did simple approximation here to rotate on the angle of 45 degrees converted to radians per 100 pixels of mouse movement:
var horizontalRotationAngleRadians = Math.Pi/4f * (currentMousePosition.X - _lastMousePosition.X) / 100f;
// Create rotation matrix assuming Y is up vector:
var rotationMatrixForPlayerDirection = Matrix.CreateRotationY(horizontalRotationAngleRadians);
// Calculate player direction:
var playerDirection = _playerLooksAt - _playerPosition;
// Normalize it*, so the direction vector will have coefficients per each axis indicating how much the position should be moved to either side:
playerDirection.Normalize();
// and rotate it:
var rotatedPlayerDirection = Vector3.Transfom(playerDirection, rotationMatrixForPlayerDirection);
// Then you can simply move forward or backward along this vector:
var movementOnVector = (rotatedPlayerDirection * Time.deltaTime * playerSpeed * inputVectorForMovement.Z);
_position += movementOnVector;
// To move left or right according to the direction vector
// you have to calculate a vector perpendicular
// to both of direction vector and up vector (which is Y)**:
var sideDirectionVector = Vector3.Cross(rotatedPlayerDirection, Vector3.UnitY);
// and just do the movement along that vector:
movementOnVector = (sideDirectionVector * Time.deltaTime * playerSpeed * inputVectorForMovement.X);
_position += movementOnVector;
// Do not forget to update fields:
_playerLooksAt = _position + rotatedPlayerDirection;
_lastMousePosition = currentMousePosition;
}
**交叉产品
推荐阅读
- google-cloud-platform - 将谷歌云存储文件夹挂载到谷歌人工智能平台作业
- apache-zookeeper - 运行 Curator 示例时出现 UnimplementedException
- kubernetes - 错误:pod 具有未绑定的立即 PersistentVolumeClaims
- powershell - 删除所有文件和文件夹工作很慢
- swift - 当allowCameraControl = true时如何禁用场景视图中的一些默认功能?
- csv - 在 Flutter 中读取 CSV 文件时没有这样的文件
- powershell - 在一个文件夹中单独使用多个 CSV 并保存它们的名称
- r - 如何省略具有包含在单独向量中的值的行
- java - Spring Boot & Elastic 客户端 - NoSuchMethodError: org.elasticsearch.action.support.IndicesOptions.ignoreThrottled()Z
- javascript - 如何更新或操作从父级加载到 iframe 中的内容?