unity爲我們提供了許多人機交互的方式,包括鼠標、鍵盤、手柄等等,這些具體的設置我們可以通過Edit->ProjectSettings->Input中查看
這裏我講一下鼠標左鍵的點擊,我們點開Fire1
這裏Alt Positive Button顯示的是mouse 0,表示鼠標左鍵點擊就會有該響應,而且是積極相應,這些可以自己修改
下面我做一個小遊戲:
- 用 Plane 或其他物體做地面, tag 爲“Finish”
- 點擊地面後,出現一個圓形攻擊標記,兩秒後自動消失。注意:該攻擊標記不能擋住點擊。
首先我們做一個Terrain,上次我們說過美化的方法,所以我做出了這樣子的
進入Inspector,將Tag改爲Finish
然後我們製作一個圓形攻擊標誌,在Assert中創建文件夾Resources->Prefabs,然後創建一個圓柱,將其高度設爲0.001(設爲0會變成一個黑色圓),拖入Prefabs,然後在當前目錄創建Material,給它添加喜歡的顏色,然後再拖入我們的預設,圓形標誌就做好了
現在我們考慮如何編寫腳本,這裏我採用了工廠單例模式。意思很簡單,就是有一個腳本在鼠標點擊後告訴一個工廠“我需要一個圓形標誌,放在哪裏”,工廠接到小心以後就先看看自己庫存還有沒有,有就直接拿給它,否則就創建一個拿給它。因爲unity創建一個遊戲對象、銷燬一個遊戲對象會佔很大的資源,所以有什麼辦法可以少生產,少銷燬甚至不銷燬呢?很簡單,把用完的拿回來。那這些庫存放哪呢,也在遊戲場景中,只是並不在攝像機的視角範圍內。
這樣我們思路就很清晰了,一個人機交互,並給工廠下達指令的腳本、一個生產、回收的工廠
Factory
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Factory : MonoBehaviour {
private static Factory instance;
public static List<GameObject> free = new List<GameObject>();
public static List<GameObject> used = new List<GameObject>();
public static Factory GetInstance()
{
if (instance == null)
{
instance = new Factory();
}
return instance;
}
public void placeAttackMark(Vector3 position)
{
GameObject t;
if (free.Count == 0) // 空餘組中沒有多餘的,此時需要創建
{
t = Instantiate<GameObject>(Resources.Load<GameObject>("Prefabs/Cylinder"), Vector3.zero, Quaternion.identity);
} else
{
t = free[0];
free.Remove(t);
}
used.Add(t);
t.transform.position = position;
t.AddComponent<disappear>();
}
}
爲什麼要用static呢,原因很簡單,單例模式,整個遊戲只需要一個工廠。用了兩個List,一個用於表示庫存,一個用於記錄用過的,以便可以回收。placeAttackMark是作爲交互腳本調用的,首先判斷是否有庫存,有的話把這個調到指定位置,並移到已用記錄中,否則直接創造一個。由於要求兩秒以後自動消失,我們爲每個拿出去的產品添加一個計時器(組件)disappear。
disappear
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class action : Factory { }
public class disappear : action {
private float time = 2;
void Update()
{
time -= Time.deltaTime;
if (time <= 0)
{
transform.position = Vector3.zero;
used.Remove(gameObject);
free.Add(gameObject);
Destroy(this);
}
}
}
當時間到了以後,把這個標記移到我們看不見的地方,再從已用list中刪除,同時把它重新加入庫存中,完成回收,值得一提的是,要刪掉這個組件,不然它會每一幀都運行。
Shot
首先我說一下是如何判斷鼠標是否點擊到了物體,簡單來說,就是以攝像機爲原點,朝鼠標點擊的位置發出一條射線,如果撞擊到了物體就是點擊到了這個物體的意思。所以Shot中我們要添加一個攝像機成員,還要一個工廠
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Shot : MonoBehaviour {
private Factory MyFactory;
public GameObject Cam;
// Use this for initialization
void Start ()
{
MyFactory = Factory.GetInstance();
}
// Update is called once per frame
void Update () {
if (Input.GetButtonDown("Fire1"))
{
Vector3 mp = Input.mousePosition;
Camera ca = Cam.GetComponent<Camera>();
Ray ray = ca.ScreenPointToRay(mp);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.gameObject.tag.Contains("Finish"))
{
print(mp);
MyFactory.placeAttackMark(hit.point);
}
}
}
}
}
Raycasr(ray, out hit){}的意思就是如果這條射線發生了碰撞就執行以下事件:告訴工廠我要在點擊的位置生成一個圓形標誌
這樣我們就完成了這樣一個有(無)趣(聊)的小遊戲