(1)游戏对象运动的本质是什么?
运动的本质: 游戏对象空间位置(Position)、角度Rotation和形状Scale三个属性随时间而变化的过程。
(2)请用三种方法以上方法,实现物体的抛物线运动。(如,修改Transform属性,使用向量Vector3的方法…)
方法1:
实现向右和向下运动的两个脚本,并同时挂载到相同的GameObject上
向右运动:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RightMove : MonoBehaviour
{
public float speed = 1.0;
void Start()
{
}
void Update()
{
this.transform.position += speed * Vector3.right * Time.deltaTime;
}
}
向下运动:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DownMove : MonoBehaviour
{
public float speed = 1.0;
void Start()
{
}
void Update()
{
this.transform.position += speed * Vector3.down * Time.deltaTime;
}
}
方法2:
利用Vector3让x和y方向都做一定速度的运动,相当于将上面两个脚本合二为一
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour
{
public float speedx = 5.0;
public float speedy = 2.0;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
transform.position += new Vector3(speedx * Time.deltaTime,
-1 * speedy * Time.deltaTime, 0);
speedy += 1.0f;
}
}
方法3:
使用transform.Translate,将方法2中的变化向量Vector3传进Translate函数。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour
{
public float speedx = 5;
public float speedy = 2;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
transform.Translate(new Vector3(speedx * Time.deltaTime,
-1 * speedy * Time.deltaTime, 0));
speedy += 1.0f;
}
}
(3)写一个程序,实现一个完整的太阳系, 其他星球围绕太阳的转速必须不一样,且不在一个法平面上。
下载好太阳系各星体所需要的贴图并贴到对应的星体上,并且将它们的位置摆放好。
[图片]
编写运动脚本,根据太阳的位置Sun.position 使各行星做不同法平面和转速的围绕太阳的RotateAround运动,Sun.position 就设置为Vector.zero 以供方便,手动用Vector3去调整各行星转动的方向和速度。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class roundsun : MonoBehaviour
{
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
GameObject.Find("Sun").transform.Rotate(Vector3.up * Time.deltaTime * 5 );
GameObject.Find("Mercury").transform.RotateAround(Vector3.zero, new Vector3(0.1f, 1, 0), 60 * Time.deltaTime);
//设置公转的方向和速度 方向轴为(0, 1, 0) 速度为 60
GameObject.Find("Mercury").transform.Rotate(Vector3.up * Time.deltaTime * 10000 / 58);
//设置自转 自转速度为10000/58 58是水星的自传周期 倒数就是时间 下同
GameObject.Find("Venus").transform.RotateAround(Vector3.zero, new Vector3(0, 1, -0.1f), 55 * Time.deltaTime);
GameObject.Find("Venus").transform.Rotate(Vector3.up * Time.deltaTime * 10000 / 243);
GameObject.Find("Earth").transform.RotateAround(Vector3.zero, new Vector3(0, 1, 0), 50 * Time.deltaTime);
GameObject.Find("Earth").transform.Rotate(Vector3.up * Time.deltaTime * 10000);
GameObject.Find("Moon").transform.RotateAround(Vector3.zero, new Vector3(0, 1, 0), 5 * Time.deltaTime);
GameObject.Find("Moon").transform.Rotate(Vector3.up * Time.deltaTime * 10000/27);
GameObject.Find("Mars").transform.RotateAround(Vector3.zero, new Vector3(0.2f, 1, 0), 45 * Time.deltaTime);
GameObject.Find("Mars").transform.Rotate(Vector3.up * Time.deltaTime * 10000);
GameObject.Find("Jupiter").transform.RotateAround(Vector3.zero, new Vector3(-0.1f, 2, 0), 35 * Time.deltaTime);
GameObject.Find("Jupiter").transform.Rotate(Vector3.up * Time.deltaTime * 10000 / 0.3f);
GameObject.Find("Saturn").transform.RotateAround(Vector3.zero, new Vector3(0, 1, 0.2f), 20 * Time.deltaTime);
GameObject.Find("Saturn").transform.Rotate(Vector3.up * Time.deltaTime * 10000 / 0.4f);
GameObject.Find("Uranus").transform.RotateAround(Vector3.zero, new Vector3(0, 2, 0.1f), 15 * Time.deltaTime);
GameObject.Find("Uranus").transform.Rotate(Vector3.up * Time.deltaTime * 10000 / 0.6f);
GameObject.Find("Neptune").transform.RotateAround(Vector3.zero, new Vector3(-0.1f, 1, -0.1f), 10 * Time.deltaTime);
GameObject.Find("Neptune").transform.Rotate(Vector3.up * Time.deltaTime * 10000 / 0.7f);
}
}
使用GameObject.Find()方法就能在一个脚本中根据名称找到各个行星对象并定义它的运动,从而只用编写一个脚本且只需要挂载在Sun对象上即可。
[图片]
点击运行。
运行视频链接:
https://www.bilibili.com/video/BV1PP411K7p9/?vd_source=66cc21f92131571125d69a5f24344dcd
2.牧师与魔鬼编程实践
列出游戏中提及的事物(Objects)
对象:牧师、魔鬼、船、河、陆地
用表格列出玩家动作表(规则表)
动作
条件
角色
点击牧师或魔鬼
游戏未结束;角色与船同岸;角色在船上
角色上岸
点击牧师或魔鬼
游戏未结束;角色与船同岸;角色在岸上
角色上船
点击船
船上存在一个角色
船开到对岸
将游戏中对象做成预制
用一些图片贴上3d object 再调一下颜色就做出了这些预制体,在脚本运行时可以动态加载出来。
有MVC架构实现:分为Controller\Model、View 三部分,有7个脚本支持
关键代码逻辑实现解析:
1.Model部分实现
基本游戏对象Water直接用预制实例化即可
陆地模型LandModel
区分出发地和目的地,起点和终点两岸landSign标志;
;Vector3数组保存角色位置;用RoleModel数组存储角色信息
构造初始化LandModel
其他LandModel内部需要使用的成员函数(用于实现角色上船和上岸的动作)
船模型BoatModel的实现与LandModel类似且相关联,只是运用不同对象;
角色模型RoleModel类实现
包含角色动作和鼠标点击事件,并写好函数roleMove来联系二者
还需要一些set、get函数和移动函数来获取设置内部变量。
2.Controller类部分实现
写一个单例模式实现SSDirect类 – 控制全局,
FirstController控制主要场景,负责加载游戏场景的对象,定义角色移动的函数并检查游戏的状态,以及启动游戏;(截取部分)
Interface类来提供接口 ,规范FirstController ;
MoveController来控制角色移动,ClickController控制角色被点击时的动作;
3.用户界面类UserGUi
功能:游戏结束成功或失败时都实现文本框,显示提示信息。
定义sign标记胜负:1胜利 -1:失败 0:未知(运行中)
牧师与魔鬼演示视频地址:
https://www.bilibili.com/video/BV1NR4y1Q7Pc/
3. 思考题
使用向量与变换,实现并扩展 Tranform 提供的方法,如 Rotate、RotateAround 等
使用向量与变换实现RotateAround:
void RotateAround(Transform t,Vector3 center,Vector axis,float angle){
var rot=Quaternion.AngleAxis(angle,axis);
t.position=(center+(t.position-center)*rot);
t.rotation=t.rotation*rot;
}
使用向量与变换实现Rotate:
void Rotate(Transform t,Vector3 axis,float angle){
var rot=Quaternion.AngleAxis(angle,axis);
t.rotation*=rot;
}