3D 游戏编程与设计 - 空间与运动

简答并用程序验证

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 方法实现。
在二维坐标系中,物体的抛物线运动方程为:
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} x2x1y2y1=vxt2vxt1=vxΔt=vyt2+21at22vyt1+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;
    }
}

3D 游戏编程与设计 - 空间与运动_第1张图片

3

写一个程序,实现一个完整的太阳系, 其他星球围绕太阳的转速必须不一样,且不在一个法平面上。

我们可以为每个行星添加 Trail Renderer 组件以追踪运动轨迹。

  1. 首先我们为每个行星添加公转组件 RotateAroundScript 如下所示,游戏对象将会围绕着自己的父对象旋转,我们可以在 Unity 面板中通过设置 directionspeed 来设置旋转法平面和公转角速率。
public class RotateAroundScript : MonoBehaviour
{
    public Vector3 direction;
    public float speed;

    void Update()
    {
        transform.RotateAround(transform.parent.position, direction * Time.deltaTime, speed * Time.deltaTime);
    }
}
  1. 然后我们为每个行星添加自转组件 RotationScript 如下所示,允许通过 Unity 面板设置 directionspeed 来控制自转角和自转角速率。
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);
    }
}

3D 游戏编程与设计 - 空间与运动_第2张图片

编程实践

程序需要满足的要求:

  1. play the game ( http://www.flash-game.net/game/2535/priests-and-devils.html )
  2. 列出游戏中提及的事物(Objects)
  3. 用表格列出玩家动作表(规则表),注意,动作越少越好
  4. 请将游戏中对象做成预制
  5. 在 GenGameObjects 中创建 长方形、正方形、球 及其色彩代表游戏中的对象。
  6. 使用 C# 集合类型 有效组织对象
  7. 整个游戏仅 主摄像机 和 一个 Empty 对象, 其他对象必须代码动态生成!!! 。 整个游戏不许出现 Find 游戏对象, SendMessage 这类突破程序结构的 通讯耦合 语句。 违背本条准则,不给分
  8. 请使用课件架构图编程,不接受非 MVC 结构程序
  9. 注意细节,例如:船未靠岸,牧师与魔鬼上下船运动中,均不能接受用户事件!

参见 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;
}

你可能感兴趣的:(3D,游戏编程与设计)