You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

游戏角色屏幕间平滑移动实现方法咨询(含代码示例需求)

Smooth Character Movement from Left to Right on Screen Click: 3 Implementation Methods

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

  1. Select your character GameObject.
  2. Open the Animation window (Window > Animation > Animation).
  3. Create a new clip (name it MoveRight).
  4. Set a keyframe at 0 seconds with the character on the left side of the screen.
  5. Set a keyframe at your desired duration (e.g., 2 seconds) with the character on the right side.
  6. 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

火山引擎 最新活动