實驗過程中常會需要有些目標點給受試者進行Target,如何隨機生成不同的距離與角度是很重要的,故我們今天先在 2D 平面上來實現,透過簡單的數學關係來達成我們想要的結果。三角函數是個很強大的,所以今天也會小試身手來創造在User 前面生成兩個隨機物件,且具有隨機距離與角度關係。
首先我建立一個我想要生成的物件。我使用 Asset Store 的一個Open Package,名為 Meshtinit Free Chicken Mega Toon Series 裡面的公雞。因為我覺得很可愛。我們從 Window > Package Manager 去引入該 Package。
在左下角我們可以看到 Assets > Meshtinit Free Chicken Mega Toon Series > Prefabs, Prefabs 就會有我今天會需要使用到的公雞模型。 直接拉到 Scene 使用即可。
我們把該Prefab 拉到Scene 中。 接著就會看到 Hierarchy 自動生成該物件。 Reset 該物件上的 Transform 好讓其位置我們可以比較好控制。 Animator 目前在這邊不需要可以取消勾選,那是物件的動作行為,尚不需要。
接下來調整 Main Camera 的可視角度,更改 Position and Rotation。
首先新增一個空白物件 GenerateManagement ,並新增腳本元素 GenerateObj.cs。
開始撰寫文本上的內容。 因為這次包含三角函數的關係,但僅為 2D 平面的三角關係,所以並不會到很困難,但我這邊還是會細說每個步驟與宣告變數的意義。
首先宣告該當前公雞的位置,也就是目前 User 的位置。
public Transform ChickenObj;
Vector3 currentPosition;
float[] angle = {0f, 30f, 60f, 90f, 120f, 150f, 180f};
float[] distance = {0.5f, 1f, 2, 2.5f};
List<GameObject> generateObj = new List<GameObject>();
public GameObject generateObjModel;
private int ObjId = 0;
先想一下如果要在前方某一個角度與某一個距離生成物件,可以想一下該物件的原點向外的距離也就是 distance 一個半徑,那有角度、距離( distance)就可以透過 Cosine、Sine 來求出 deltaX, deltaZ。然後再從原點(User 位置) 向 x 軸與 z 軸延伸就會是新的座標點。 請注意到 Unity 是左手坐標系。現在觀察的是 2D 。前方為Z軸,側向為 X軸。
所以先定義該User(Chicken)原來的位置。
currentPosition = ChickenObj.position;
Random.Range(initial, end);
UnityEngine.Random.Range(initial, end);
void randomObj()
{
int getAngle = Random.Range(0, angle.Length);
int getDistance = Random.Range(0, distance.Length);
float randomAngle = angle[getAngle];
float randomDistance = angle[getDistance];
Debug.Log("Random Angle: " + randomAngle + ", Distance: " + randomDistance);
}
Vector2 offset = new Vector2(Mathf.Sin(randomAngle * Mathf.PI/180.0f), Mathf.Cos(randomAngle * Mathf.PI/180.0f)) * randomDistance;
Vector3 newPosition = new Vector3(currentPosition.x + offset.y, 0f,currentPosition.z + offset.x);
概念如下:
float newX= Origin + distance * Mathf.Cos( angle * Mathf.PI / 180f);
float newZ = Origin + distance * Mathf.Sin( angle * Mathf.PI / 180f);
reateGenerateList[i] = (GameObject)GameObject.Instantiate(generateObjModel, newPosition, Quaternion.identity);
void randomObj()
{
for(int i = 0; i < 2; i++)
{
int getAngle = Random.Range(0, angle.Length);
int getDistance = Random.Range(0, distance.Length);
float randomAngle = angle[getAngle];
float randomDistance = distance[getDistance];
Debug.Log("Random Angle: " + randomAngle + ", Dista nce: " + randomDistance);
Vector2 offset = new Vector2(Mathf.Sin(randomAngle * Mathf.PI/180.0f), Mathf.Cos(randomAngle * Mathf.PI/180.0f)) * randomDistance;
Vector3 newPosition = new Vector3(currentPosition.x + offset.y, currentPosition.y ,currentPosition.z + offset.x);
createGenerateList[i] = (GameObject)GameObject.Instantiate(generateObjModel, newPosition, Quaternion.identity);
}
}
void resetObj()
{
for(int i = 0 ; i < 2; i++)
{
Destroy(createGenerateList[i]);
}
}
void Update()
{
if(Input.GetKeyDown("l"))
{
randomObj();
}else if(Input.GetKeyDown("p"))
{
resetObj();
}
}
回到 Unity 後,將其我們要的物件放置進腳本中。注意到要生成的物件放置成Prefab 中。
執行開始可以看到每次生成兩個以User 為基準向外看去的兩個隨機位置上的物件。