Unity玩家对象手动旋转问题:实现移动朝向匹配及按键释放后旋转重置
Got it, let's break down how to solve your problem step by step. Your current code has two main issues: it keeps rotating the player every frame while the key is held (instead of stopping at a target angle), and it doesn't handle resetting the rotation when you let go of the key. Let's fix that.
First, Clarify the Core Behavior
From your description, I assume you want one of two common scenarios—pick whichever fits your game:
- Hold a key to snap/smooth to a fixed direction (e.g., hold D to face right (Y=90°), hold A to face left (Y=-90°), release to face forward (Y=0°))
- Hold a key to continuously rotate, then snap back to forward when released
Scenario 1: Fixed Direction Rotation (Snap/Smooth)
This is likely what you're aiming for—pressing a key turns the player to a specific direction, and letting go resets them to their original forward facing. Here's the adjusted code:
public class PlayerAction : MonoBehaviour { // Adjust this to control how smooth the rotation is (higher = faster transition) public float rotationSmoothSpeed = 5f; void Update() { // Check if we're holding right (D or Right Arrow) or left (A or Left Arrow) bool isRightHeld = Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow); bool isLeftHeld = Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow); Quaternion targetRotation; if (isRightHeld) { // Target rotation: face right (Y-axis 90°) targetRotation = Quaternion.Euler(0, 90, 0); } else if (isLeftHeld) { // Target rotation: face left (Y-axis -90°) targetRotation = Quaternion.Euler(0, -90, 0); } else { // No keys held: reset to forward (Y-axis 0°) targetRotation = Quaternion.Euler(0, 0, 0); } // Smoothly rotate toward the target angle // Replace this line with transform.rotation = targetRotation; if you want instant snaps transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, rotationSmoothSpeed * Time.deltaTime); } }
Key Details:
- We use
Input.GetKeyinstead ofGetAxishere because we want reliable detection of continuous key holds (no smoothing delays that might leave input values lingering after release). Quaternion.Euler(0, y, 0)lets you create rotations using the Euler angles you're familiar with—you don't need to deep-dive into raw Quaternion math for basic rotation like this!- The
Lerpfunction makes transitions feel natural, but you can swap it for a direct assignment if you want instant, snappy turns.
Scenario 2: Continuous Rotation + Reset
If you want the player to spin continuously while holding a key, then snap back to forward when released, use this version:
public class PlayerAction : MonoBehaviour { // How fast the player rotates (degrees per second) public float rotationSpeed = 180f; void Update() { float horizontalInput = Input.GetAxis("Horizontal"); if (horizontalInput != 0) { // Rotate continuously based on input (left = negative, right = positive) transform.Rotate(0, horizontalInput * rotationSpeed * Time.deltaTime, 0); } else { // No input: reset rotation to forward (0,0,0) transform.rotation = Quaternion.Euler(0, 0, 0); } } }
Key Details:
Input.GetAxis("Horizontal")gives a value between -1 (left) and 1 (right), which we multiply by rotation speed to control direction and speed.Time.deltaTimeensures rotation speed stays consistent across different frame rates.
Quick Tips for Quaternion Confusion
You mentioned struggling with Quaternions—don't overcomplicate it! For most basic rotation needs in Unity, you only need three things:
Quaternion.Euler(x, y, z): Creates a rotation from the Euler angles you already understand (x=pitch, y=yaw, z=roll).transform.rotation: Assign a Quaternion here to set the object's rotation directly.Quaternion.Lerp(a, b, t): Smoothly interpolates between two rotations for natural-looking transitions.
内容的提问来源于stack exchange,提问作者fireslide

