按住AS,SD,DW或WA的组合键移动我的物体后,它会成功对角移动并旋转到正确位置,但释放按键后,它会旋转回0,90,180或者360取决于释放我的键后最近的旋转,我想这是因为我离开了键的那一帧,所以它运行该代码并将其移动到0,90,180,360。但我不知道如何解决它。
释放按键后,它不会保持这种状态,而是向左或向上移动
PlayerMovement.cs
using UnityEngine;
using System.Collections;
public class playerMovement : MonoBehaviour {
private float speedWalk = 7.5f;
private float speedRotate = 7.5f;
private GameObject raycastObject;
// Update is called once per frame
void FixedUpdate ()
{
//Non-Diagonal Movements
if (Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.S) && !Input.GetKey(KeyCode.D)) //player movement up
{
transform.localPosition += new Vector3(0.0f, 0.0f, speedWalk * Time.deltaTime);
}
if (Input.GetKey(KeyCode.S) && !Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.D)) //player movement down
{
transform.localPosition -= new Vector3(0.0f, 0.0f, speedWalk * Time.deltaTime);
}
if (Input.GetKey(KeyCode.D) && !Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.S)) //player movement right
{
transform.localPosition += new Vector3(speedWalk * Time.deltaTime, 0.0f, 0.0f);
}
if (Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.D) && !Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.S)) //player movement left
{
transform.localPosition -= new Vector3(speedWalk * Time.deltaTime, 0.0f, 0.0f);
}
//Diagonal Movements **@@@@@@@@** I think this is the problem.
if (Input.GetKey(KeyCode.A) && Input.GetKey(KeyCode.W)) //player movement Top Left
{
transform.localPosition -= new Vector3(speedWalk * Time.deltaTime, 0.0f, 0.0f);
transform.localPosition += new Vector3(0.0f, 0.0f, speedWalk * Time.deltaTime);
}
if (Input.GetKey(KeyCode.W) && Input.GetKey(KeyCode.D)) //player movement Top Right
{
transform.localPosition += new Vector3(0.0f, 0.0f, speedWalk * Time.deltaTime);
transform.localPosition += new Vector3(speedWalk * Time.deltaTime, 0.0f, 0.0f);
}
if (Input.GetKey(KeyCode.D) && Input.GetKey(KeyCode.S)) //player movement Bottom Right
{
transform.localPosition += new Vector3(speedWalk * Time.deltaTime, 0.0f, 0.0f);
transform.localPosition -= new Vector3(0.0f, 0.0f, speedWalk * Time.deltaTime);
}
if (Input.GetKey(KeyCode.S) && Input.GetKey(KeyCode.A)) //player movement Bottom Left
{
transform.localPosition -= new Vector3(0.0f, 0.0f, speedWalk * Time.deltaTime);
transform.localPosition -= new Vector3(speedWalk * Time.deltaTime, 0.0f, 0.0f);
}
}
}
playerRotateMouse.cs
using UnityEngine;
using System.Collections;
public class playerRotateMouse : MonoBehaviour
{
public Transform Player;
private float speed = 7.5f;
Quaternion targetRotation;
void FixedUpdate()
{
Plane playerPlane = new Plane(Vector3.up, transform.position);
// Generates a ray from cursor
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
float hitdist = 0.0f;
if (Input.GetButtonDown("Fire1") || Input.GetButtonDown("Fire2"))
{
if (playerPlane.Raycast(ray, out hitdist))
{
Vector3 targetPoint = ray.GetPoint(hitdist);
Debug.DrawRay(transform.position, targetPoint, Color.green);
targetRotation = Quaternion.LookRotation(targetPoint - transform.position);
}
}
// Smooth rotation towards point.
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
//Rotate base on key pressed
if (Input.GetKey(KeyCode.W) && !(Input.GetButton("Fire1") || Input.GetButton("Fire2"))) //player rotate up
{
targetRotation = Quaternion.LookRotation(Vector3.forward);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.S) && !(Input.GetButton("Fire1") || Input.GetButton("Fire2"))) //player rotate down
{
targetRotation = Quaternion.LookRotation(Vector3.forward * -1);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.D) && !(Input.GetButton("Fire1") || Input.GetButton("Fire2"))) //player rotate right
{
targetRotation = Quaternion.LookRotation(Vector3.right);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.A) && !(Input.GetButton("Fire1") || Input.GetButton("Fire2"))) //player rotate left
{
targetRotation = Quaternion.LookRotation(Vector3.left);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
}
}
}
答案 0 :(得分:0)
我会保存最后一个时间戳,并检查第二个密钥释放是否在特定时间范围内。如果它在(例如)20ms内释放,请不要重置它。
例如:(伪)
private bool[] _directionKeysPressed = new bool[4];
private DateTime _previousKeyRelease;
private void KeyDown(object sender, EventArgs e)
{
_keyPressedCount++;
switch(keys)
{
case(W): _directionKeysPressed[0] = true;
case(D): _directionKeysPressed[1] = true;
// .................
}
}
private void KeyUp(object sender, EventArgs e)
{
_keyPressedCount--;
if(_keyPressedCount == 0)
{
// all keys released
_directionKeysPressed[] <--- last direction...
// reset all bools
return;
}
// ONLY if the key is released outside the 20 ms, reset the key.
if(_previousKeyRelease.AddMilliseconds(20) < DateTime.UTCNow)
{ // RESET KEY
switch(keys)
{
case(W): _directionKeysPressed[0] = false;
case(D): _directionKeysPressed[1] = false;
// .................
}
}
_previousKeyRelease = DateTime.UTCNow;
}
我个人会用Int32中的一个位域来做这个,但是对于一个bool数组来说更清楚。