Unity三体运行模拟体验
这两天看完三体电视剧,很想体验一把三体人的世界…于是,说干就干。
先来看看效果吧
先来个上帝视角的
Unity三体模拟上帝视角
然后再来个三体人视角的(行星视角)
Unity三体运行模拟(行星视角+上帝视角)
其实很简单
简单的复习一下万有引力定律:
F = G M ⋅ m r 2 F = G{
{M·m}\over{r^2}} F=Gr2M⋅m
其中,F是两个物体间的引力,G是引力常数,M和m分别是两个物体的质量,r是他们之间的距离。
搭个简单的场景
这场景实在是太简单,就4个球。为了好看点,材质加了纹理、法线、发光贴图,然后PostProcess环境简单调试一下,场景默认的平行灯禁用,给3个太阳添加灯光组件。如下图所示:
然后简单的写几行代码
总共用了3个脚本:
脚本1:星星管理器。
主要提供游戏里用到的几个静态变量,没有别的用了。
using UnityEngine;
public class GameLogic : MonoBehaviour
{
public const float G = 0.03f;
public static ThreeBody[] bodys;
private void Awake()
{
bodys = GetComponentsInChildren<ThreeBody>();
}
}
脚本2:星星运行(核心)
using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
public class ThreeBody : MonoBehaviour
{
[SerializeField] private float initSpeed; // 初始速度
public Vector3 position
{
get => transform.position;
set => transform.position = value;
}
private Rigidbody rigid;
private void Awake()
{
rigid = GetComponent<Rigidbody>();
}
private void Start()
{
// 如果想让星星初始时随机朝向,那么取消注释这一句
// transform.forward = Random.onUnitSphere;
// 赋值一下星星的初始速度
rigid.velocity = transform.forward * initSpeed;
}
private void Update()
{
Vector3 force = Vector3.zero;
// 枚举所有的星星
foreach (var body in GameLogic.bodys)
{
if(body == this) // 自己的话就跳过
continue;
// 计算另一个星星和自己的偏移,也就是指向另一个星星的方向
Vector3 offset = body.position - position;
// 万有引力公式
force += offset.normalized * (body.rigid.mass * rigid.mass * GameLogic.G / offset.sqrMagnitude);
}
// 将计算得到里引力,施加到刚体上
rigid.AddForce(force);
}
}
脚本三:星星自转(没有也行)
using UnityEngine;
public class SelfRotation : MonoBehaviour
{
[SerializeField] private Vector3 axis;
[SerializeField] private float Speed;
private void Update()
{
transform.Rotate(axis, Speed * Time.deltaTime);
}
}
感想
这个参数确实很难调啊,总是运行一会儿就碰到一起了。很难调整处一个很稳定的结构。稍微调一点点参数,初始位置、初始速度、引力系数、质量。。。那么结果是千差万别。甚至一样的条件下,计算机帧率不同,结果就不同。呵呵。只能算个粗略的模拟吧,但是能感受到效果了不是吗??还能看见“引力弹弓”的神奇。总体来说,很适合新手去练练手。
相关代码
点击下载源码
源码中包括很多精美的地面高清贴图,还有很多精美的夜空、星空、天空盒。