RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1296461
Accepted
Максим Фисман
Максим Фисман
Asked:2022-06-18 03:45:40 +0000 UTC2022-06-18 03:45:40 +0000 UTC 2022-06-18 03:45:40 +0000 UTC

为 Sea Battle 等游戏正确渲染 10x10 场

  • 772

我要创建的游戏是迷宫。简而言之,10x10海战中的2个场地,玩家轮流进行:他们可以从场地的一个单元格移动到任何相邻的单元格,构建所有访问单元格的“路线”。

问题是这样的:如何正确实现字段本身?我看到的额头上的想法:Field 字段精灵,它有 100 个带有碰撞器的子 FieldCell 对象和相应的脚本。但是,玩家仍然需要能够通过点击墙壁来布置迷宫的墙壁。10x10 的场地只有 81 面墙(不包括外面的墙)。结果总共有:2*(1+100+81)=364 个对象,在我看来,这是很多 => 方法是错误的。

那么如何实现这样的事情呢?也许您可以以某种方式获得相对于图像本身而不是屏幕/世界的单击图像的确切位置...

unity3d
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Yaroslav
    2022-06-18T05:41:17Z2022-06-18T05:41:17Z

    如果该领域的瓦片的所有图片都在一个图集中,那么它们在1个drawcall中渲染,理论上一百个都不是问题。我不明白为什么瓷砖需要脚本,数百个碰撞器(我不明白为什么),可能还有数百个更新,这真的很重。

    获取点击坐标:

    private Plane _planeXY = new Plane(Vector3.back, 0);
    
    private Vector3 GetPlanePosition (Vector3 mousePosition)
    {
        Ray Ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        float enter = 0.0f;
        if (_planeXY.Raycast(Ray, out enter))
            return Ray.GetPoint(enter);
        return Vector3.zero;
    }
    

    字段可以很容易地确定它是否被单击以及在哪个图块上:

    [DisallowMultipleComponent]
    
    public class FieldLogic : MonoBehaviour
    {
        public event Action<Vector2Int> TileChanged;
        [SerializeField] private Vector2Int _size = new Vector2Int(10, 10);
    
        public Vector2Int Size => _size;
    
        public void OnTileClick (Vector2Int index)
        {
            TileChanged?.Invoke(index);
        }
    
    }
    

    [DisallowMultipleComponent]
    [RequireComponent(typeof(FieldLogic))]
    
    public class FieldView : MonoBehaviour
    {
        [SerializeField] private int _tileSize = 32;
        private SpriteRenderer[,] _tileSprites;
    
        public int TileSize => _tileSize;
    
        private void Start ()
        {
            FieldLogic Logic = GetComponent<FieldLogic>();
            Logic.TileChanged += OnTileChange;
            SpawnSprites(Logic.Size);
        }
    
        private void SpawnSprites (Vector2Int size)
        {
            Transform Parent = transform;
            _tileSprites = new SpriteRenderer[size.x, size.y];
            Vector3 Ancore = size*0.5f;
            for (int x = 0; x < size.x; x++)
                for (int y = 0; y < size.y; y++)
                {
                    GameObject NewTile = new GameObject();
                    Transform TileTransform = NewTile.transform;
                    TileTransform.parent = Parent;
                    TileTransform.localPosition = Ancore+new Vector3(_tileSize*x, _tileSize*y);
                    _tileSprites[x, y] = NewTile.AddComponent<SpriteRenderer>();
                }
        }
    
        private void OnTileChange (Vector2Int index)
        {
    
        }
    }
    

    [DisallowMultipleComponent]
    [RequireComponent(typeof(FieldView))]
    [RequireComponent(typeof(FieldLogic))]
    
    public class FieldInteractive : MonoBehaviour
    {
        private Transform _transform;
        private FieldView _view;
        private FieldLogic _logic;
    
        private void Start ()
        {
            _transform = transform;
            _view = GetComponent<FieldView>();
            _logic = GetComponent<FieldLogic>();
        }
    
        public void OnClick (Vector2 position)
        {
            if (HitField(position))
            {
                Vector2Int TileIndex = GetHitTileIndex(position);
                _logic.OnTileClick(TileIndex);
            }
        }
    
        private Vector2Int GetHitTileIndex (Vector2 position)
        {
            float TileSize = _view.TileSize;
            position -= (Vector2)_transform.position;
            return new Vector2(Mathf.FloorToInt(position.x/TileSize), Mathf.FloorToInt(position.y/TileSize));
        }
    
        private bool HitField (Vector2 position)
        {
            Vector2Int FieldSize = _logic.Size;
            float TileSize = _view.TileSize;
            Rect FieldRect = new Rect(_transform.position, FieldSize*TileSize);
            return FieldRect.Contains(position);
        }
    }
    

    FieldView 只负责视觉,FieldInteractive 负责触摸。业务逻辑由 FieldLogic 处理。交互式在单元格上发送点击事件,并且视图愚蠢地对逻辑脚本事件做出反应并自行更新。

    • 3

相关问题

  • 使物体通过 2D 对撞机而不停止

  • 如何将组件与 Unity 变量等同起来

  • 需要制作一个场景来统一加载场景

  • unity 奇怪的相机分辨率

  • Unity 2020 中的长时间加载

  • 改进游戏。如何平衡?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5