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 关于#.net#的问题:End Function
  • ¥15 无法import pycausal
  • ¥15 VS2022创建MVC framework提示:预安装的程序包具有对缺少的注册表值的引用
  • ¥15 weditor无法连接模拟器Local server not started, start with?
  • ¥20 6-3 String类定义
  • ¥15 嵌入式--定时器使用
  • ¥20 51单片机学习中的问题
  • ¥30 Windows Server 2016利用兩張網卡處理兩個不同網絡
  • ¥15 Python中knn问题
  • ¥15 使用C#,asp.net读取Excel文件并保存到Oracle数据库