You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中实现随移动角色平滑发射并归位的拳头机制

解决方案:拳头发射后归位到移动玩家的实现

核心思路

  • 给拳头设置三种状态:待机(跟随玩家保持固定偏移)、发射中(沿朝向移动指定时长)、归位中(追踪玩家位置返回)
  • 发射逻辑可参考玩家dash的速度参数,但单独控制拳头移动,不干扰玩家自身动作
  • 归位逻辑实时计算玩家当前位置,用平滑移动实现追踪,适配玩家持续移动的场景

修改后的拳头脚本(FakeLeft)

using UnityEngine;

public class FakeLeft : MonoBehaviour
{
    // 关联玩家对象(Inspector面板拖入)
    public ManScript player;
    // 待机时拳头相对玩家的偏移距离
    public Vector3 offset;
    // 发射速度(可复用玩家dashSpeed)
    public float launchSpeed = 15f;
    // 发射持续时长
    public float launchDuration = 0.3f;
    // 归位移动速度
    public float returnSpeed = 10f;

    private enum FistState { Idle, Launching, Returning }
    private FistState currentState;
    private float launchTimer;
    private Vector3 launchDirection;

    void Start()
    {
        currentState = FistState.Idle;
        // 初始化偏移(场景中已摆好位置时自动获取相对坐标)
        if (player != null)
        {
            offset = transform.position - player.transform.position;
            // 可选:直接复用玩家的dash速度
            launchSpeed = player.dashSpeed;
        }
    }

    void Update()
    {
        if (player == null) return;

        // 按下F键触发发射(仅待机状态可触发)
        if (Input.GetKeyDown(KeyCode.F) && currentState == FistState.Idle)
        {
            StartLaunch();
        }

        switch (currentState)
        {
            case FistState.Idle:
                // 待机时跟随玩家,保持偏移位置
                transform.position = player.transform.position + offset;
                // 同步玩家方向旋转
                UpdateRotation();
                break;
            case FistState.Launching:
                LaunchMovement();
                break;
            case FistState.Returning:
                ReturnToPlayer();
                break;
        }
    }

    // 启动发射流程
    void StartLaunch()
    {
        currentState = FistState.Launching;
        launchTimer = launchDuration;
        // 根据当前朝向确定发射方向
        launchDirection = transform.right;
    }

    // 发射阶段移动逻辑
    void LaunchMovement()
    {
        transform.Translate(launchDirection * launchSpeed * Time.deltaTime, Space.World);
        launchTimer -= Time.deltaTime;

        // 发射时长结束,切换到归位状态
        if (launchTimer <= 0)
        {
            currentState = FistState.Returning;
        }
    }

    // 归位到玩家逻辑
    void ReturnToPlayer()
    {
        // 实时更新目标位置(玩家当前位置+偏移)
        Vector3 targetPos = player.transform.position + offset;
        // 平滑移动到目标点
        transform.position = Vector3.MoveTowards(transform.position, targetPos, returnSpeed * Time.deltaTime);

        // 接近目标后切换回待机状态
        if (Vector3.Distance(transform.position, targetPos) < 0.1f)
        {
            transform.position = targetPos;
            currentState = FistState.Idle;
        }
    }

    // 保留原旋转逻辑,同步方向时更新偏移
    void UpdateRotation()
    {
        if (Input.GetKeyDown(KeyCode.A))
        {
            transform.eulerAngles = Vector3.forward * 180;
            offset = Quaternion.Euler(0,0,180) * Vector3.right * offset.magnitude;
        }
        if (Input.GetKeyDown(KeyCode.D))
        {
            transform.eulerAngles = Vector3.forward * 0;
            offset = Quaternion.Euler(0,0,0) * Vector3.right * offset.magnitude;
        }
        if (Input.GetKeyDown(KeyCode.W))
        {
            transform.eulerAngles = Vector3.forward * 90;
            offset = Quaternion.Euler(0,0,90) * Vector3.right * offset.magnitude;
        }
        if (Input.GetKeyDown(KeyCode.S))
        {
            transform.eulerAngles = Vector3.forward * 270;
            offset = Quaternion.Euler(0,0,270) * Vector3.right * offset.magnitude;
        }
    }
}

玩家脚本(ManScript)的补充说明

无需修改核心移动逻辑,仅需在Unity编辑器中,将玩家对象拖入拳头脚本的player字段即可。如果需要严格复用dash参数,可在拳头脚本的Start方法中直接读取玩家的dashSpeed(已在脚本中注释示例)。

关键细节

  • 状态枚举清晰区分不同阶段,避免逻辑冲突
  • 归位时实时更新玩家位置,确保拳头能追踪移动中的玩家
  • 切换方向时同步更新偏移向量,保证待机状态下拳头位置始终正确

内容的提问来源于stack exchange,提问作者Kr00mmi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 13:18:15