算法实现2D OBB碰撞
box
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class DrawLine : MonoBehaviour {
public Vector3[] p = new Vector3[4]; public Vector3 up { get; set; }
public Vector3 right { get; set; } private Cube _cube1;
public Cube cube1 {
get {
if (_cube1 == null) {
_cube1 = new Cube();
_cube1.halfScale = 1;
}
return _cube1;
}
} public Matrix4x4 matrix;
public Color color = Color.green; private void OnDrawGizmos() {
Gizmos.color = color;
Vector3 pos = transform.position;
//设置与transform相同矩阵
matrix = Matrix4x4.TRS(pos, transform.rotation, transform.lossyScale); up = new Vector3(matrix[0, 1], matrix[1, 1], matrix[2, 1]);
right = new Vector3(matrix[0, 0], matrix[1, 0], matrix[2, 0]); p[0] = up - right + pos;
p[1] = -up - right + pos;
p[2] = -up + right + pos;
p[3] = up + right + pos; Gizmos.DrawLine(p[0], p[1]);
Gizmos.DrawLine(p[1], p[2]);
Gizmos.DrawLine(p[2], p[3]);
Gizmos.DrawLine(p[3], p[0]);
}
} public class Cube {
public Vector3 center;
public float halfScale;
public Quaternion rotate; public Vector3 GetPoint1 => center + new Vector3(-halfScale, halfScale, 0);
public Vector3 GetPoint2 => center + new Vector3(-halfScale, -halfScale, 0);
public Vector3 GetPoint3 => center + new Vector3(halfScale, -halfScale, 0);
public Vector3 GetPoint4 => center + new Vector3(halfScale, halfScale, 0);
}
检查是否碰撞
using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class ColliderCheck : MonoBehaviour {
public DrawLine cube1x;
public DrawLine cube2x;
public float lineLength;
public bool check; // Start is called before the first frame update
void Start()
{ } // Update is called once per frame
void Update()
{ } private void OnDrawGizmos() {
//判断 cube1 与 cube2 是否相交
//获取cube2 在 cube的up 和 right 轴上的投影 check = CheckIsAxis(cube1x, cube2x) && CheckIsAxis(cube2x, cube1x);
if (check) {
cube1x.color = Color.red;
cube2x.color = Color.red;
} else {
cube1x.color = Color.green;
cube2x.color = Color.green;
} if (Input.GetKeyDown(KeyCode.K)) { }
} /// <summary>
/// 从矩阵获取坐标
/// </summary>
/// <param name="matrix"></param>
/// <returns></returns>
public Vector3 GetPosition(Matrix4x4 matrix) {
var x = matrix.m03;
var y = matrix.m13;
var z = matrix.m23; return new Vector3(x, y, z);
} /// <summary>
/// 从矩阵获取旋转
/// </summary>
/// <param name="matrix"></param>
/// <returns></returns>
public Quaternion GetRotation(Matrix4x4 matrix) {
//m11 + m22 + m33 = 4w^2
float qw = Mathf.Sqrt(1f + matrix.m00 + matrix.m11 + matrix.m22) / 2;
float w = 4 * qw;
float qx = (matrix.m21 - matrix.m12) / w;
float qy = (matrix.m02 - matrix.m20) / w;
float qz = (matrix.m10 - matrix.m01) / w;
return new Quaternion(qx, qy, qz, qw);
} /// <summary>
/// 从矩阵获取缩放
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public static Vector3 GetScale(Matrix4x4 m) {
var x = Mathf.Sqrt(m.m00 * m.m00 + m.m01 * m.m01 + m.m02 * m.m02);
var y = Mathf.Sqrt(m.m10 * m.m10 + m.m11 * m.m11 + m.m12 * m.m12);
var z = Mathf.Sqrt(m.m20 * m.m20 + m.m21 * m.m21 + m.m22 * m.m22); return new Vector3(x, y, z);
} private bool CheckIsAxis(DrawLine cube1, DrawLine cube2) {
//可得y轴上的最小值与最大值
NewMethod(cube1, cube2, cube1.up, out var maxValue, out var minValue);
//Debug.Log(minValue + " " +maxValue);
//判断y轴是否重合
bool isOverLayY = false;
if (maxValue <= cube1.cube1.halfScale && maxValue >= -cube1.cube1.halfScale) {
isOverLayY = true;
} if (minValue <= cube1.cube1.halfScale && minValue >= -cube1.cube1.halfScale) {
isOverLayY = true;
} //判断x轴
NewMethod(cube1, cube2, cube1.right, out var maxValue2, out var minValue2);
bool isOverLayX = false;
if (maxValue2 <= cube1.cube1.halfScale && maxValue2 >= -cube1.cube1.halfScale) {
isOverLayX = true;
} if (minValue2 <= cube1.cube1.halfScale && minValue2 >= -cube1.cube1.halfScale) {
isOverLayX = true;
} if (isOverLayX && isOverLayY) {
return true;
}
return false;
} private void NewMethod(DrawLine cube1, DrawLine cube2, Vector3 onNormal ,out float maxValue, out float minValue) {
float[] yArray = new float[4];
maxValue = 0;
minValue = 0;
for (int i = 0; i < 4; i++) {
Vector3 cube1Pos = cube1.transform.position;
var line = Vector3.Project(cube2.p[i] - cube1Pos, onNormal);
float yValue = line.magnitude;
yArray[i] = yValue;
//Debug.Log(yValue);
if (i == 0) {
maxValue = yValue;
minValue = yValue;
} else {
if (yValue > maxValue) {
maxValue = yValue;
} if (yValue < minValue) {
minValue = yValue;
}
}
}
}
}



2D凸多边形碰撞检测算法GJK + EPA
https://zhuanlan.zhihu.com/p/178841676
算法实现2D OBB碰撞的更多相关文章
- 游戏中的2D OBB碰撞模型的碰撞算法介绍和实践
前言 上一篇博文说道,射线与场景中模型上的所有三角形求交时,会大幅度影响效率且花费比较多的时间,因此会采取使用包围盒的形式,进行一个加速求交.在此文中介绍OBB碰撞模型的碰撞算法 OBB的碰撞模型 有 ...
- Cocos2d-x教程(34)-三维物体OBB碰撞检測算法
欢迎增加Cocos2d-x 交流群:193411763 个中心点.1个旋转矩阵和3个1/2边长(注:一个旋转矩阵包括了三个旋转轴,若是二维的OBB包围盒则是一个中心点,两个旋转轴,两个1/2边长). ...
- 2D空间的OBB碰撞实现
OBB全称Oriented bounding box,方向包围盒算法.其表现效果和Unity的BoxCollider并无二致.由于3D空间的OBB需要多考虑一些情况 这里仅关注2D空间下的OBB. 实 ...
- [Unity2D]Box Collider 2D盒子碰撞器
盒子碰撞器(BoxCollider2D)是Unity2D中常用的碰撞器,所有为碰撞器,顾名思义,就是用于检测物体之间的碰撞情况的,Unity2D里面除了BoxCollider2D碰撞器之外还集成Box ...
- OBB碰撞
OBB碰撞检测,坐标点逆时针 class OBBTest extends egret.DisplayObjectContainer { private obb1:OBB; private obb2:O ...
- 2D多边形碰撞器优化器
http://www.unity蛮牛.com/thread-19827-1-1.html http://pan.baidu.com/s/1qW2mWS8 Asset Store Link: http: ...
- 游戏碰撞OBB算法(java代码)
业务需求 游戏2D型号有圆形和矩形,推断说白了就是碰撞检测 : 1.圆形跟圆形是否有相交 2.圆形跟矩形是否相交 3.矩形和矩形是否相交 ...
- 使用TouchScript做2D按钮实现长按功能
导入TouchScript 下载地址:https://www.assetstore.unity3d.com/#/content/7394 把TouchScript和Touch Debugger两个预设 ...
- AABB包围盒、OBB包围盒、包围球的比較
1) AABB 包围盒: AABB 包围盒是与坐标轴对齐的包围盒, 简单性好, 紧密性较差(尤其对斜对角方向放置的瘦长形对象, 採用AABB, 将留下非常大的边角空隙, 导致大量不是必需的包围盒相交測 ...
- 创建基本的2D场景(part2)
让我们继续来学习Unity2D游戏场景的制作,本文分为以下3个部分: · 添加角色和控制 . 添加2D物理阻挡 · 添加2D效果 通过制作一个移动帽子接保龄球的小游戏,我们可以学习到任何创建游戏对象, ...
随机推荐
- 免费纯真IP地址数据库的解析
纯真(CZ88.NET)自2005年起一直为广大社区用户提供社区版IP地址库,只要获得纯真的授权就能免费使用,并不断获取后续更新的版本.如果有需要免费版IP库的朋友可以前往纯真的官网进行申请. 纯真除 ...
- Spring注解之自定义注解入门
目录 前言 注解是什么 自定义注解 元注解 @Target @Retention @Documented @Inherited 结束语 Reference 前言 在业务开发过程中,Spring 框 ...
- slf4j、logback、log4j、log4j2的区别
区别 slf4j是一个日志接口,自己没有具体实现日志系统,只提供了一组标准的调用api,这样将调用和具体的日志实现分离,使用slf4j后有利于根据自己实际的需求更换具体的日志系统,比如,之前使用的具体 ...
- 阿里微服务解决方案-Alibaba Cloud之服务消费方(Feign)(四)
一.创建服务消费方并集成OpenFeign 创建模块的方式与创建服务提供方的方式一致 目录结构如下 1.1 创建完项目后,加入 OpenFeign的依赖 在父工程的 pom.xml 文件中加入如下依赖 ...
- SolidWorks下载安装教程(附安装包)SolidWorks 2025 软件全方位指南
一.SolidWorks 2025 软件深度介绍 SolidWorks 2025 是达索系统精心研发推出的一款功能强大且专业的三维机械设计软件,它将 3D CAD 设计.分析及产品数据管理功能高度集成 ...
- 赴一场开源盛会丨10月29日 COSCon'22 开源年会杭州分会场,这里只差一个「你」!
报名地址:https://www.bagevent.com/event/8322877 2022年,世界正在改变,开源创造价值.已经办到第七届的开源年会首次来到杭州与开发者们相聚.你眼中的开源是怎样的 ...
- HyperWorks的四面体网格剖分
HyperMesh 向用户提供了若干种生成四面体网格的方法.标准四面体网格剖分(Standard Tetramesh)基于一个已有的封闭壳单元包络而成的空间,在合理设置参数的基础上生成四面体网格.标准 ...
- 故障处理:Oracle一体机磁盘故障时磁盘组重平衡失败的故障处理
最近半个月遇到有两个客户的Oracle Exadata一体机出现物理磁盘的损坏,一个客户是机械磁盘.一个客户是FLASH磁盘.很巧的是这两个客户他们的日常运维过程中都是只看物理服务器的故障信号灯.但是 ...
- .NET 全栈开发工程师学习路径
PS:最近一直反复地看博客园以前发布的一条.NET全栈开发工程师的招聘启事,觉得这是我看过最有创意也最朴实的一个招聘启事,更为重要的是它更像是一个技术提纲,能够指引我们的学习和提升,现在转载过来与各位 ...
- MongoDB入门实战教程(12)
MongoDB在4.2版本开始全面支持了多文档事务,这也让MongoDB可以作为OLTP的选项之一,本篇我们就来学习一下MongoDB的多文档事务. 1 ACID支持程度 谈到事务,就不得不提经典的A ...