public World world;
void Start()
{
//实例化一个世界时需要给他填入重力Vector2数组
world = new World(new Vector2(0f,0f));
//调整相关参数,这个上文里说过,也可以先通过Profile profile = new Profile();然后更改里面的设定,之后动过profile.xxx进行赋值。
world.AllowSleep = true;
world.WarmStarting = true;
world.ContinuousPhysics = true;
world.SubStepping = true;
}
Body ground;
{
var bd = new BodyDef();
ground = World.CreateBody(bd);
}
var bd = new BodyDef
{
BodyType = BodyType.DynamicBody,
AllowSleep = false,
Position = new Vector2(0.0f, 10.0f)
};
//圆形
var shape = new CircleShape();
shape.Radius = 10f;
shape.Position.Set(0, 0);
body.CreateFixture(shape, 0);
//方形
var shape = new PolygonShape();
shape.SetAsBox(0.5f, 10.0f, new Vector2(10.0f, 0.0f), 0.0f);
body.CreateFixture(shape, 5.0f);
//官方演示demo中并没有使用body位置进行更新,而是通过夹具的碰撞接触点进行图案的绘制,所以当你看完官方演示之后反而会更糊涂了。
//而且Box2D并没有返回id值记录的相关操作,这方面我们需要自己进行维护,这里我直接采用字典进行维护对应关系
private Dictionary objcectList;
//创建一个GameObject,紧随其后创建对应shap和body,然后把body和GameObject塞入字典中,之后用foreach遍历更新即可
//最后,在update中调用。第一个参数填入刷新频率,此时的分母相当于帧数,第二个填入Vel计算次数,第三个填入pos计算次数。经实测两个填入3就有不错的效果。
world.Step(1.0f / 10.0f, 3, 3);
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Box2DSharp.Collision.Shapes;
using Box2DSharp.Common;
using Box2DSharp.Dynamics;
using Box2DSharp.Dynamics.Joints;
using Box2DSharp.Collision;
using Testbed.Abstractions;
using System;
using Joint = Box2DSharp.Dynamics.Joints.Joint;
using Vector2 = System.Numerics.Vector2;
using Color = Box2DSharp.Common.Color;
using Random = UnityEngine.Random;
using UnityEngine.UI;
using Box2DSharp.Dynamics.Contacts;
using Box2DSharp.Collision.Collider;
public class CirlTest : MonoBehaviour
{
// Start is called before the first frame update
[SerializeField]
private GameObject _prefab;
[SerializeField]
private GameObject _squarePrefab;
[SerializeField]
private UnityEngine.Transform _transform;
public World world;
private int cnt = 300;
private int now_cnt;
private Dictionary objcectList;
[Range(0f, 1f)]
public float speed = 0.1f;
//show fps
private float m_frameCount = 0.0f;
private string m_fpsText;
private float m_lastPrintTime = 0.0f;
private GUIStyle m_style;
[SerializeField]
private Text m_text;
private bool flag;
void Start()
{
world = new World(new Vector2(0f,0f));
world.AllowSleep = true;
world.WarmStarting = true;
world.ContinuousPhysics = true;
world.SubStepping = true;
//创建地面
var groundBodyDef = new BodyDef { BodyType = BodyType.StaticBody };
groundBodyDef.Position.Set(0.0f, -10.0f);
var groundBody = world.CreateBody(groundBodyDef);
objcectList = new Dictionary();
objcectList.Clear();
now_cnt = 0;
//show fps
m_style = new GUIStyle { fontSize = 20, };
}
// Update is called once per frame
private void FixedUpdate()
{
calFPS();
if (flag == false) return;
UpdatePosition();
}
protected void PreStep()
{
float rx = Random.Range(-50.0f, 50.0f);
float ry = Random.Range(-50.0f, 50.0f);
if(now_cnt >= 30)
{
//创建实例化对象
var circle = GameObject.Instantiate(_prefab, new UnityEngine.Vector2(rx, ry), Quaternion.identity);
circle.transform.SetParent(_transform);
//在world中对应创建对象
var bodyDef = new BodyDef { BodyType = BodyType.DynamicBody };
var shape = new CircleShape();
shape.Radius = 0.95f;
bodyDef.Position.Set(rx, ry);
var body = world.CreateBody(bodyDef);
body.CreateFixture(shape, 1.0f);
objcectList.Add(body, circle);
}
else
{
//创建实例化对象
var square = GameObject.Instantiate(_squarePrefab, new UnityEngine.Vector2(rx, ry), Quaternion.identity);
square.transform.SetParent(_transform);
//square.transform.localScale = new Vector3(, 1, 1);
var bd = new BodyDef
{
BodyType = BodyType.DynamicBody,
Position = new Vector2(rx, ry),
FixedRotation = false
};
var body = world.CreateBody(bd);
var shape = new PolygonShape();
shape.SetAsBox(1f, 2f);
var fixtureDef = new FixtureDef
{
Shape = shape,
Density = 0.001f,
Friction = 0.3f
};
//body.ApplyForceToCenter(new Vector2(-rx/10, -ry/10), true);
body.AngularDamping = 0.01f;
body.CreateFixture(fixtureDef);
objcectList.Add(body, square);
}
++now_cnt;
}
private void UpdatePosition()
{
foreach (var obj in objcectList)
{
Vector2 pos = obj.Key.GetPosition();
float angle = UnityEngine.Vector2.SignedAngle(new UnityEngine.Vector2(pos.X,pos.Y), UnityEngine.Vector2.left);
obj.Key.SetTransform(pos - pos * speed * Time.deltaTime, angle);
}
world.AllowSleep = true;
world.WarmStarting = true;
world.ContinuousPhysics = true;
world.SubStepping = true;
if (now_cnt < cnt)
{
PreStep();
}
world.Step(1.0f / 10.0f, 3, 3);
foreach (var obj in objcectList)
{
Vector2 pos = obj.Key.GetPosition();
obj.Value.transform.position = new UnityEngine.Vector2(pos.X,pos.Y);
obj.Value.transform.rotation = Quaternion.Euler(new Vector3(0,0, obj.Key.GetAngle()));
//if (obj.Key.GetAngle() >= 1f) Debug.Log(obj.Key.GetAngle());
}
}
//show fps
private void calFPS()
{
m_frameCount += 1.0f;
float currentTime = UnityEngine.Time.realtimeSinceStartup;
float passedTime = currentTime - m_lastPrintTime;
//每秒钟计算一次fps
if (passedTime >= 1.0f)
{
float fps = m_frameCount / passedTime;
m_fpsText = string.Format("FPS:{0:0.00}", fps);
m_frameCount = 0.0f;
m_lastPrintTime = currentTime;
}
}
void OnGUI()
{
if (string.IsNullOrEmpty(m_fpsText) == false)
{
GUI.Label(new Rect(20.0f, 0.0f, 300.0f, 20.0f), m_fpsText, m_style);
}
}
public void OnClickedBtn()
{
cnt = int.Parse(m_text.text);
flag = true;
}
}