老规矩先上图:

最近在做一个做一个游戏,绳子缠绕在一起然后需要把绳子解开方能赢得游戏。因为需要用到一个绳子的效果,网了查了不少资料一方面是用插件Obi Rope 或 Megafiers 都可以实现,另一方面比较硬核的可以使用自己的算法也可以用关节什么的。

但由于IOS14以上版本对代码审核非常严格,很多插件是无法使用的,只能自己写算法了,网上很多方法都是使用关节实现的绳子效果,绳子并非一条连贯的绳子,以下分享一实现的方式:
一、使用铰链关节(Hinge Joint)把球体串起,保留Sphere Collider和Rigidbody。

二、随便找下物体挂上下面脚本,使物体可以被拖拽。

using UnityEngine;public class MousePosHandle : MonoBehaviour
{#region 公有变量//------------------------------------------------------------------------------------//------------------------------------------------------------------------------------#endregion#region 私有变量//------------------------------------------------------------------------------------private Transform dragGameObject;private Vector3 offset;private bool isPicking;private Vector3 targetScreenPoint;//------------------------------------------------------------------------------------#endregion#region 公有方法#endregion#region 私有方法//------------------------------------------------------------------------------------private void Update(){if (Input.GetMouseButtonDown(0)){if (CheckGameObject()){offset = dragGameObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, targetScreenPoint.z));}}if (isPicking){//当前鼠标所在的屏幕坐标Vector3 curScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, targetScreenPoint.z);//把当前鼠标的屏幕坐标转换成世界坐标Vector3 curWorldPoint = Camera.main.ScreenToWorldPoint(curScreenPoint);Vector3 targetPos = curWorldPoint + offset;dragGameObject.position = targetPos;}if (Input.GetMouseButtonUp(0)){isPicking = false;if (dragGameObject != null){dragGameObject = null;}}}//------------------------------------------------------------------------------------/// <summary>/// 检查是否点击到cbue/// </summary>/// <returns></returns>bool CheckGameObject(){Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);RaycastHit hitInfo;if (Physics.Raycast(ray, out hitInfo, 1000f)){isPicking = true;//得到射线碰撞到的物体dragGameObject = hitInfo.collider.gameObject.transform;targetScreenPoint = Camera.main.WorldToScreenPoint(dragGameObject.position);return true;}return false;}//------------------------------------------------------------------------------------#endregion
}

三、 建模一个圆柱体网格大概是酱子,节不能太少因为绳子会不柔顺,也不能太多因为 性能会伤不起。

四、加了一个可爱的贴图

五、然后把球和网格放在一起。

六、创建MonoBehaviour,添加脚本并挂上对应物体,通过先找到所有球

public MeshFilter TargetMesh;               //网格
public Transform BallGroup;                 //球体集合(关节上所有球放这)
private List<Transform> m_listBall;         //存放所有球体
private List<MeshData> m_listMeshData;      //节点数据void Start(){m_listBall = new List<Transform>();foreach (Transform tran in BallGroup){m_listBall.Add(tran);}
}

七、提供一个方法,帮所有网格节点找到对应的球节点,网格自动寻找离自己最近的球为目标。

private Transform __FindNearest(Vector3 v3){if (m_listBall != null){float MaxDis = 999999;Transform MaxTran = null;for (int i = 0; i < m_listBall.Count; i++){float curDis = Vector3.Distance(m_listBall[i].localPosition, v3);if (curDis < MaxDis){MaxDis = curDis;MaxTran = m_listBall[i];}}return MaxTran;}return null;}

八、提供记录节点数据的数据结构

public class MeshData
{public int Index;               //索引public Transform target;        //目标球球public Vector3 offset;          //与目标球球位置差距
}

九、在Start中调用以下代码找到各节点的目标与位差信息

m_listMeshData = new List<MeshData>();int totleMeshPoint = TargetMesh.mesh.vertices.Length;for (int i = 0; i < totleMeshPoint; i++){MeshData data = new MeshData();data.Index = i;data.target = __FindNearest(TargetMesh.mesh.vertices[i]);if (data.target == null) Debug.Log("有空的");data.offset = TargetMesh.mesh.vertices[i] - data.target.localPosition;m_listMeshData.Add(data);}

十、然后在Update调用以下方法,并拖动。你会得到下面的效果:

 private void MoveMeshPoint(){Vector3[] v3 = TargetMesh.mesh.vertices;for (int i = 0; i < m_listMeshData.Count; i++){MeshData curData = m_listMeshData[i];v3[i] = curData.target.localPosition+ curData.offset;}TargetMesh.mesh.vertices = v3;}


十一、跟着动了对吗?显然这还不是我们要的最终效果,优化一下加上这句,
让位置着跟着球球旋转一下:

Vector3 dir = curData.target.transform.TransformDirection(curData.offset);

变成这样:

private void MoveMeshPoint(){Vector3[] v3 = TargetMesh.mesh.vertices;for (int i = 0; i < m_listMeshData.Count; i++){MeshData curData = m_listMeshData[i];Vector3 dir = curData.target.transform.TransformDirection(curData.offset);v3[i] = curData.target.localPosition + dir;}TargetMesh.mesh.vertices = v3;}


十二、完整代码:

using System.Collections.Generic;
using UnityEngine;public class TestMono : MonoBehaviour
{public MeshFilter TargetMesh;               //网格public Transform BallGroup;                 //球体集合(关节上所有球放这)private List<Transform> m_listBall;         //存放所有球体private List<MeshData> m_listMeshData;      //节点数据void Start(){m_listBall = new List<Transform>();foreach (Transform tran in BallGroup){m_listBall.Add(tran);}m_listMeshData = new List<MeshData>();int totleMeshPoint = TargetMesh.mesh.vertices.Length;for (int i = 0; i < totleMeshPoint; i++){MeshData data = new MeshData();data.Index = i;data.target = __FindNearest(TargetMesh.mesh.vertices[i]);if (data.target == null) Debug.Log("有空的");data.offset = TargetMesh.mesh.vertices[i] - data.target.localPosition;m_listMeshData.Add(data);}}// Update is called once per framevoid Update(){MoveMeshPoint();}private void MoveMeshPoint(){Vector3[] v3 = TargetMesh.mesh.vertices;for (int i = 0; i < m_listMeshData.Count; i++){MeshData curData = m_listMeshData[i];Vector3 dir = curData.target.transform.TransformDirection(curData.offset);v3[i] = curData.target.localPosition + dir;}TargetMesh.mesh.vertices = v3;}private Transform __FindNearest(Vector3 v3){if (m_listBall != null){float MaxDis = 999999;Transform MaxTran = null;for (int i = 0; i < m_listBall.Count; i++){float curDis = Vector3.Distance(m_listBall[i].localPosition, v3);if (curDis < MaxDis){MaxDis = curDis;MaxTran = m_listBall[i];}}return MaxTran;}return null;}}public class MeshData
{public int Index;               //索引public Transform target;        //目标球球public Vector3 offset;          //与目标球球位置差距
}

有问题请与我取得联系。
Demo地址:
https://download.csdn.net/download/ww1351646544/15345650

Unity绳子/绳索效果相关推荐

  1. Unity绳子插件QuickRopes使用方法(让你快速创建你想要的绳索效果)

    QuickRope插件使用教程 QuickRope插件介绍 插件demo演示说明 如何快速创建一条绳子或锁链 绳子编辑脚本QuickRope说明 基本设置: 物理属性设置: 链接处的预制体属性的设置 ...

  2. Unity 绳子效果 插件(Obi Rope )

    插件下载地址 Obi Rope插件地址 Obi Rope插件地址 一.绳子解算类脚本控制 1.Max Particles :最大粒子数 2.Max Diffuse Particles://最大传播默认 ...

  3. unity 条目换位效果_Unity AI主题博客条目

    unity 条目换位效果 Welcome to the first of Unity's new AI-themed blog entries! We have set up this space a ...

  4. [Unity绳子插件]Obi - Advanced Rope Simulation的使用

    今天我们用一个插件来做一个拖动绳子的效果,首先导入插件: 如果是比较旧的版本文件路径要注意一下 注意文件夹路径放置,一定要放正确: 把这两个文件夹拖到Assets下,正确路径如下所示: 下面我用的是比 ...

  5. Unity 实现贴花效果的制作教程

    c#教程​https://www.cnblogs.com/Yesi/p/15829200.html ​ 有些游戏中的战斗痕迹的效果会通过贴花来实现的,贴花的方式多种多样.而在Unity中,有一种给官方 ...

  6. unity气流模拟效果

    机房气流模拟效果 参考 效果展示: 资源链接:unity气流模拟效果-Unity3D文档类资源-CSDN下载

  7. 用Unity实现景深效果

    用Unity实现景深效果 景深也是一种非常常见的后处理手段,它用来模拟相机拍摄画面的效果.今天我们讨论如何在Unity中实现它. 简单来说,景深效果可以拆分为两个部分,一个部分是聚焦,使画面中指定的区 ...

  8. Unity 翻书效果

    Unity翻书效果 目前做的VR项目中需要一个翻阅魔法书的效果,考虑过使用UnityBookPageCurl-master插件,但是那个插件是纯UI显示的,只有二维效果,在VR里观感不佳,之后在网上找 ...

  9. Unity时光倒流效果实现

    Unity时光倒流效果实现<25/11/2017> 场景:一个Panel,一个由众多小Cube堆叠而成的巨大Cube,巨大Cube中心放置爆炸点Bomb. 实现方式:一共就三个脚本,每个C ...

最新文章

  1. 谈博客的赢(盈)利模式
  2. AI Time | 论道数据共享开放与隐私保护
  3. 源码解析 React Hook 构建过程
  4. DOM操作表格的各种属性[z]
  5. flask项目从本地迁移到服务器上遇到net::ERR_CONNECTION_R问题
  6. 【工具】克隆题库(适用于所有以POJ2005-2017为模板的OJ平台)
  7. 如何分析EFCore引发的内存泄漏
  8. win下nginx+php+mysql服务器套装_WNMP(Windows+Nginx+PHP+MySQL)安装
  9. javah找不到类文件
  10. Linux上简体繁体文件的相互转换
  11. sessionstorage ie8下跨页面_前端页面布局困难?教你用盒子模型一招解决
  12. Azkaban 外部接口的使用与开发
  13. uclibc 中的 dlopen 不是线程安全的
  14. codeforces 792CDivide by Three(两种方法:模拟、动态规划
  15. uni app项目资讯列表展开与收起
  16. 核心网upf作用_5G核心网SMF和UPF拓扑增强技术研究
  17. Android趣味课程:九宫格拼图游戏
  18. 金蝶K3Cloud中DBUtils的用法
  19. 网站盈利有哪些模式?
  20. 网上订餐python_网上订餐管理系统摘要.doc

热门文章

  1. 如何在51单片机实现电子万年历
  2. 学计算机的男孩情商高吗,2021情商高的男孩适合学什么专业
  3. 学历教育如何做快手广告投放?快手广告投放的展现量介绍
  4. 华为机试真题实战应用【赛题代码篇】-购买水果最便宜的方案(附Java和C++代码实现)
  5. 读万卷书不如行万里路,行万里路不如阅人无数,阅人无数不如名师指路,名师指路不如自己去悟
  6. MD5校验(checksum)
  7. PDF Search 10.3 PDF文档搜索工具
  8. 虚拟机ping外网连接失败解决方法
  9. 计算机组成原理有如下c语言程序段,《计算机组成原理》课后题答案 清华大学出版 秦磊华 吴非··...
  10. VMware报错 无法打开内核设备 \\.\Global\vmx86: 系统找不到指定的文件