游戏角色屏幕间平滑移动实现方法咨询(含代码示例需求)
Hey there! I’ve got three reliable methods to get your character sliding smoothly across the screen when the user taps/clicks—perfect for your game. All examples are tailored for Unity (the most common engine for this kind of task), but the core ideas apply to other engines too.
1. Using Coroutines
Coroutines are my go-to for time-based movement because they keep your logic clean and easy to follow. They let you run a sequence of code over multiple frames without jamming up your Update() method.
Here’s a full code example:
using UnityEngine; using System.Collections; public class CharacterMovementCoroutine : MonoBehaviour { [SerializeField] private float moveDuration = 2f; // How long the movement takes private Vector3 startPos; private Vector3 targetPos; void Start() { // Set initial position (left side of screen, accounting for camera) startPos = Camera.main.ViewportToWorldPoint(new Vector3(0.1f, 0.5f, Camera.main.nearClipPlane)); // Set target position (right side of screen) targetPos = Camera.main.ViewportToWorldPoint(new Vector3(0.9f, 0.5f, Camera.main.nearClipPlane)); targetPos.z = transform.position.z; // Keep character's original Z position transform.position = startPos; } void Update() { // Detect screen click/tap if (Input.GetMouseButtonDown(0)) { // Start the movement coroutine (only if not already moving) if (!IsInvoking(nameof(MoveCharacterCoroutine))) StartCoroutine(MoveCharacterCoroutine()); } } private IEnumerator MoveCharacterCoroutine() { float elapsedTime = 0f; while (elapsedTime < moveDuration) { // Calculate progress through the movement float t = elapsedTime / moveDuration; // Add smooth ease-in-out for more natural movement t = Mathf.SmoothStep(0f, 1f, t); // Interpolate between start and target position transform.position = Vector3.Lerp(startPos, targetPos, t); elapsedTime += Time.deltaTime; yield return null; // Wait for the next frame } // Ensure we land exactly on the target position transform.position = targetPos; } }
Pro tip: Swap Mathf.SmoothStep() with an AnimationCurve if you want even more control over the movement’s acceleration/deceleration curve.
2. Using Vector3.Lerp/MoveTowards in Update()
If you prefer handling movement directly in Update(), Lerp (linear interpolation) works great—just make sure you control the interpolation correctly (don’t just call Lerp every frame without a timer, or it’ll never reach the target).
Example code using MoveTowards for constant speed:
using UnityEngine; public class CharacterMovementLerp : MonoBehaviour { [SerializeField] private float moveSpeed = 2f; // Units per second private Vector3 targetPos; private bool isMoving = false; void Start() { Vector3 startPos = Camera.main.ViewportToWorldPoint(new Vector3(0.1f, 0.5f, Camera.main.nearClipPlane)); targetPos = Camera.main.ViewportToWorldPoint(new Vector3(0.9f, 0.5f, Camera.main.nearClipPlane)); targetPos.z = transform.position.z; transform.position = startPos; } void Update() { // Trigger movement on click, if not already moving if (Input.GetMouseButtonDown(0) && !isMoving) { isMoving = true; } if (isMoving) { // Move towards target at a constant speed transform.position = Vector3.MoveTowards(transform.position, targetPos, moveSpeed * Time.deltaTime); // Check if we've reached the target (with a small tolerance) if (Vector3.Distance(transform.position, targetPos) < 0.01f) { transform.position = targetPos; isMoving = false; } } } }
Note: Vector3.MoveTowards() is simpler than raw Lerp here—it guarantees constant speed, which is often what you want for this kind of straightforward movement.
3. Using Unity Animator (Animation System)
If you plan to add more complex animations later (like a walk cycle or idle pose), using the Animator system is the way to go. It’s visual, easy to tweak, and integrates seamlessly with other character animations.
Step 1: Create the Movement Animation Clip
- Select your character GameObject.
- Open the Animation window (
Window > Animation > Animation). - Create a new clip (name it
MoveRight). - Set a keyframe at 0 seconds with the character on the left side of the screen.
- Set a keyframe at your desired duration (e.g., 2 seconds) with the character on the right side.
- Adjust the curve in the Animation window to add smooth easing if needed.
Step 2: Code to Trigger the Animation
using UnityEngine; public class CharacterMovementAnimator : MonoBehaviour { [SerializeField] private Animator animator; private bool hasMoved = false; // Optional: Prevent re-triggering movement void Start() { // Reset character to left side on start Vector3 startPos = Camera.main.ViewportToWorldPoint(new Vector3(0.1f, 0.5f, Camera.main.nearClipPlane)); startPos.z = transform.position.z; transform.position = startPos; // Auto-find Animator if not assigned in inspector if (animator == null) animator = GetComponent<Animator>(); } void Update() { if (Input.GetMouseButtonDown(0) && !hasMoved) { // Trigger the movement animation animator.Play("MoveRight"); hasMoved = true; // Remove this line if you want to allow repeated movement } } }
Bonus: Add a boolean parameter to your Animator Controller instead of calling Play() directly—this lets you set up smooth transitions between movement and other states (like idle).
Which Method Should You Choose?
- Coroutines: Best for custom, code-driven movement with easy-to-add logic (like pausing mid-movement or adding movement callbacks).
- Lerp/MoveTowards: Great for simple, constant-speed movement without extra setup.
- Animator: Ideal if you want to combine movement with other animations (walk cycles, facial expressions, etc.).
内容的提问来源于stack exchange,提问作者Wp3Dev




