2018年6月20日 星期三

week17 郭晉瑜期末作品展示

期末作品影片:

參考遊戲:漆彈大作戰2
遊戲內容:
        原先想使用網路連線進行多人對戰,但由於技術問題無法實現網路部分,最終呈現效果為:
1.使用右手射出紅色漆彈,漆彈碰到牆壁或者地板會將漆彈的內容物噴漆散發
2.使用左手射出藍色漆彈,漆彈碰到牆壁或者地板會將漆彈的內容物噴漆散發
3.使用右手touchpad可進行上下左右移動
4.利用3個camera計算出面積
5.紅藍雙方面積較大者勝利

程式概念:
1.計算面積
           利用三個相機,一個照射所有地圖畫面的俯視圖,一個照射紅色噴漆部分,一個照射藍色噴漆部分,分別計算出紅、藍色部分在主畫面中所佔比例

2.射擊子彈
           製作出一個子彈預置物以及子彈生成地點,利用vr手把上的trigger發射出去

3.噴漆效果
           將噴漆隱藏在子彈的子物件,將牆壁以及地板設置tag,若子彈碰到tag將會把噴漆效果開啟子彈消失,由於試驗過後發現子彈無法附著於牆壁上,因此我們將iskinematic關閉,而噴漆之間會產生的碰撞以及位置錯誤也分別被我們用程式碼一一解決。

主要程式:
1.射擊子彈
     void Update()
    {
     
        if (device.GetTouchDown(SteamVR_Controller.ButtonMask.Trigger))
        {
            Debug.Log("射擊");
            Shot();
        }
        else if (device.GetTouchUp(SteamVR_Controller.ButtonMask.Trigger))
        {
         
            Debug.Log("停止射擊");
        }
    }
    void Shot() {
        var bullet=(GameObject)Instantiate(BulletPrefab, BulletSpawn.position, BulletSpawn.rotation);
        bullet.GetComponent<Rigidbody>().velocity = bullet.transform.forward * 25;
    }

2.touchpad移動
if (controller.GetTouch(touchpad))
{
axis = device.GetAxis(Valve.VR.EVRButtonId.k_EButton_Axis0);

if (rig != null)
{
rig.position += (transform.right * axis.x*3 + transform.forward * axis.y*3) * Time.deltaTime;
rig.position = new Vector3(rig.position.x,0, rig.position.z);
}
}

3.子彈附著、固定旋轉角度、開啟噴漆效果、關閉碰撞、及子彈圖案
    void OnCollisionEnter(Collision col)
    {
        if (col.gameObject.tag=="Wall")
        {
            gameObject.GetComponent<Rigidbody>().isKinematic = true;
            quate.eulerAngles = new Vector3(0, 0, 0);
            gameObject.transform.rotation = quate;
            Ink.gameObject.SetActive(true);
            bulletcol.enabled = false;
            rend.enabled= false;
        }
    }

4.計算面積:
        {
          StartCoroutine("GetPercent");
        }
}

    public IEnumerator GetPercent()
    {
        //先擷取所有物件的畫面
        yield return new WaitForEndOfFrame();
        Texture2D texF = new Texture2D(Screen.width, Screen.height, TextureFormat.ARGB32, false);
        texF.ReadPixels(new Rect(0, 0, texF.width, texF.height), 0, 0, false);
        texF.Apply();

        //接著先Culling掉目標Camera,然後擷取畫面取得背景圖片
        int PrevMask = myCamera.cullingMask;
        myCamera.cullingMask = 0;
        yield return new WaitForEndOfFrame();

        Texture2D texB = new Texture2D(Screen.width, Screen.height, TextureFormat.ARGB32, false);
        texB.ReadPixels(new Rect(0, 0, texB.width, texB.height), 0, 0, false);
        texB.Apply();

        myCamera.cullingMask = PrevMask;
        myCamera.Render(); //強制Render一次避免產生閃爍

        //取得並判斷Pixel是否相同
        Color32[] colB = texB.GetPixels32();
        Color32[] colF = texF.GetPixels32();
        Destroy(texB);
        Destroy(texF);
        int count = 0;
        for (int i = 0; i < colF.Length; i++)
        {
            if (!Color32.Equals(colB[i], colF[i]))
                count++;
        }

        //計算百分比       
        float percent = (float)count * 100 / (float)(Screen.width * Screen.height);
        Debug.Log("COLOR_red :" + percent);
        text.text = "red: " + percent + "\n";
        this.GetComponent<testPercent1>().enabled =true;
        this.GetComponent<testPercent>().enabled = false;
    }
開發歷程:

參考文件:
計算面積: http://www.iverv.com/2014/04/unitypixels.html

沒有留言:

張貼留言