3D游戏编程与设计作业三

本文介绍了在Unity中实现物体抛物线运动的三种方法,并展示了创建一个完整太阳系的代码,包括行星围绕太阳的公转和自转。此外,还讨论了如何使用C#集合动态生成游戏对象以及遵循MVC架构设计游戏。同时,提供了针对"Priests and Devils"游戏的规则和对象预设。
摘要由CSDN通过智能技术生成


1.简答并用程序验证

(1) 游戏对象运动的本质是什么?
游戏对象运动是游戏对象按照预设好的方式向某个方向、或者围绕某个物体进行运动,其本质是相对于原点坐标的位置的变化,体现在unity中就是transform中position的各个值的改变。

(2)请用三种方法以上方法,实现物体的抛物线运动。
a.创建一个新的vector3属性

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

public class move1 : MonoBehaviour
{
    int speed;
    // Start is called before the first frame update
    void Start()
    {
        speed = 1;
    }

    // Update is called once per frame
    void Update()
    {
        float x = this.transform.position.x;
        float newX = x + speed*Time.deltaTime;

        this.transform.position = new Vector3(newX, newX*(newX-4));
    }
}

效果如下:
在这里插入图片描述
b.直接修改position
由于抛体运动在水平方向上做匀速运动,在竖直方向上做匀加速运动,因此可以将其分解为这两个方向上的运动,然后再进行合成。

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

public class move2 : MonoBehaviour
{
    int speedx;
    int speedy;
    // Start is called before the first frame update
    void Start()
    {
        speedx = 1;
        speedy = -2;
    }

    // Update is called once per frame
    void Update()
    {
        this.transform.position += Vector3.right*speedx;
        this.transform.position += Vector3.up*speedy;
        speedy++;
    }
}

这种方式理论上可以实现抛体运动,但是由于Update函数的执行频率太高了,因此效果不明显,看到的就是物体一下就飞到很远的地方去了,因此就不放图了。

c.使用translate方法

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

public class move3 : MonoBehaviour
{
    int speedx;
    int speedy;
    // Start is called before the first frame update
    void Start()
    {
        speedx = 1;
        speedy = -2;
    }

    // Update is called once per frame
    void Update()
    {
        Vector3 move = new Vector3(Time.deltaTime*speedx, Time.deltaTime*speedy, 0);
        speedy++;
        transform.Translate(move);
    }
}

其实和上一种方法十分类似,也是会因为update执行过快而无法看到效果。
代码传送门:GitHub

(3)写一个程序,实现一个完整的太阳系, 其他星球围绕太阳的转速必须不一样,且不在一个法平面上。
公转代码如下:

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

public class revolution : MonoBehaviour
{
    public Transform center;
    public float speed;
    public float x, y, z;
    // Start is called before the first frame update
    void Start()
    {
        x = Random.Range(20, 100);
        y = Random.Range(20, 100);
        z = Random.Range(20, 100);
        speed = Random.Range(8, 25);
    }

    // Update is called once per frame
    void Update()
    {
        this.transform.RotateAround(center.position, new Vector3(x,y,0), speed*Time.deltaTime);
    }
}

可见使用了random函数来随机赋予法平面的角度(经过试验发现z=0效果较好)和公转速度,编写好脚本之后只需将其依次拉入已经创建好的“行星”,然后将center设为sun即可。
公转可以使用trail render特效来描绘出轨迹,利于观察,具体可参考博客介绍
效果:
在这里插入图片描述

自转代码:

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

public class rotation : MonoBehaviour
{
    public int speed;
    // Start is called before the first frame update
    void Start()
    {
        speed = Random.Range(4, 10);
    }

    // Update is called once per frame
    void Update()
    {
        this.transform.RotateAround(this.transform.position, Vector3.up, speed*Time.deltaTime);
    }
}

然后将自转代码拖到各个行星上即可。

但是此时发现背景太空了,因此还要给“模拟太阳系”添加一个背景图。
创建一个新的material,在shader属性中选Skybox/Panoramic,然后把自己想要的背景图片加上去:
在这里插入图片描述
然后在camera的add component中rendering添加skybox,在customer skybox中选择刚刚创建的background即可。
在这里插入图片描述
最终效果:
在这里插入图片描述
源代码传送门:Github

2. 编程实践——Priests and Devils

(1)列出游戏中提及的事物(Objects)
牧师、魔鬼、船、河岸、河

(2)用表格列出玩家动作表(规则表),注意,动作越少越好

角色动作
牧师/魔鬼点击岸上的牧师/魔鬼,如果船当前在该角色的岸边且船上人数少于2则上船
牧师/魔鬼点击船上的牧师/魔鬼,则牧师/魔鬼从船上转移到岸上
行驶到另一侧的河岸

(3)将游戏对象做成预设
 的
(4)在场景控制器 LoadResources 方法中加载并初始化 长方形、正方形、球 及其色彩代表游戏中的对象。

	public void LoadResources(){
		Debug.Log("DD");
		GameObject water = Instantiate(Resources.Load("Prefabs/Water", typeof(GameObject)), new Vector3(0,-1,0), Quaternion.identity) as GameObject;
		water.name = "water";
		start_land = new LandModel("start");
		end_land = new LandModel("end");
		boat = new BoatModel();
		role = new RoleModel[6];

		for (int i = 0; i < 3; i++){
			RoleModel r = new RoleModel("priest");
			r.SetName("priest" + i);
			r.SetPosition(start_land.GetEmptyPosition());
			r.GoLand(start_land);
			start_land.AddRole(r);
			role[i] = r;
		}

		for (int i = 3; i < 6; i++){
			RoleModel r = new RoleModel("devil");
			r.SetName("devil" + i);
			r.SetPosition(start_land.GetEmptyPosition());
			r.GoLand(start_land);
			start_land.AddRole(r);
			role[i] = r;
		}
	}

(5)使用 C# 集合类型 有效组织对象。整个游戏仅主摄像机和一个 Empty 对象, 其他对象必须代码动态生成!

(6)请使用课件架构图编程,不接受非 MVC 结构程序
在这里插入图片描述
M(Model):ModelController,其中实现了boat、land、role的各个函数。
V(View):UserGUI中实现了一个简易GUI。
C(Controller):SSDirector是创建导演,一个游戏只有一个;Controller是管理各个model之间的行为的类;
除此之外,Click是相应鼠标点击的类,InterfaceController是为了降低各个类的耦合而制作的接口,用于各个model之间的调用。

运行时只需要将controller拖入创建的空对象中即可。

源代码传送门:GitHub

最终效果:
获胜:
在这里插入图片描述
失败:在这里插入图片描述

参考
https://blog.csdn.net/TempterCyn/article/details/101110379
由于我自己写的游戏最后还是有许多bug没有解决,最终是跟着这个师兄的思路完成的。
https://www.jianshu.com/p/07028b3da573
除此之外还有很多其他博客也给我提供了帮助,地址没有一一保存了。

3.思考题

使用向量与变换,实现并扩展 Tranform 提供的方法,如 Rotate、RotateAround 等。
Rotate:

void Rotate(Transform t,Vector3 axis,float angle){ 
    var rot=Quaternion.AngleAxis(angle,axis);
    t.rotation*=rot;
}

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;
}(这里会报错?说position不能与rotation运算?)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值