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

【3D游戏编程】3. 空间与运动

程序员文章站 2022-07-13 09:12:47
...

一. 简答并用程序验证

1. 游戏对象运动的本质是什么?

游戏对象运动的本质是游戏对象的属性(主要是transform的position,rotation和scale)随每一帧的而发生的改变。

2. 请用三种方法以上方法,实现物体的抛物线运动。(如,修改Transform属性,使用向量Vector3的方法…)

  • 直接给物体初速度,利用重力实现抛物线运动(需要勾选Rigidbody中的use gravity)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class parabola : MonoBehaviour {

	// Use this for initialization
	void Start () {//赋予初速度
		this.GetComponent<Rigidbody>().velocity = new Vector3(5, 10, 0);
	}
	
	// Update is called once per frame
	void Update () {
		
	}
}

  • 直接修改transform属性
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class parabola2 : MonoBehaviour {

	public float v_x;
	public float v_y;
	public float g;
	public float t;
	// Use this for initialization
	void Start () {
		v_x = 5.0f;
		v_y = 10.0f;
		g = 10.0f;

	}
	
	// Update is called once per frame
	void Update () {
		t = Time.deltaTime;
		this.transform.position += new Vector3 (v_x * t, v_y * t - 0.5f * g * t * t, 0.0f);
		v_y = v_y - g * t;//不可少,否则永远不会下来
	}
}

  • 使用Vector3变量
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class parabola3 : MonoBehaviour {

	public float v_x;
	public float v_y;
	public float g;
	public float t;
	// Use this for initialization
	void Start () {
		v_x = 5.0f;
		v_y = 10.0f;
		g = 10.0f;

	}

	// Update is called once per frame
	void Update () {
		t = Time.deltaTime;
		Vector3 displace = new Vector3 (v_x * t, v_y * t - 0.5f * g * t * t, 0.0f);
		v_y = v_y - g * t;//不可少,否则永远不会下来
		this.transform.position = Vector3.Lerp(transform.position,transform.position + displace,1);

	}
}

实现结果

【3D游戏编程】3. 空间与运动

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

初始图象:

八大行星中,木星最大,是其他七大行星总质量的2.5倍,而太阳质量是木星的1000倍。以质量之比作为体积之比然后为了方便观察对体积进行调节后的设定如下:
【3D游戏编程】3. 空间与运动

脚本:

整个太阳系都安装同一个脚本(如下),脚本按照行星的角色进行自转和公转角速度的选择

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class planets : MonoBehaviour
//所有行星与太阳共用一个文件(但太阳不是行星)
{
	public float speed,s2;
	public GameObject center;//旋转中心
	public int offset_x;//法平面的偏移角x
	public int offset_z;//法平面的偏移角z
	public int offset_y;//法平面的偏移角y
	// Start is called before the first frame update
	void Start()
	{
		offset_x = Random.Range(0, 20);
		offset_z = Random.Range(0, 20);
		offset_y = Random.Range(0, 10);
		speed = Random.Range (10, 90);
		s2 = Random.Range (10, 20);
		center = GameObject.Find("Sun");
	}

	// Update is called once per frame
	void Update()
	{
		if (this.name == "Sun") {//太阳只有自转
			this.transform.Rotate (new Vector3 (-offset_y, offset_x, 0) * s2 * Time.deltaTime);
		} else {
			//公转
			//垂直于角速度(x,y,z)的平面(可以)是(z,0,x)
			Vector3 axis = new Vector3 (-offset_z, 0, offset_x);
			this.transform.RotateAround (center.transform.position, axis, speed * Time.deltaTime);
			//行星自转,轴随意定的
			this.transform.Rotate (new Vector3 (-offset_y, offset_x, 0) * s2 * Time.deltaTime);
		}
	}
}
大致效果:

公转效果不太符合事实,还需调整:
【3D游戏编程】3. 空间与运动
【3D游戏编程】3. 空间与运动

动图与视频:

【3D游戏编程】3. 空间与运动
演示视频

二. 编程实践

阅读以下游戏脚本
Priests and Devils
Priests and Devils is a puzzle game in which you will help the Priests and Devils to cross the river within the time limit. There are 3 priests and 3 devils at one side of the river. They all want to get to the other side of this river, but there is only one boat and this boat can only carry two persons each time. And there must be one person steering the boat from one side to the other side. In the flash game, you can click on them to move them and click the go button to move the boat to the other direction. If the priests are out numbered by the devils on either side of the river, they get killed and the game is over. You can try it in many > ways. Keep all priests alive! Good luck

程序要求

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

priest(巫师),devil(恶魔),boat(船),river(河),bank(河岸)

用表格列出玩家动作表(规则表),注意,动作越少越好
玩家动作 结果
点击人物 船未满(2人)时人物上船。
点击人物 船满人时人物下船。
点击小船 船上有人时小船驶向河的另一岸。到达时假如某一河岸恶魔数量多于牧师,游戏结束
将游戏对象做成预置

【3D游戏编程】3. 空间与运动

使用MVC架构:

MVC结构即Model,View,Controller分离。
场景中的所有GameObject就是Model,它们受到Controller的控制,比如说牧师和魔鬼受到MyCharacterController类的控制,船受到BoatController类的控制,河岸受到BankController类的控制。
View就是UserGUI和ClickGUI,它们展示游戏结果,并提供用户交互的渠道(点击物体和按钮)。
Controller:除了刚才说的MyCharacterController、BoatController、CoastController以外,还有更高一层的Controller:FirstController(场景控制器),FirstController控制着这个场景中的所有对象,包括其加载、通信、用户输入。
最高层的Controller是Director类,一个游戏中只能有一个实例,它控制着场景的创建、切换、销毁、游戏暂停、游戏退出等等最高层次的功能。
【3D游戏编程】3. 空间与运动

项目结果:

演示视频
项目地址

参考资料:

https://www.jianshu.com/p/07028b3da573