首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >我想用鼠标在联合中输入,将比萨片从2D圆圈中切割出来。什么样的数据结构和几何公式最适合这一点?

我想用鼠标在联合中输入,将比萨片从2D圆圈中切割出来。什么样的数据结构和几何公式最适合这一点?
EN

Game Development用户
提问于 2021-10-29 20:13:36
回答 1查看 261关注 0票数 5

我知道这可能不是一件容易的事情,因为我还没有在网上找到这样的代码示例,但是如果我想在拖动过程中输入鼠标,在用户一放开鼠标,计算成某种网格的切片时,我们就可以使用鼠标输入,那么我需要注意的是什么,以及对此最好的算法和数据结构是什么?

EN

回答 1

Game Development用户

发布于 2021-11-01 15:31:27

从理论上讲,这并不是那么复杂--给定一个点a在圆表面的某个地方,从圆心射出一条射线穿过这个长度点r。这条线的端点是你切圆的外部边缘。重复饼片的另一个边缘。

代码语言:javascript
复制
Vector2 calcEdgePoint(Vector2 mouseDownPosition,Vector2 circleCenter, float circleRadius)
   {
    Ray2D ray = new Ray2D(circleCenter, mouseDownPosition - circleCenter);

    return ray.GetPoint(circleRadius);
   }

如何在您的统一游戏中实践这一点取决于您需要多准确,以及您希望如何处理用户输入。

Mesh MouseOver

一种简单的方法--我可能会首先尝试--是“预切片”披萨(圆圈)网格,并简单地跟踪用户拖过的部分来确定要减去的部分。

下面是一个快速而肮脏的例子。

  1. 网格--我用3D来确保凸对撞机的工作,但是你可能会让它与简单的三角形一起工作。我的披萨有32片。尽可能多地使用以获得所需的分辨率。
  1. 场景设置--“饼”父母带着孩子的网格和一个控制器。摄像机直指馅饼上。
  1. 每个切片都有一个凸对撞机和一个PieSlice脚本:
  1. 饼片脚本“电话回家”与PizzaPieSlicer控制器的鼠标进入,退出和(可选)停留信息:
代码语言:javascript
复制
using UnityEngine;

public class PieSlice : MonoBehaviour
{
    MeshRenderer mr;

    void Start()
    {
        mr = GetComponent<MeshRenderer>();
    }

    private void OnMouseEnter()
    {
        Debug.Log("entered");
        PizzaPieSlicer.instance.SliceEnter(mr);
    }

    private void OnMouseExit()
    {
        PizzaPieSlicer.instance.SliceExit(mr);
    }
}

控制器脚本跟踪批萨是否使用状态机“活动”。当没有片处于活动状态时,它会继续并分割饼。

代码语言:javascript
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PizzaPieSlicer : MonoBehaviour
{

    [SerializeField] Transform pieParent;
    [SerializeField] Material[] materials;
    public static PizzaPieSlicer instance;
   

    public enum State
    {
        slicing,
        idle,
        sliced
    }

    public List<Transform> slices = new List<Transform>(); // public for debugging
    public State state; // public for debugging;
    public int hit = 0; // maybe useful to count? public for debugging " "

    void Start()
    {
        instance = this;
        state = State.idle;

    }

    public void SliceEnter(MeshRenderer mr)
    {
        mr.sharedMaterial = materials[1];
        state = State.slicing;
        if (!slices.Contains(mr.transform))
        {
            slices.Add(mr.transform);
        }
        hit++;
    }

    public void SliceExit(MeshRenderer mr)
    {
        mr.sharedMaterial = materials[2];
        state = State.idle;
    }

    public void SliceStay()
    {
        state = State.slicing;
    }

    void SliceIt()
    {
        var sliceParent = new GameObject().GetComponent<Transform>();

        foreach(Transform t in slices)
        {
            t.SetParent(sliceParent);
        }

        sliceParent.position = new Vector3(1, 1, 1); //Do something more intelligent here
    }

    void Update()
    {
        switch (state)
        {
            case State.idle:
                if(hit > 0)
                {
                    Debug.Log("Slice it!");
                    SliceIt();
                    state = State.sliced;
                }
                break;

            case State.slicing:
                // do something 
                break;

            case State.sliced:
                // reset maybe?
                break;

            default:
                break;
        }
    }
}

演示:

注意:我本打算让PieSlice脚本在OnMouseOver事件期间通知PizzaPieSlicer,但事实证明这可能是不必要的;不过,我认为我的脚本的状态机可能依赖一种可能不可靠的竞争条件(退出事件总是在输入事件之前触发) --更好的方法可能是保持一个堆栈按下enter并在退出时拉动;如果一个帧经过,而堆栈为空,则触发这个片段。

图像径向填充

团结中的另一种方法(如果这是UI元素)是使用Image.FillMethod.Radial360并根据用户的鼠标输入指定一个fillAmount。这种方法的一个可能的缺点是图像填充起源被限制在四个基本点上;在其他地方开始填充需要首先旋转图像,如果sprite不是普通填充的话,这可能是不可取的。

票数 4
EN
页面原文内容由Game Development提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://gamedev.stackexchange.com/questions/197632

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档