qq_43384650 2021-12-20 17:06 采纳率: 37.5%
浏览 51
已结题

unity脚本逻辑问题

如何在unity中实现,物体在一个长宽都为10米的平面边缘逆时针移动,输入1移动1格子,输入4移动4格子。

  • 写回答

2条回答 默认 最新

  • dark9spring 2021-12-21 19:32
    关注
    
    using System;
    using UnityEngine;
    using UnityEngine.UI;
    
    /// <summary>
    /// 移动方向
    /// </summary>
    public enum MoveDirection
    {
        X,
        OppositeX,
        Z,
        OppositeZ
    }
    
    public sealed class CreateMap : MonoBehaviour
    {
        [SerializeField] private Vector3 startPoint;
        [SerializeField] private Vector3 endPoint;
        [SerializeField] private float length;
        [SerializeField] private float width;
        [SerializeField] private GameObject player;
        [SerializeField] private InputField input;
    
        /// <summary>
        /// 每步的米数
        /// </summary>
        private const sbyte Step = 1;
    
        private void Awake()
        {
            startPoint = player.transform.position;
            length = startPoint.z - endPoint.z;
            width = startPoint.x - endPoint.x;
            input.onEndEdit.AddListener((value) =>
            {
                if (!sbyte.TryParse(value, out var result)) 
                    return;
                switch (result)
                {
                    case 1:
                        Move(result);
                        break;
                    case 4:
                        Move(result);
                        break;
                    default:
                        Debug.LogError("输入错误");
                        break;
                }
            });
        }
    
        private void Move(sbyte step)
        {
            var playerPos = player.transform.position;
            //OppositeZ
            if (Math.Abs(playerPos.x - startPoint.x) < 0.05f)
            {
                if (playerPos.z + endPoint.z - step * Step >= -length)
                {
                    playerPos.z -= step * Step;
                }
                else
                {
                    var (x, z) = CalculateMove(step, MoveDirection.OppositeZ, playerPos);
                    playerPos.x += x * Step;
                    playerPos.z -= z * Step;
                }
            }
            //Z
            else if (Math.Abs(playerPos.x - endPoint.x) < 0.05f)
            {
                if (playerPos.z + startPoint.z + step * Step <= length)
                {
                    playerPos.z += step * Step;
                }
                else
                {
                    var (x, z) = CalculateMove(step, MoveDirection.Z, playerPos);
                    playerPos.x -= x * Step;
                    playerPos.z += z * Step;
                }
            }
            //OppositeX
            else if (Math.Abs(playerPos.z - startPoint.z) < 0.05f)
            {
                if (playerPos.x + startPoint.x - step * Step >= -width)
                {
                    playerPos.x -= step * Step;
                }
                else
                {
                    var (x, z) = CalculateMove(step, MoveDirection.OppositeX, playerPos);
                    playerPos.x -= x * Step;
                    playerPos.z -= z * Step;
                }
            }
            //X
            else if (Math.Abs(playerPos.z - endPoint.z) < 0.05f)
            {
                if (playerPos.x + endPoint.x + step * Step <= width)
                {
                    playerPos.x += step * Step;
                }
                else
                {
                    var (x, z) = CalculateMove(step, MoveDirection.X, playerPos);
                    playerPos.x += x * Step;
                    playerPos.z += z * Step;
                }
            }
    
            player.transform.position = playerPos;
        }
    
        /// <summary>
        /// 移动后超出界限重新计算
        /// </summary>
        /// <param name="step"></param>
        /// <param name="direction">该移动的方向</param>
        /// <param name="playerPos"></param>
        /// <returns>返回x或z该移动的距离</returns>
        private (float x, float z) CalculateMove(sbyte step, MoveDirection direction, Vector3 playerPos)
        {
            var stepToMove = step;
            while (true)
            {
                switch (direction)
                {
                    case MoveDirection.X:
                        if (!(step * Step + playerPos.x > endPoint.x)) return (step, stepToMove - step);
                        step--; //xStep
                        direction = MoveDirection.X;
                        continue;
                    case MoveDirection.OppositeX:
                        if (!(-step * Step + playerPos.x < startPoint.x)) return (step, stepToMove - step);
                        step--; //xStep
                        direction = MoveDirection.OppositeX;
                        continue;
                    case MoveDirection.Z:
                        if (!(step * Step + playerPos.z > startPoint.z)) return (stepToMove - step, step);
                        step--; //zStep
                        direction = MoveDirection.Z;
                        continue;
                    case MoveDirection.OppositeZ:
                        if (!(-step * Step + playerPos.z < endPoint.z)) return (stepToMove - step, step);
                        step--; //zStep
                        direction = MoveDirection.OppositeZ;
                        continue;
                    default:
                        throw new ArgumentOutOfRangeException(nameof(direction), direction, null);
                }
            }
        }
    }
    

    img

    img

    代码有点长且注释不全,隔了一天就忘记自己写了啥,算法这块我不会,就用最简单的数学知识实现了,脚本挂哪个物体都行,参数设置好就行。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 12月31日
  • 已采纳回答 12月23日
  • 创建了问题 12月20日

悬赏问题

  • ¥15 自定义 thinkphp 命令行,一直报错,如何解决?
  • ¥15 爬取1-112页所有帖子的标题但是12页后要登录后才能 我使用selenium模拟登录 账号密码输入后 会报错 不知道怎么弄了
  • ¥30 关于用python写支付宝扫码付异步通知收不到的问题
  • ¥50 vue组件中无法正确接收并处理axios请求
  • ¥15 隐藏系统界面pdf的打印、下载按钮
  • ¥15 MATLAB联合adams仿真卡死如何解决(代码模型无问题)
  • ¥15 基于pso参数优化的LightGBM分类模型
  • ¥15 安装Paddleocr时报错无法解决
  • ¥15 python中transformers可以正常下载,但是没有办法使用pipeline
  • ¥50 分布式追踪trace异常问题