Unity 3D GAME Homework 3

(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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值