我的第一次Unity遊戲開發歷程

學習unity3d一個多月了,也做幾個簡單demo,但都是跟教程來做的。這次為了找一份實習,下定決心做一個遊戲的demo,雖然沒什麼內容,極易通關,優化也差,各種bug。

But when you being the lowest,whatever you do is up。

遊戲名:侏羅紀公園

遊戲型別:FPS

故事概述:你突然出現一處充滿霸王龍的神祕森林,你必須殺死它們中的頭目:巨型霸王龍才能生存下去。

製作歷程:

1.作圖構思,寫預覽圖

2.根據構圖設計UI,場景

3.收集資源,製作地形,場景

4.新增資源,編寫程式碼實現功能

5.第一階段完成:地形,天空盒,恐龍模型

6.新增程式碼到相應gameoject實現功能。

暫時不展示成果。

貼出核心程式碼並記錄所遇到的問題。

DianusorAI:

using UnityEngine;
using System.Collections;
public class DinosaurAI : Unit {
public GameObject enemy;
private GameObject myenemy;
private UnityEngine.AI.NavMeshAgent nam;
public float rotateSpeed;
// Use this for initialization
void Start () {
base.Start ();
myenemy= Instantiate (enemy, transform.position, transform.rotation)as GameObject;
}
// Update is called once per frame
void Update () {
nam=GetComponent<UnityEngine.AI.NavMeshAgent>();
RotateTo ();
nam.SetDestination(myenemy.transform.position);
}
void RotateTo(){
Vector3 targetdir = transform.position - myenemy.transform.position;
Vector3 newdir = Vector3.RotateTowards (transform.forward,targetdir,rotateSpeed*Time.deltaTime,0.0f);
transform.rotation = Quaternion.LookRotation (newdir);
}
}

shell:

using UnityEngine;
using System.Collections;
public class shell2 : MonoBehaviour {
public int damage;
public float explosionRadius;
public GameObject explosionEffect;
public float explosiontime;
void OnCollisionEnter(){
GameObject g= Instantiate (explosionEffect, transform.position, transform.rotation)as GameObject;
Destroy (gameObject);
Destroy (g, explosiontime);
Collider[] cols = Physics.OverlapSphere (transform.position,explosionRadius);
if (cols.Length > 0) {
for(int i=0;i<cols.Length;i  ){
Unit u=cols[i].GetComponent<Unit>();
if(u!=null){
u.ApplyDamage(damage);
}
}
}
}
}

shootboom:

using UnityEngine;
using System.Collections;
public class shootboom : MonoBehaviour {
public Transform shootPoint;
public GameObject shell;
public float shootSpeed;
private AudioSource audioSource;
// Use this for initialization
void Start () {
audioSource = GetComponent<AudioSource> ();
}
// Update is called once per frame
void Update () {
if (Input.GetMouseButtonDown(0)) {
Shoot();
}
}
public void Shoot(){
GameObject newsheel =Instantiate (shell, shootPoint.position, shootPoint.rotation)as GameObject;
Rigidbody r = newsheel.GetComponent<Rigidbody> ();
r.velocity = shootPoint.forward * shootSpeed;
audioSource.Play ();
}
}

Unit:

using UnityEngine;
using System.Collections;
public class Unit : MonoBehaviour {
public int health=1000;
private int curhealth;
public GameObject deadEffect;
// Use this for initialization
public  void Start () {
this.curhealth = this.health;
}
public int getcurhea(){
return this.curhealth;
}
// Update is called once per frame
void Update () {
}
public void ApplyDamage(int damage){
if (curhealth > damage) {
curhealth -= damage;
} else {
Destruct();
}
}
public void Destruct(){
if(deadEffect!=null){
Instantiate(deadEffect,transform.position,transform.rotation);
}
Destroy (gameObject);
}
}

welcomeCG:

using UnityEngine;
using System.Collections;
public class Weclomecg : MonoBehaviour {
public GameObject world;
public GameObject canvas;
// Use this for initialization
void Start () {
StartCoroutine(WaitAndPrint(2.0F));  
Destroy (canvas);
}
// Update is called once per frame
void Update () {
}
IEnumerator WaitAndPrint(float waitTime)  
{  
yield return new WaitForSeconds(waitTime);  
canvas.SetActive (false);
world.SetActive (true);
}   
}

收穫:

1.延遲執行可用Invoke 延遲等待執行也可用yield return

void Start () {
StartCoroutine(WaitAndPrint(2.0F));  
Destroy (canvas);
}

IEnumerator WaitAndPrint(float waitTime)  
{  
yield return new WaitForSeconds(waitTime);  
canvas.SetActive (false);
world.SetActive (true);

}   

2.在製作遊戲過程中,很多單位都會擁有的值可存放在一個Unit基類中,並去繼承它。

3.實現射擊通常是用射線檢測。我這裡用產生子彈,子彈碰撞到物體會檢測一定範圍內的所有碰撞體,用陣列去獲取它們,然後逐個判斷是否為敵人,是則造成傷害值。

該方法特別適用於炸彈爆炸。   詳情見shell中程式碼。

4.給某個物體加一個速度。例子:

GameObject newsheel =Instantiate (shell, shootPoint.position, shootPoint.rotation)as GameObject;
Rigidbody r = newsheel.GetComponent<Rigidbody> ();

r.velocity = shootPoint.forward * shootSpeed;

5.實現某個物體隨機走動或者尋敵。

不尋敵的話可以設定該物體的transform不斷改變,使用random函式。

否則首先要在Navigation中烘焙。然後給該物體新增NavMeshAgent。掛上指令碼即可。不尋敵的話使用Random即可實現。我在此遊戲中創造一個隨機物體後setdestinatin

指令碼中核心程式碼(實現尋敵)

void Update () {
nam=GetComponent<UnityEngine.AI.NavMeshAgent>();
RotateTo ();
nam.SetDestination(myenemy.transform.position);
}
void RotateTo(){
Vector3 targetdir = transform.position – myenemy.transform.position;
Vector3 newdir = Vector3.RotateTowards (transform.forward,targetdir,rotateSpeed*Time.deltaTime,0.0f);
transform.rotation = Quaternion.LookRotation (newdir);
}

6.讓模型播放動畫,需在匯入unity前給模型配備動畫,在用unity中新增AnimationController,並設定狀態機。附加到模型上,模型即可播放動畫,

7.新增fog效果後,會影響某些特效的渲染。

效果圖:

遊戲試玩:

百度雲盤:http://pan.baidu.com/s/1o8LiLZG