gpt4 book ai didi

c# - Unity - 使用新输入系统/角色 Controller 让角色看着鼠标

转载 作者:行者123 更新时间:2023-12-04 07:20:32 25 4
gpt4 key购买 nike

一直遵循本指南 https://youtu.be/bXNFxQpp2qk?t=1280对于角色 Controller 。这让我开始进行基本的运动,在 21:20 的时候,他创造了一种让球员轮换的方法。

https://youtu.be/b0AQg5ZTpac以及面向鼠标位置的播放器的此视频。在 7:15 处,她解释了如何获取我将其存储在 positionToLookAt

中的 mousePosition

我希望我的角色的旋转用鼠标来完成,并且有一个像这里这样的视野:https://youtu.be/rQG9aUWarwE

一直试图让玩家面向鼠标位置的方向,但一直没有得到结果。这里显示https://imgur.com/gallery/mPPWogi视频结果和我的 PlayerInputs。

有同行提到更换四元数 targetRotation = Quaternion.LookRotation(positionToLookAt);经过四元数 targetRotation = Quaternion.LookRotation(positionToLookAt - transform.position);

但它不起作用并在 imgur 中产生了相同的结果。

有人可以帮我吗?我被卡住了,我不知道如何让这个角色看着鼠标。

这是方法的片段

   void handleRotation()
{
Vector3 positionToLookAt;

// get mouse position
Vector2 mousePosition = playerInput.CharacterControls.MousePosition.ReadValue<Vector2>();
mousePosition = Camera.main.ScreenToWorldPoint(mousePosition);

// insert mouse position to looking position
positionToLookAt.x = currentMovement.x;
//positionToLookAt.x = mousePosition.x;
positionToLookAt.y = 0.0f;
positionToLookAt.z = currentMovement.z;
//positionToLookAt.z = mousePosition.y;

Quaternion currentRotation = transform.rotation;

if (isMovementPressed)
{
Quaternion targetRotation = Quaternion.LookRotation(positionToLookAt);
transform.rotation = Quaternion.Slerp(currentRotation, targetRotation, rotationFactorPerFrame * Time.deltaTime);
}

}

如果有人想要我的完整代码,请看这里。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;


public class AnimationAndMovementController : MonoBehaviour
{

PlayerInput playerInput;
UnityEngine.CharacterController characterController;

Animator animator;

int isWalkingHash;
int isRunningHash;


Vector2 currentMovementInput;
Vector3 currentMovement;
Vector3 currentRunMovement;
bool isMovementPressed;
bool isRunPressed;
float rotationFactorPerFrame = 15.0f;
float runMultiplier = 3.0f;

//Debug.Log(context.ReadValue<Vector2>());



void Start()
{

}

void Awake()
{
playerInput = new PlayerInput();
characterController = GetComponent<UnityEngine.CharacterController>();
animator = GetComponent<Animator>();

isWalkingHash = Animator.StringToHash("isWalking");
isRunningHash = Animator.StringToHash("isRunning");


playerInput.CharacterControls.Move.started += onMovementInput;
playerInput.CharacterControls.Move.canceled += onMovementInput;
playerInput.CharacterControls.Move.performed += onMovementInput;

playerInput.CharacterControls.Run.started += onRun;
playerInput.CharacterControls.Run.canceled += onRun;

}

void onRun(InputAction.CallbackContext context)
{
isRunPressed = context.ReadValueAsButton();
}


void onMovementInput (InputAction.CallbackContext context)
{

currentMovementInput = context.ReadValue<Vector2>();
currentMovement.x = currentMovementInput.x;
currentMovement.z = currentMovementInput.y;

currentRunMovement.x = currentMovementInput.x * runMultiplier;
currentRunMovement.z = currentMovementInput.y * runMultiplier;

isMovementPressed = currentMovementInput.x != 0 || currentMovementInput.y != 0;

}




void handleRotation()
{
Vector3 positionToLookAt;

Vector2 mousePosition = playerInput.CharacterControls.MousePosition.ReadValue<Vector2>();
mousePosition = Camera.main.ScreenToWorldPoint(mousePosition);

positionToLookAt.x = currentMovement.x;
//positionToLookAt.x = mousePosition.x;
positionToLookAt.y = 0.0f;
positionToLookAt.z = currentMovement.z;
//positionToLookAt.z = mousePosition.y;

Quaternion currentRotation = transform.rotation;

if (isMovementPressed)
{
Quaternion targetRotation = Quaternion.LookRotation(positionToLookAt);
transform.rotation = Quaternion.Slerp(currentRotation, targetRotation, rotationFactorPerFrame * Time.deltaTime);
}

}

void handleAnimation()
{
bool isWalking = animator.GetBool(isWalkingHash);
bool isRunning = animator.GetBool(isRunningHash);

if (isMovementPressed && !isWalking) {
animator.SetBool(isWalkingHash, true);
}
else if (!isMovementPressed && isWalking){
animator.SetBool(isWalkingHash, false);
}

if ((isMovementPressed && isRunPressed) && !isRunning)
{
animator.SetBool(isRunningHash, true);
}
else if ((!isMovementPressed && !isRunPressed) && isRunning)
{
animator.SetBool(isRunningHash, false);
}
else if ((isMovementPressed && !isRunPressed) && isRunning)
{
animator.SetBool(isRunningHash, false);
}

}


void handleGravity()
{



if (characterController.isGrounded) {
float groundedGravity = -0.05f;
currentMovement.y = groundedGravity;
currentRunMovement.y = groundedGravity;
} else {
float gravity = -9.8f;
currentMovement.y = gravity;
currentRunMovement.y = gravity;
}
}




// Update is called once per frame
void Update()
{
handleRotation();
handleAnimation();
handleGravity();

if (isRunPressed) {
characterController.Move(currentRunMovement * Time.deltaTime);
}
else {
characterController.Move(currentMovement * Time.deltaTime);
}


}


void OnEnable()
{
playerInput.CharacterControls.Enable();
}

void OnDisable()
{
playerInput.CharacterControls.Disable();
}
}

编辑

更新了完整代码,handleRotation() 是处理旋转的地方:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class AnimationAndMovementController : MonoBehaviour
{

PlayerInput playerInput;
CharacterController characterController;


Animator animator;

int isWalkingHash;
int isRunningHash;

Camera _camera;

Vector2 currentMovementInput;
Vector3 currentMovement;
Vector3 currentRunMovement;

bool isMovementPressed;
bool isRunPressed;

//float rotationFactorPerFrame = 15.0f;
float runMultiplier = 3.0f;



// Start is called before the first frame update
void Start()
{
_camera = Camera.main;
}

void Awake()
{
playerInput = new PlayerInput();
characterController = GetComponent<CharacterController>();
animator = GetComponent<Animator>();

isWalkingHash = Animator.StringToHash("isWalking");
isRunningHash = Animator.StringToHash("isRunning");


playerInput.CharacterControls.Move.started += onMovementInput;
playerInput.CharacterControls.Move.canceled += onMovementInput;
playerInput.CharacterControls.Move.performed += onMovementInput;

playerInput.CharacterControls.Run.started += onRun;
playerInput.CharacterControls.Run.canceled += onRun;

}


void onRun(InputAction.CallbackContext context)
{
isRunPressed = context.ReadValueAsButton();
}


void onMovementInput(InputAction.CallbackContext context)
{

currentMovementInput = context.ReadValue<Vector2>();
currentMovement.x = currentMovementInput.x;
currentMovement.z = currentMovementInput.y;

currentRunMovement.x = currentMovementInput.x * runMultiplier;
currentRunMovement.z = currentMovementInput.y * runMultiplier;

isMovementPressed = currentMovementInput.x != 0 || currentMovementInput.y != 0;

}



void handleAnimation()
{
bool isWalking = animator.GetBool(isWalkingHash);
bool isRunning = animator.GetBool(isRunningHash);

if (isMovementPressed && !isWalking)
{
animator.SetBool(isWalkingHash, true);
}
else if (!isMovementPressed && isWalking)
{
animator.SetBool(isWalkingHash, false);
}

if ((isMovementPressed && isRunPressed) && !isRunning)
{
animator.SetBool(isRunningHash, true);
}
else if ((!isMovementPressed && !isRunPressed) && isRunning)
{
animator.SetBool(isRunningHash, false);
}
else if ((isMovementPressed && !isRunPressed) && isRunning)
{
animator.SetBool(isRunningHash, false);
}

}


void handleGravity()
{
if (characterController.isGrounded)
{
float groundedGravity = -0.05f;
currentMovement.y = groundedGravity;
currentRunMovement.y = groundedGravity;
}
else
{
float gravity = -9.8f;
currentMovement.y = gravity;
currentRunMovement.y = gravity;
}
}



void handleRotation()
{

// We're getting a Vector2, whereas we will need a Vector3
// Get a z value based on camera, and include it in a Vector3
var mousePosition = playerInput.CharacterControls.MousePosition.ReadValue<Vector2>();
var mousePositionZ = _camera.farClipPlane * .5f;
var mouseViewportPosition = _camera.ScreenToWorldPoint(new Vector3(mousePosition.x, mousePosition.y, mousePositionZ));


// Do the same with the object's position
var positionOnViewport = Camera.main.WorldToViewportPoint(transform.position);

// Get the angle between the points
var angle = AngleBetweenTwoPoints(positionOnViewport, mouseViewportPosition);

// Apply the angle as the rotation of the object
transform.rotation = Quaternion.Euler(new Vector3(0f, -angle, 0f));

}


float AngleBetweenTwoPoints(Vector3 a, Vector3 b)
{
return Mathf.Atan2(b.y - a.y, b.x - a.x) * Mathf.Rad2Deg;
}



// Update is called once per frame
void Update()
{

handleRotation();
handleAnimation();
handleGravity();


if (isRunPressed)
{
characterController.Move(currentRunMovement * Time.deltaTime);
}
else
{
characterController.Move(currentMovement * Time.deltaTime);
}

}


void OnEnable()
{
playerInput.CharacterControls.Enable();
}

void OnDisable()
{
playerInput.CharacterControls.Disable();
}


}

inputs

编辑 2:当前迭代

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class AnimationAndMovementController : MonoBehaviour
{

PlayerInput playerInput;
CharacterController characterController;


Animator animator;

int isWalkingHash;
int isRunningHash;

Camera _camera;

Vector2 currentMovementInput;
Vector3 currentMovement;
Vector3 currentRunMovement;

bool isMovementPressed;
bool isRunPressed;

float rotationFactorPerFrame = 15.0f;
float runMultiplier = 3.0f;



// Start is called before the first frame update
void Start()
{
_camera = Camera.main;
}

void Awake()
{
playerInput = new PlayerInput();
characterController = GetComponent<CharacterController>();
animator = GetComponent<Animator>();

isWalkingHash = Animator.StringToHash("isWalking");
isRunningHash = Animator.StringToHash("isRunning");


playerInput.CharacterControls.Move.started += onMovementInput;
playerInput.CharacterControls.Move.canceled += onMovementInput;
playerInput.CharacterControls.Move.performed += onMovementInput;

playerInput.CharacterControls.Run.started += onRun;
playerInput.CharacterControls.Run.canceled += onRun;

}


void onRun(InputAction.CallbackContext context)
{
isRunPressed = context.ReadValueAsButton();
}


void onMovementInput(InputAction.CallbackContext context)
{

currentMovementInput = context.ReadValue<Vector2>();
currentMovement.x = currentMovementInput.x;
currentMovement.z = currentMovementInput.y;

currentRunMovement.x = currentMovementInput.x * runMultiplier;
currentRunMovement.z = currentMovementInput.y * runMultiplier;

isMovementPressed = currentMovementInput.x != 0 || currentMovementInput.y != 0;

}



void handleAnimation()
{
bool isWalking = animator.GetBool(isWalkingHash);
bool isRunning = animator.GetBool(isRunningHash);

if (isMovementPressed && !isWalking)
{
animator.SetBool(isWalkingHash, true);
}
else if (!isMovementPressed && isWalking)
{
animator.SetBool(isWalkingHash, false);
}

if ((isMovementPressed && isRunPressed) && !isRunning)
{
animator.SetBool(isRunningHash, true);
}
else if ((!isMovementPressed && !isRunPressed) && isRunning)
{
animator.SetBool(isRunningHash, false);
}
else if ((isMovementPressed && !isRunPressed) && isRunning)
{
animator.SetBool(isRunningHash, false);
}

}


void handleGravity()
{
if (characterController.isGrounded)
{
float groundedGravity = -0.05f;
currentMovement.y = groundedGravity;
currentRunMovement.y = groundedGravity;
}
else
{
float gravity = -9.8f;
currentMovement.y = gravity;
currentRunMovement.y = gravity;
}
}

void handle_isRunPressed()
{
if (isRunPressed)
{
characterController.Move(currentRunMovement * Time.deltaTime);
}
else
{
characterController.Move(currentMovement * Time.deltaTime);
}
}

void handleRotation()
{
var mousePosition = playerInput.CharacterControls.MousePosition.ReadValue<Vector2>();
var mousePositionZ = _camera.farClipPlane * .5f;

var mouseWorldPosition = _camera.ScreenToWorldPoint(new Vector3(mousePosition.x, mousePosition.y, mousePositionZ)); // _camera.ScreenToViewportPoint(mousePosition);

// Get the angle between the points
// Use the x and z from the object/mouse, since we're looking along the y axis
var angle = AngleBetweenTwoPoints(new Vector2(transform.position.x, transform.position.z), new Vector2(mouseWorldPosition.x, mouseWorldPosition.z));

transform.rotation = Quaternion.Euler(new Vector3(0f, -angle, 0f));
}


float AngleBetweenTwoPoints(Vector3 a, Vector3 b)
{
return Mathf.Atan2(b.y - a.y, b.x - a.x) * Mathf.Rad2Deg;
}



// Update is called once per frame
void Update()
{
handleRotation();
handleAnimation();
handleGravity();

handle_isRunPressed();
}


void OnEnable()
{
playerInput.CharacterControls.Enable();
}

void OnDisable()
{
playerInput.CharacterControls.Disable();
}


}

不幸的是,我的代码在 handleRotation() 中旋转仍然无法按预期工作

编辑 3:

void handleRotation()
{
// We're getting a Vector2, whereas we will need a Vector3
// Get a z value based on camera, and include it in a Vector3
Vector2 mousePosition = playerInput.CharacterControls.MousePosition.ReadValue<Vector2>();

var mousePositionZ = _camera.farClipPlane * .5f;

Vector3 mouseViewportPosition = _camera.ViewportToWorldPoint(new Vector3(mousePosition.x, mousePosition.y, _camera.transform.position.y));


Debug.Log("MousePos: " + mouseViewportPosition);

Vector3 positionToLookAt;

positionToLookAt.x = mouseViewportPosition.x;
positionToLookAt.y = 0.0f;
//positionToLookAt.z = currentMovement.z;
positionToLookAt.z = mouseViewportPosition.z;

Quaternion currentRotation = transform.rotation;

Quaternion targetRotation = Quaternion.LookRotation(positionToLookAt - transform.position);
transform.rotation = Quaternion.Slerp(currentRotation, targetRotation, rotationFactorPerFrame * Time.deltaTime);

}

它在旋转。但不正确。

最佳答案

更新拍摄 2

这是我在 Update() 中的完整代码:

var mousePosition = _playerInput.Player.MousePosition.ReadValue<Vector2>();
var mousePositionZ = _camera.farClipPlane * .5f;

var mouseWorldPosition = _camera.ScreenToWorldPoint(new Vector3(mousePosition.x, mousePosition.y, mousePositionZ)); // _camera.ScreenToViewportPoint(mousePosition);

// Get the angle between the points
// Use the x and z from the object/mouse, since we're looking along the y axis
var angle = AngleBetweenTwoPoints(new Vector2(transform.position.x, transform.position.z), new Vector2(mouseWorldPosition.x, mouseWorldPosition.z));

transform.rotation = Quaternion.Euler(new Vector3(0f, -angle, 0f));

辅助函数是一样的:

float AngleBetweenTwoPoints(Vector2 a, Vector2 b)
{
return Mathf.Atan2(b.y - a.y, b.x - a.x) * Mathf.Rad2Deg;
}

更新

我想出了如何按照 Joseph 最初尝试的方式做到这一点。ScreenToWorldPoint 确实可以在新的输入系统中正常工作。问题在于我们尝试使用它的方式。它需要一个 Vector3!

不能这样做:

// Don't do this, it wont work!
var mousePosition = _playerInput.Player.MousePosition.ReadValue<Vector2>();
var mouseViewportPosition = _camera.ScreenToWorldPoint(mousePosition);

你需要这样做:

// We're getting a Vector2, whereas we will need a Vector3
// Get a z value based on camera, and include it in a Vector3
var mousePosition = _playerInput.Player.MousePosition.ReadValue<Vector2>();
var mousePositionZ = _camera.farClipPlane * .5f;
var mouseViewportPosition = _camera.ScreenToWorldPoint(new Vector3(mousePosition.x, mousePosition.y, mousePositionZ));

原答案:

你的例子有一些问题......我想你正在编辑它以根据移动方向进行旋转? 可能现在引擎中的鼠标位置有问题...我注意到其他一些线程提示输入值不一样,但我不确定到什么程度.可能无法转换为世界坐标?

出于某种原因,这对我不起作用,它总是吐出 (0.0, 10.0, 0.0):

var mouseWorldPosition = Camera.main.ScreenToWorldPoint(mousePosition);

这是我能够开始工作的:

// Get the mouse position from the NEW input system
var mousePosition = _playerInput.Player.MousePosition.ReadValue<Vector2>();

// Convert the mousePosition to the VIEWPORT
var mouseViewportPosition = Camera.main.ScreenToViewportPoint(mousePosition);

// Do the same with the object's position
var positionOnViewport = Camera.main.WorldToViewportPoint(transform.position);

// Get the angle between the points
var angle = AngleBetweenTwoPoints(positionOnViewport, mouseViewportPosition);

// Apply the angle as the rotation of the object
transform.rotation = Quaternion.Euler(new Vector3(0f, -angle, 0f));

大意来自这里,包括这个函数(https://answers.unity.com/questions/855976/make-a-player-model-rotate-towards-mouse-location.html):

float AngleBetweenTwoPoints(Vector3 a, Vector3 b)
{
return Mathf.Atan2(b.y - a.y, b.x - a.x) * Mathf.Rad2Deg;
}

请注意,这并不完美……角度稍微偏离了……不确定为什么会这样。你可以在这里看到它有点夸张:

enter image description here

我认为这里故事的寓意是检查每个阶段的输入,看看它是什么样子以及它是如何转换的。现在我们知道一些新的输入值可能会关闭,您可以使用旧系统的鼠标位置,或者将我的示例与您提到的其他一些方法结合起来。

关于c# - Unity - 使用新输入系统/角色 Controller 让角色看着鼠标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68530495/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com