Chinar 的初衷是将一种简单的生活方式带给世人 使有限时间 具备无限可能 |
助力快速理解 Physic.Simulate 绘制运动轨迹 为初学者节省宝贵的时间,避免采坑! |
Chinar 教程效果:
1
Presentation —— 介绍
同一场景,解决多种物理效果并存问题
愤怒小鸟、桌球、爆炸....
Unity 2018.3以后支持多个物理场景
用以解决物理限制问题
看了下官方发布的视频中一个比较有意思的案例
台球轨迹案例
但我没找到官方的例子 地址在哪
于是自己实现了一个简单的效果,供大家参考学习了解 PhysicsScene的用法所在
本质就是,一个场景下 有多种物理效果。可自己定义,如何表现 !
大家可以自己看下发布文档,地址如下:
Unity 2018.3发布文档!( Chinar Blog )
2
Demo —— 栗子
一个桌球场景,我们先来模拟被击打白球的运动轨迹
原理就是创建一个 白球
克隆对象,在第二场景中模拟白球的物理运动轨迹,并记录轨迹!
也就是创建一个不可见的场景,用来模拟白球的运动轨迹绘制。
点击鼠标左键,击打白球,验证轨迹是否正确。二者互不影响
注意物理:两个场景完全独立 !
代码
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
/// <summary>
/// 模拟轨迹
/// </summary>
public class ChinarForece : MonoBehaviour
{
public Transform DirectionBall; //指向方向的球
public Transform TrackBallTransform; //轨迹球
private Rigidbody trackBallRigidbody; //
public Slider VelocitySlider; //力度值 滑动器
public Slider AngleSlider; //角度值
private PhysicsScene physicsScene; //物理场景
public GameObject[] OtherGameObjects; //所有小球
public int TrackFrames = 80; //轨迹帧率
private int ICount; //对象计数
private float timer;
/// <summary>
/// 对象池字典
/// </summary>
private readonly Dictionary<int, Transform> goDict = new Dictionary<int, Transform>();
void Start()
{
AngleSlider.onValueChanged.AddListener(OnValueChanged);
trackBallRigidbody = TrackBallTransform.GetComponent<Rigidbody>();
Physics.autoSimulation = false;
CreatePhysicsScene();
GeneratePool();
}
/// <summary>
/// 创建一个用于模拟的场景
/// </summary>
private void CreatePhysicsScene()
{
var scene = SceneManager.CreateScene("指向模拟场景");
physicsScene = scene.GetPhysicsScene();
SceneManager.MoveGameObjectToScene(DirectionBall.parent.gameObject, scene);
for (int i = 3; i < OtherGameObjects.Length; i++)
{
SceneManager.MoveGameObjectToScene(OtherGameObjects[i], scene);
}
}
/// <summary>
/// 生成池子
/// 轨迹球 重复利用
/// </summary>
private void GeneratePool()
{
var GoPoolPos = new Vector3(100, 100, 100);
for (int i = 0; i < TrackFrames; i++)
{
var iclone = Instantiate(TrackBallTransform);
iclone.position = GoPoolPos;
iclone.localScale=Vector3.one*0.5f;
goDict.Add(i, iclone);
}
}
/// <summary>
/// 重置球位置
/// 其他球要隐形的
/// </summary>
private void resetOtherBall()
{
for (int i = 0; i < 3; i++)
{
OtherGameObjects[i + 3].transform.position = OtherGameObjects[i].transform.position;
}
}
/// <summary>
/// 角度发生改变时
/// </summary>
public void OnValueChanged(float value)
{
Physics.autoSimulation = false; //关闭 物理模拟
TrackBallTransform.position = transform.position;
trackBallRigidbody.velocity = Vector3.zero;
DirectionBall.parent.rotation = Quaternion.Euler(0, value, 0);
Vector3 vector3 = DirectionBall.position - transform.position;
trackBallRigidbody.AddForce(vector3 * VelocitySlider.value);
for (int i = 0; i < TrackFrames; i++)
{
physicsScene.Simulate(0.02f);
GoPool().position = TrackBallTransform.position;
}
}
/// <summary>
/// 简化版对象池
/// 每次调用返回一个新对象
/// </summary>
private Transform GoPool()
{
ICount++;
if (ICount == TrackFrames - 1)
{
ICount = 0;
}
return goDict[ICount];
}
void Update()
{
if (!EventSystem.current.IsPointerOverGameObject())
{
if (Input.GetMouseButtonUp(0))
{
Physics.autoSimulation = true;
Vector3 vector3 = DirectionBall.position - transform.position;
GetComponent<Rigidbody>().AddForce(vector3 * VelocitySlider.value);
}
}
}
}
3
Demo 2 —— 栗子 2
碰撞后,被碰撞物体的运动轨迹绘制
将动量传递给碰撞对象,得到碰撞的对象。 从而记录被碰撞对象的运动轨迹
调用 physicsScene.Simulate(0.02f);
完成轨迹预测;
这个API 需要 Physics.autoSimulation = false;
//关闭 物理模拟
然后自行调用,每调用一次 执行一帧物理刷新
支持
May Be —— 开发者,总有一天要做的事!
Chinar 提供一站式《零》基础教程 使有限时间 具备无限可能! |
Chinar 免费服务器、建站教程全攻略!( Chinar Blog )
![](https://img-blog.csdnimg.cn/20190508013858624.png)
![Chinar交流群 Chinar](http://pub.idqqimg.com/wpa/images/group.png)
本博客为非营利性个人原创,除部分有明确署名的作品外,所刊登的所有作品的著作权均为本人所拥有,本人保留所有法定权利。违者必究
对于需要复制、转载、链接和传播博客文章或内容的,请及时和本博主进行联系,留言,Email: ichinar@icloud.com
对于经本博主明确授权和许可使用文章及内容的,使用时请注明文章或内容出处并注明网址