3D 游戏编程与设计 - 空间与运动
程序员文章站
2022-07-13 09:10:29
...
简答并用程序验证
1
游戏对象运动的本质是什么?
游戏对象运动的本质是变换游戏对象自身的坐标。
在游戏开发中,我们可以通过矩阵变换的方式实现游戏对象的变换,比如:
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);
}
}
2
请用三种方法以上方法,实现物体的抛物线运动
(如,修改Transform属性,使用向量Vector3的方法…)
方法一
通过 Translate 方法实现。
在二维坐标系中,物体的抛物线运动方程为:
那么每个时间间隔 的运动向量为:
那么我们只需要通过代码验证即可:
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;
}
}
3
写一个程序,实现一个完整的太阳系, 其他星球围绕太阳的转速必须不一样,且不在一个法平面上。
我们可以为每个行星添加 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;
}