游戏对象运动的本质是什么?
游戏对象运动的本质是变换游戏对象自身的坐标。
在游戏开发中,我们可以通过矩阵变换的方式实现游戏对象的变换,比如:
public class TranslationScript : MonoBehaviour
{
// 游戏对象的迁移方向向量,向量模长为平移速度,向量方向为平移方向
Vector3 translation = new Vector3(1, 0, 0);
void Update()
{
// 每帧移动游戏对象,移动距离需要考虑帧长。
transform.Translate(Time.deltaTime * translation);
}
}
public class RotationScript : MonoBehaviour
{
// 游戏对象的旋转向量,向量模长决定旋转速度,游戏对象将以向量方向的直线为轴逆时针旋转
Vector3 translation = new Vector3(1, 0, 0);
void Update()
{
// 每帧移动游戏对象,旋转角度要考虑帧长。
transform.Translate(Time.deltaTime * translation);
}
}
请用三种方法以上方法,实现物体的抛物线运动
(如,修改Transform属性,使用向量Vector3的方法…)
通过 Translate 方法实现。
在二维坐标系中,物体的抛物线运动方程为:
x = v x t y = v y t + 1 2 a t 2 \begin{aligned} x&=v_xt\\ y&=v_yt+\frac{1}{2}at^2 \end{aligned} xy=vxt=vyt+21at2
那么每个时间间隔 Δ t \Delta t Δt 的运动向量为:
x 2 − x 1 = v x t 2 − v x t 1 = v x Δ t y 2 − y 1 = v y t 2 + 1 2 a t 2 2 − v y t 1 + 1 2 a t 1 2 = v y Δ t + 1 2 a ( Δ t 2 + 2 t 1 Δ t ) \begin{aligned} x_2-x_1&=v_xt_2-v_xt_1=v_x\Delta t\\ y_2-y_1&=v_yt_2+\frac{1}{2}at_2^2-v_yt_1+\frac{1}{2}at_1^2=v_y\Delta t+\frac{1}{2}a(\Delta t^2+2t_1\Delta t) \end{aligned} x2−x1y2−y1=vxt2−vxt1=vxΔt=vyt2+21at22−vyt1+21at12=vyΔt+21a(Δt2+2t1Δt)
那么我们只需要通过代码验证即可:
public class ProjectileMotionScript : MonoBehaviour
{
// 初始速度
public Vector3 v; // 初始速度,在 Unity 界面中可以设置为 (10, 0, 0)
public float g; // 重力加速度,在 Unity 界面中可以设置为 9.8
private float t = 0;
void Update()
{
transform.Translate(v * Time.deltaTime);
transform.Translate(0, -0.5f * g * (Time.deltaTime * Time.deltaTime + 2 * Time.deltaTime * t), 0);
t += Time.deltaTime;
}
}
写一个程序,实现一个完整的太阳系, 其他星球围绕太阳的转速必须不一样,且不在一个法平面上。
我们可以为每个行星添加 Trail Renderer
组件以追踪运动轨迹。
RotateAroundScript
如下所示,游戏对象将会围绕着自己的父对象旋转,我们可以在 Unity 面板中通过设置 direction
和 speed
来设置旋转法平面和公转角速率。public class RotateAroundScript : MonoBehaviour
{
public Vector3 direction;
public float speed;
void Update()
{
transform.RotateAround(transform.parent.position, direction * Time.deltaTime, speed * Time.deltaTime);
}
}
RotationScript
如下所示,允许通过 Unity 面板设置 direction
和 speed
来控制自转角和自转角速率。public class RotationScript : MonoBehaviour
{
public Vector3 direction;
public float speed;
// Update is called once per frame
void Update()
{
transform.Rotate(direction * Time.deltaTime, speed * Time.deltaTime);
}
}
程序需要满足的要求:
- play the game ( http://www.flash-game.net/game/2535/priests-and-devils.html )
- 列出游戏中提及的事物(Objects)
- 用表格列出玩家动作表(规则表),注意,动作越少越好
- 请将游戏中对象做成预制
- 在 GenGameObjects 中创建 长方形、正方形、球 及其色彩代表游戏中的对象。
- 使用 C# 集合类型 有效组织对象
- 整个游戏仅 主摄像机 和 一个 Empty 对象, 其他对象必须代码动态生成!!! 。 整个游戏不许出现 Find 游戏对象, SendMessage 这类突破程序结构的 通讯耦合 语句。 违背本条准则,不给分
- 请使用课件架构图编程,不接受非 MVC 结构程序
- 注意细节,例如:船未靠岸,牧师与魔鬼上下船运动中,均不能接受用户事件!
参见 https://github.com/huanghongxun/3D-Programming-And-Design/tree/master/homework2/PriestsAndDevils
使用向量与变换,实现并扩展 Tranform 提供的方法,如 Rotate、RotateAround 等
// Let t rotate with specific axis and angle.
void Rotate(Transform t, Vector3 axis, float angle)
{
var rot = Quaternion.AngleAxis(angle, axis);
t.position = rot * t.position;
t.rotation *= rot;
}
// Let t rotate around center with specific axis and angle.
void RotateAround(Transform t, Vector3 center, Vector3 axis, float angle)
{
var position = t.position;
var rot = Quaternion.AngleAxis(angle, axis);
var direction = position - center;
direction = rot * direction;
t.position = center + direction;
t.rotation *= rot;
}