900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > Unity 一笔画的玩法实现

Unity 一笔画的玩法实现

时间:2020-07-15 22:07:14

相关推荐

Unity 一笔画的玩法实现

文章目录

前言一、分解一笔画玩法二、代码1.“端口”:Port(每两个点相同端口连接起来就是“线”)2.“点”:Point3.OneStrokeDraw(一笔画:点线管理器)总结

前言

策划在游戏里的一个关卡采用一笔画类似的玩法,我在调查发现关于一笔画的玩法在网上很少。

一笔画有很多实现方法,以下这种方法是我自己的一个实现方法。

目前这个交互方式是点击每个点来连线(策划需求),而要想拖动连线的话可以使用IDragHandler的其他接口来实现。

一、分解一笔画玩法

玩法:通过存在的 “线” 通道把所有的 “点” 都连起来

首先,结构是多个点和线相连的几何图;

“线”:只能通过一次的通道。

“点”:是各通道的连接处,也是通关的要素之一。

举例图:

注意点:

1.在连到的最新“点”判断是否存在没连过的 “线”;

2.连过的“点”虽然可以连,但是是只会经过 “线”通道;

3.每次连一个“点”要判断是否所有的“点”和 “线”都被连接;

4.会使用到 LineRenderer 组件。

二、代码

1.“端口”:Port(每两个点相同端口连接起来就是“线”)

每个点都有一或多个端口,这个端口只能跟别的有相同端口号的相连

/// <summary>/// 端口属性/// </summary>[Serializable]public class Port{public int portNum; //端口号public bool isConnected; //是否被连接}

2.“点”:Point

含有端口类

变量:

1.暗亮点素材是Ui层为了标明显示出点是否被连接过

2.ports管理该点的所有端口

3.samePort 存储两点间的相同端口号

using System;using System.Collections.Generic;using System.Reflection;using UnityEngine;using UnityEngine.EventSystems;using UnityEngine.UI;public class Point : MonoBehaviour, IPointerDownHandler{[Header("暗点素材")] public Sprite closeSprite;[Header("亮点素材")] public Sprite openSprite;public List<Port> ports; //存储点中所有端口数据private int samePort; //存储两点间的相同端口号/// <summary>/// 端口属性/// </summary>[Serializable]public class Port{public int portNum; //端口号public bool isConnected; //是否被连接}/// <summary> 重置点数据 </summary>public void ResetPort(){DimThePoint();samePort = 0;foreach (var port in ports){port.isConnected = false;}}/// <summary>/// 每个点被点击的时候/// </summary>/// <param name="eventData"></param>public void OnPointerDown(PointerEventData eventData){Debug.Log("OnPointerDown: " + gameObject.name);//先判断是否可以为mainPoint并点亮pointif (transform.parent.gameObject.GetComponent<OneStrokeDraw>().mainPoint == null){var oneStrokeDraw = transform.parent.gameObject.GetComponent<OneStrokeDraw>();oneStrokeDraw.mainPoint = this.gameObject;LightenThePoint();//划线操作oneStrokeDraw.LengthOfLineRenderer++;oneStrokeDraw.line.SetVertexCount(oneStrokeDraw.LengthOfLineRenderer);oneStrokeDraw.line.SetPosition(0, gameObject.transform.localPosition);}else if (transform.parent.gameObject.GetComponent<OneStrokeDraw>().mainPoint != this.gameObject){var mainPoint = transform.parent.gameObject.GetComponent<OneStrokeDraw>().mainPoint;Debug.Log(eventData.pointerEnter.gameObject.name);if (CanTwoPointsBeConnected(mainPoint.GetComponent<Point>(),eventData.pointerEnter.gameObject.GetComponent<Point>(), out samePort)){mainPoint.GetComponent<Point>().ChangePortIsConnected(samePort);eventData.pointerEnter.gameObject.GetComponent<Point>().ChangePortIsConnected(samePort);Debug.Log(mainPoint.name + " 与 " +eventData.pointerEnter.gameObject.name + " 相连");var oneStrokeDraw = transform.parent.gameObject.GetComponent<OneStrokeDraw>();oneStrokeDraw.nowNumInIsConnected += 2;//记录已连接的端口数//传递主Point换下一个点继续判断oneStrokeDraw.mainPoint = eventData.pointerEnter.gameObject;eventData.pointerEnter.gameObject.GetComponent<Point>().LightenThePoint();//划线操作//绘制两点间划线//设置线段的端点数oneStrokeDraw.LengthOfLineRenderer++;oneStrokeDraw.line.SetVertexCount(oneStrokeDraw.LengthOfLineRenderer);int drawPosition = oneStrokeDraw.LengthOfLineRenderer - 1;oneStrokeDraw.line.SetPosition(drawPosition, gameObject.transform.localPosition);//通关的判断if (oneStrokeDraw.CheckAllPointsIsConnected()){//TODO 通关处理Debug.Log("成功");}}}}/// <summary> 检查相连的两个点是否可以连接 </summary>public bool CanTwoPointsBeConnected(Point point1, Point point2, out int samePort){foreach (var port1 in point1.ports){//若两个点存在相同端口号if (point2.ports.Exists(port => port.portNum == port1.portNum)){if (!port1.isConnected) //并且还没被连接(唯一性,一般相同端口号相同状态){samePort = port1.portNum;return true; //则这个端口可以连接}}}//不能相连的情况处理samePort = 0;return false;}/// <summary> 使该点变亮点 </summary>public void LightenThePoint(){this.GetComponent<Image>().sprite = openSprite;}/// <summary> 使该点变暗点 </summary>public void DimThePoint(){this.GetComponent<Image>().sprite = closeSprite;}/// <summary>/// 连接点中的端口/// </summary>/// <param name="portNum">端口号</param>public void ChangePortIsConnected(int portNum){var portHash = ports.Find(port => port.portNum == portNum);portHash.isConnected = true;}}

3.OneStrokeDraw(一笔画:点线管理器)

管理点线及总和的变量,组件LineRenderer,并判断通关条件以及重置方法

变量

1.points存储所有点数据

2.line挂载LineRenderer组件

3.isConnectedInSum端口总数

4.LengthOfLineRenderer端点个数 (LineRenderer划线用)

5.mainPoint主节点(当前连到的,要判断的点)

6.nowNumInIsConnected当前已连接端口数

using System;using System.Collections.Generic;using UnityEngine;using UnityEngine.EventSystems;public class OneStrokeDraw : MonoBehaviour{public List<Point> points; //存储所有点数据public LineRenderer line;private int isConnectedInSum; //端口总数private LengthOfLineRenderer = 1;private GameObject mainPoint;private int nowNumInIsConnected; //当前已连接端口数private void Start(){isConnectedInSum = CountIsConnectedInSum(); //记录端口总数}/// <summary> 计算端口总数 </summary>private int CountIsConnectedInSum(){int isConnectedNum = 0;foreach (var point in points){isConnectedNum += point.ports.Count;}return isConnectedNum;}/// <summary> 检查所有点是否都完成连接 (每次连接的时候都会判断) </summary>public bool CheckAllPointsIsConnected(){return isConnectedInSum == nowNumInIsConnected; //遍历每个点耗性能,这是优化的方案}/// <summary> UI层:重置所有点数据 </summary>public void ResetAllPoint(){foreach (var point in points){point.ResetPort();}LengthOfLineRenderer = 0;line.SetVertexCount(LengthOfLineRenderer);//设置线段的端点数// line.SetPosition(0, new Vector3(0, 0, 0));mainPoint = null;nowNumInIsConnected = 0;//取消所有划线}}

总结

以上就是所有要讲的内容,本文仅仅介绍了一笔画的大致实现,目前这个交互方式是点击每个点来连线,而要想拖动连线的话可以使用IDragHandler的其他接口来实现。

要善于分解然后考虑每个要素的特点以及实现,这个是要我们的观察力以及想法构造,不能只靠学,得自己多动手。

感谢观看到这里,祝你我在学习路上更上一层楼!!!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。