【Unity3D】空間與運動

1. 簡答並用程序驗證

(1) 遊戲對象運動的本質是什麼?

遊戲對象運動的本質是遊戲對象的position、rotation、scale等屬性隨着幀的改變而發生改變。

(2) 請用三種方法以上方法,實現物體的拋物線運動。(如,修改Transform屬性,使用向量Vector3的方法…)

  1. 修改Transform屬性
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ParabolicMotion : MonoBehaviour
{
    public float v0;    // 水平方向初速度
    public float v1;    // 垂直方向初速度
    public float g; // 重力
    public float t; // 時間

    // Start is called before the first frame update
    void Start()
    {
        v0 = 8.0f;
        v1 = -2.5f;
        g = 9.8f;
    }

    // Update is called once per frame
    void Update()
    {
        t = Time.deltaTime;
        if (this.transform.position[1] > -1.5)
        {
            this.transform.position += new Vector3(v0 * t, v1 * t - 0.5f * g * t * t, 0.0f);
        }
    }
}

  1. 使用Vector3變量的Lerp函數(插值)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ParabolicMotion3 : MonoBehaviour
{
    public float v0;    // 水平方向初速度
    public float v1;    // 垂直方向初速度
    public float g; // 重力
    public float t; // 時間

    // Start is called before the first frame update
    void Start()
    {
        v0 = 8.0f;
        v1 = -2.5f;
        g = 9.8f;
    }

    // Update is called once per frame
    void Update()
    {
        t = Time.deltaTime;
        if (this.transform.position[1] > -1.5)
        {
            Vector3 vec = new Vector3(v0 * t, v1 * t - 0.5f * g * t * t, 0.0f);
            // lerp:插值
            this.transform.position = Vector3.Lerp(transform.position, transform.position + vec, 1);
        }
    }
}

  1. 利用Rigidbody中的use gravity,直接用重力實現拋物線運動。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ParabolicMotion3 : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        // 利用vector3賦初速度
        this.GetComponent<Rigidbody>().velocity = new Vector3(8.0, -2.5, 0);
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

(3) 寫一個程序,實現一個完整的太陽系, 其他星球圍繞太陽的轉速必須不一樣,且不在一個法平面上。

創建球體遊戲對象:
在這裏插入圖片描述

爲星球貼圖,並大致調整大小和位置關係。在這裏插入圖片描述
參照行星自轉與公轉的速度與週期,設置大致的參數,將以下腳本掛載到遊戲對象Sun上面,運行即可。

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

public class Move : MonoBehaviour
{
    // Start is called before the first frame update
    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), 48 * Time.deltaTime);
        // 水星自轉
        GameObject.Find("Mercury").transform.Rotate(Vector3.up * Time.deltaTime * 10000 / 58);

        GameObject.Find("Venus").transform.RotateAround(Vector3.zero, new Vector3(0, 1, -0.1f), 35 * 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), 30 * 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), 24 * 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), 13 * 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), 9 * 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), 7 * 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), 5 * Time.deltaTime);
        GameObject.Find("Neptune").transform.Rotate(Vector3.up * Time.deltaTime * 10000 / 0.7f);
    }
}

2、編程實踐

  • 閱讀以下游戲腳本

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
  • 列出遊戲中提及的事物(Objects)
    • priest, devil, river, boat
  • 用表格列出玩家動作表(規則表),注意,動作越少越好
動作 對象 描述
上下船 牧師/惡魔 從岸上到船上或從船上到岸上
等待 牧師/惡魔 在岸上等待
行駛 牧師/惡魔 讓船從一岸行駛到對岸
殺人 惡魔 當惡魔人數多於牧師時,惡魔殺死牧師,遊戲結束
  • 請將遊戲中對象做成預製

    • 如圖,將創建的對象做成預製,放入Prefabs文件夾。
      在這裏插入圖片描述
  • 在 GenGameObjects 中創建 長方形、正方形、球 及其色彩代表遊戲中的對象。

    • 以黑色球體代表devils,白色正方體代表priests。
  • 使用 C# 集合類型 有效組織對象

  • 整個遊戲僅 主攝像機 和 一個 Empty 對象, 其他對象必須代碼動態生成!!! 整個遊戲不許出現 Find 遊戲對象, SendMessage 這類突破程序結構的通訊耦合語句。 違背本條準則,不給分

  • 請使用課件架構圖編程,不接受非 MVC結構程序

    • Model:場景中的所有GameObject,它們受到Controller的控制。
    • View:UserGUI和ClickGUI,提供用戶交互的界面和動作。
    • Controller:MyCharacterController、BoatController、CoastController、以及更高一層的FirstController(控制着這個場景中的所有對象)。最高層的Controller是Director類。
  • 注意細節,例如:船未靠岸,牧師與魔鬼上下船運動中,均不能接受用戶事件!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章