【游戏开发实战】TapTap物理画线游戏,教你使用Unity实现2D物理画线功能,看到我为你画的彩虹了吗
文章目录
- 一、前言
- 二、思考
- 三、验证我们的思考
- 1、创建物体挂组件
- 2、设置组件参数
- 3、运行测试
- 4、结论
- 四、撸起袖子写代码
- 1、Line.cs
- 2、LinesDrawer.cs
- 五、场景
- 六、最终运行效果
一、前言
嗨,大家好,我是新发,我又来科普了,相信很多人玩过物理画线小游戏,比如下面这样子:
使用Unity
如何实现物理画线功能呢?今天就来教大家。
最后的实现效果如下:
本工程已上传到GitHub
,感兴趣的同学可自行下载学习。
GitHub
地址:https://github.com/linxinfa/UnityPhysicsDrawLine
二、思考
物理画线的核心就是:物理+画线。
物理:
想要有物理特性,最简单的做法就是挂碰撞体(Collider
)和刚体(Rigidbody
)组件。
画线:
可以使用LineRenderer
组件来实现画线功能。
三、验证我们的思考
1、创建物体挂组件
创建一个空物体,重命名为Line
,挂上EdgeCollider2D
、Rigidbody2D
和LineRenderer
组件。
2、设置组件参数
设置一下LineRenderer
组件的参数。
Position
:坐标点;
Width
:线宽度;
Color
:线颜色(支持渐变);
Corner Vertices
:拐弯处的顶点数量(让拐弯圆滑一点);
End Cap Vertices
:线段头尾的顶点数量(让线段头尾圆滑一点);
Use World Space
:是否使用世界坐标(不要勾选);
Materias
:材质球。
设置一下EdgeCollider2D
组件的参数。
Edge Radius
:边界碰撞体的半径。
Points
:边界碰撞体的坐标点(要与LineRenderer
的点一致)。
边界碰撞体设置完之后效果如下:
最后是Rigidbody2D
组件的参数。主要是Gravity Scale
:重力缩放值;这个值越大,物体受到的重力越大,掉落的加速度就越大。
3、运行测试
为了模拟掉落到地上的效果,我们加个地面。
运行测试效果如下:
4、结论
理论存在,实践验证成功。那么,接下来就是如何使用代码来实现鼠标画线了,关键的点就是把鼠标的坐标设置为线的点。
四、撸起袖子写代码
两个脚本,一个Line.cs
负责线段的绘制,一个LinesDrawer.cs
负责检测鼠标和生成线段与点。
1、Line.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;/// <summary>
/// 线脚本
/// </summary>
public class Line : MonoBehaviour
{public LineRenderer lineRenderer;public EdgeCollider2D edgeCollider;public Rigidbody2D rigidBody;/// <summary>/// 点数组/// </summary>[HideInInspector] public List<Vector2> points = new List<Vector2>();[HideInInspector] public int pointCount = 0;/// <summary>/// 画线过程中点与点的最小距离/// </summary>float pointsMinDistance = 0.1f;float circleColliderRadius;/// <summary>/// 添加点/// </summary>/// <param name="newPoint"></param>public void AddPoint(Vector2 newPoint){if (pointCount >= 1 && Vector2.Distance(newPoint, GetLastPoint()) < pointsMinDistance)return;points.Add(newPoint);++pointCount;// 添加圆形碰撞var circleCollider = this.gameObject.AddComponent<CircleCollider2D>();circleCollider.offset = newPoint;circleCollider.radius = circleColliderRadius;// Line RendererlineRenderer.positionCount = pointCount;lineRenderer.SetPosition(pointCount - 1, newPoint);// 边界碰撞体的点if (pointCount > 1)edgeCollider.points = points.ToArray();}/// <summary>/// 获取最后一个点/// </summary>/// <returns></returns>public Vector2 GetLastPoint(){return lineRenderer.GetPosition(pointCount - 1);}/// <summary>/// 是否启用物理特性/// </summary>public void UsePhysics(bool usePhysics){rigidBody.isKinematic = !usePhysics;}/// <summary>/// 设置线颜色/// </summary>/// <param name="colorGradient"></param>public void SetLineColor(Gradient colorGradient){lineRenderer.colorGradient = colorGradient;}/// <summary>/// 设置画线的点与点之间的最小距离/// </summary>/// <param name="distance"></param>public void SetPointsMinDistance(float distance){pointsMinDistance = distance;}/// <summary>/// 设置线宽度/// </summary>/// <param name="width"></param>public void SetLineWidth(float width){lineRenderer.startWidth = width;lineRenderer.endWidth = width;circleColliderRadius = width / 2f;edgeCollider.edgeRadius = circleColliderRadius;}
}
2、LinesDrawer.cs
using UnityEngine;/// <summary>
/// 画线控制器
/// </summary>
public class LinesDrawer : MonoBehaviour
{public GameObject linePrefab;public LayerMask cantDrawOverLayer;int cantDrawOverLayerIndex;[Space(30)]public Gradient lineColor;public float linePointsMinDistance;public float lineWidth;Line currentLine;Camera cam;private void Start(){cam = Camera.main;cantDrawOverLayerIndex = LayerMask.NameToLayer("CantDrawOver");}private void Update(){if (Input.GetMouseButtonDown(0))BeginDraw();if (null != currentLine)Draw();if (Input.GetMouseButtonUp(0))EndDraw();}// 画线逻辑-----------------------------------------------------------------------// 开始画线void BeginDraw(){// 实例化线预设currentLine = Instantiate(linePrefab, this.transform).GetComponent<Line>();// 设置参数currentLine.UsePhysics(false);currentLine.SetLineColor(lineColor);currentLine.SetPointsMinDistance(linePointsMinDistance);currentLine.SetLineWidth(lineWidth);}// 画线进行中void Draw(){var pos = cam.ScreenToWorldPoint(Input.mousePosition);// 防止线与线之间交叉RaycastHit2D hit = Physics2D.CircleCast(pos, lineWidth / 3f, Vector2.zero, 1f, cantDrawOverLayer);if (hit)EndDraw();elsecurrentLine.AddPoint(pos);}// 画线结束void EndDraw(){if (null == currentLine) return;if (currentLine.pointCount < 2){Destroy(currentLine.gameObject);}else{currentLine.gameObject.layer = cantDrawOverLayerIndex;currentLine.UsePhysics(true);currentLine = null;}}
}
五、场景
将原来的Line
保存为预设,并挂上Line
脚本,赋值对应的变量。
添加一个Layer
:CantDrawOver
,目的是防止画线的时候线与线交叉(也可以防止线与其他被标记为CantDrawOver
层的物体交叉)。
在场景中创建一个空物体,重命名为LineDrawer
,并挂上LineDrawer
脚本,赋值对应的参数。
六、最终运行效果
【游戏开发实战】TapTap物理画线游戏,教你使用Unity实现2D物理画线功能,看到我为你画的彩虹了吗相关推荐
- HTML5 Canvas游戏开发实战 PDF扫描版
HTML5 Canvas游戏开发实战主要讲解使用HTML5 Canvas来开发和设计各类常见游戏的思路和技巧,在介绍HTML5 Canvas相关特性的同时,还通过游戏开发实例深入剖析了其内在原理,让读 ...
- HTML5游戏开发实战
<HTML5游戏开发实战> 基本信息 原书名:HTML5 Games Development by Example: Beginner's Guide 作者: (美)Makzan 译者: ...
- 游戏开发实战之弹球游戏
文/Steffen Itterheim.Andreas Löw 为了更好地使用Box2D物理引擎,本文我们将制作一个真实的弹球游戏.弹球游戏桌利用各种物理世界的效果来创造有趣的体验.然而,在使用物理引 ...
- 《HTML5 Canvas游戏开发实战》——2.1 绘制基本图形
本节书摘来自华章计算机<HTML5 Canvas游戏开发实战>一书中的第2章,第2.1节,作者:张路斌著, 更多章节内容可以访问云栖社区"华章计算机"公众号查看. 2. ...
- 从踩坑到填坑|淘宝Web 3D应用与游戏开发实战
导读:本文是淘宝前端技术专家--徐乾伟(烧鹅)分享的淘宝 Web 3D 应用与游戏开发实战,这个话题在业界被谈及得比较少.今天将会从移动.3D.游戏三种交叉的话题来和大家探讨.接下来和小编一起从初试 ...
- 【游戏开发实战】Unity手游第一人称视角,双摇杆控制,FPS射击游戏Demo(教程 | 含Demo工程源码)
文章目录 一.前言 二.实现方案 1.无主之地,第一人称视角 2.我之前做的摇杆控制 3.第一人称视角 + 摇杆控制 三.开始实战 1.资源获取:Unity AssetStore 2.Low Poly ...
- 《Unity 5.x游戏开发实战》一1.9 添加一个水平面
本节书摘来异步社区<Unity 5.x游戏开发实战>一书中的第1章,第1.9节,作者: Alan Thorn 译者: 李华峰 责编: 胡俊英,更多章节内容可以访问云栖社区"异步社 ...
- 【游戏开发实战】用Go语言写一个服务器,实现与Unity客户端通信(Golang | Unity | Socket | 通信 | 教程 | 附工程源码)
文章目录 一.前言 二.Go开发环境搭建(Windows系统) 1.安装Go命令行工具 2.创建GoWorkspace目录 3.配置GOPATH环境变量 4.配置GOPROXY代理 5.安装VSCod ...
- 《Unity 2D与3D手机游戏开发实战》简介
#好书推荐##好书奇遇季#<Unity 2D与3D手机游戏开发实战>,京东当当天猫都有发售.彩色印制,定价89元,网店打折销售更便宜.本书配套源码.PPT课件,适合Unity游戏开发初学者 ...
最新文章
- UE5蓝图初学课程 Unreal Engine 5: Blueprints for Beginners
- java直接打开word_Java
- java final修饰符_java final修饰符详解,final修饰方法
- webClient 利用代理连接Rss资源
- hive导数据到mysql 自增主键出错_老大问我:“建表为啥还设置个自增 id ?用流水号当主键不正好么?”...
- [转]pthread用于进程间通信
- ActivityGroup自我堆栈管理(复用现有activity)
- 【C++】源自指针的报错
- sum() over() 函数的使用
- boost::io::quoted用法的测试程序
- 基类使用私有数据_C++作业之多继承与虚基类
- c++图的创建_「PS抠图系列13」通道混合器
- 在Windows Server2012系统中安装Oracle11g
- 蓝字冲销是什么意思_会计做帐中用红字和蓝字代表的意思是什么
- 人工智能剥夺就业岗位?不妨听听马斯克是如何建议的
- Linux命令行上程序执行的那一刹那!
- Hadoop-day07(MapReduce三个小案例)
- 朝花夕拾 - jsliang 大白前端新年庆
- 微信步数日历打卡小程序
- Papers with Code一个查找论文和对应代码的神器
热门文章
- P2P常见名词的解释
- Cadence Allegro自动放置所有元件图文教程及视频演示
- Chains (链 )
- 软文营销拒绝一成不变用故事建立情感依恋
- 服务器证书已过期,WebSphere应用服务器证书过期问题解决
- dsp31段最佳调音图_DSP调音技术~DSP功放31段EQ详解~DSP调音师推荐
- poi设置excel行高
- 华硕k5555l拆解图解_【多图】【教程】华硕K555L笔记本拆机除尘图解,通用此类模具所有笔记本...
- FB和FF MIC的用途
- 白话VPB(volume parameter block)