欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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 方法实现。
在二维坐标系中,物体的抛物线运动方程为:
x=vxty=vyt+12at2 \begin{aligned} x&=v_xt\\ y&=v_yt+\frac{1}{2}at^2 \end{aligned}
那么每个时间间隔 Δt\Delta t 的运动向量为:
x2x1=vxt2vxt1=vxΔty2y1=vyt2+12at22vyt1+12at12=vyΔt+12a(Δt2+2t1Δ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}
那么我们只需要通过代码验证即可:

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 游戏编程与设计 - 空间与运动

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 游戏编程与设计 - 空间与运动

编程实践

程序需要满足的要求:

  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;
}
相关标签: Unity