2016年4月29日 星期五

Shader 製作動態環繞圓輪

首先  感謝王巍網站詳細講解:
https://onevcat.com/2013/07/shader-tutorial-1/
----------------------------------------
Shader "Shader Forge/Diffuse" {
    Properties {
        _MinColor ("MinColor", Color) = (1,0,0,1)
        _MaxColor ("MaxColor", Color) = (0,1,0.006896496,1)
        _Health ("Health", Range(0, 1)) = 0
        [HideInInspector]_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
    }
    SubShader {
        Tags {
            "Queue"="AlphaTest"
            "RenderType"="TransparentCutout"
        }
        Pass {
            Name "FORWARD"
            Tags {
                "LightMode"="ForwardBase"
            }
            
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #define UNITY_PASS_FORWARDBASE
            #include "UnityCG.cginc"
            #pragma multi_compile_fwdbase_fullshadows
            #pragma exclude_renderers gles3 metal d3d11_9x xbox360 xboxone ps3 ps4 psp2 
            #pragma target 3.0
            uniform float4 _MinColor;
            uniform float4 _MaxColor;
            uniform float _Health;
            struct VertexInput {
                float4 vertex : POSITION;
                float2 texcoord0 : TEXCOORD0;
            };
            struct VertexOutput {
                float4 pos : SV_POSITION;
                float2 uv0 : TEXCOORD0;
            };
            VertexOutput vert (VertexInput v) {
                VertexOutput o = (VertexOutput)0;
                o.uv0 = v.texcoord0;
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex );
                return o;
            }
            float4 frag(VertexOutput i) : COLOR {
                float2 node_7657 = (i.uv0*2.0+-1.0);
                float2 node_6660 = node_7657.rg;
                float node_9531 = ((atan2(node_6660.g,node_6660.r)/6.28318530718)+0.5);
                float node_6063 = length(node_7657);
                float node_5128 = floor((0.3+node_6063));
                float node_459 = ((1.0 - ceil(((1.0 - node_9531)-_Health)))*node_5128*(1.0 - floor(node_6063)));
                clip(node_459 - 0.5);
////// Lighting:
////// Emissive:
                float3 node_8440 = lerp(_MinColor.rgb,_MaxColor.rgb,_Health);
                float3 emissive = node_8440;
                float3 finalColor = emissive;
                return fixed4(finalColor,1);
            }
            ENDCG
        }
        Pass {
            Name "ShadowCaster"
            Tags {
                "LightMode"="ShadowCaster"
            }
            Offset 1, 1
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #define UNITY_PASS_SHADOWCASTER
            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            #pragma fragmentoption ARB_precision_hint_fastest
            #pragma multi_compile_shadowcaster
            #pragma exclude_renderers gles3 metal d3d11_9x xbox360 xboxone ps3 ps4 psp2 
            #pragma target 3.0
            uniform float _Health;
            struct VertexInput {
                float4 vertex : POSITION;
                float2 texcoord0 : TEXCOORD0;
            };
            struct VertexOutput {
                V2F_SHADOW_CASTER;
                float2 uv0 : TEXCOORD1;
            };
            VertexOutput vert (VertexInput v) {
                VertexOutput o = (VertexOutput)0;
                o.uv0 = v.texcoord0;
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex );
                TRANSFER_SHADOW_CASTER(o)
                return o;
            }
            float4 frag(VertexOutput i) : COLOR {
                float2 node_7657 = (i.uv0*2.0+-1.0);
                float2 node_6660 = node_7657.rg;
                float node_9531 = ((atan2(node_6660.g,node_6660.r)/6.28318530718)+0.5);
                float node_6063 = length(node_7657);
                float node_5128 = floor((0.3+node_6063));
                float node_459 = ((1.0 - ceil(((1.0 - node_9531)-_Health)))*node_5128*(1.0 - floor(node_6063)));
                clip(node_459 - 0.5);
                SHADOW_CASTER_FRAGMENT(i)
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
    CustomEditor "ShaderForgeMaterialInspector"
}

------------------------------------------------------
結果圖:






2016年4月5日 星期二

Unity C# 按鈕 開啟檔案(text)

使用別人寫好的軟體,有請讀我的按鈕,點擊後會自動開啟請讀我文字檔案的內容呈現。
空閒的時間試寫了簡單的程式。

※ 最主要注意的地方是: 
    Application.dataPath 路徑是指的應用程式 目前的路徑。
    如果使用者發佈,要特別注意就是路徑上的問題。
    
※ 以範例程式來說明: 
    發佈以下程式,執行結果是會出錯的,因為他讀不到檔案路徑。
    發佈前,要呼叫的文字檔案請放在(發佈檔案名稱_data) 位置。

範例程式:

using UnityEngine;
using System.Diagnostics;

public class ThreadTest : MonoBehaviour {
    void OnGUI() {
        // 請讀我按鈕
        if (GUI.Button(new Rect(Screen.width / Screen.width * 500, Screen.height / Screen.height * 50, 100, 30), "請讀我"))
            // 路徑要注意
            getStartImportText(Application.dataPath + "/ReadMe.txt");
    }


    //讀取路徑
    public void getStartImportText(string path)
    {
        Process.Start(path);
    }
}

--------------------
結果圖: 
     

Unity C# 使用者輸入錯誤 (整數)

using UnityEngine;
using System.Collections;
using System;
using System.Windows.Forms;

public class ThreadTest : MonoBehaviour {

    string x = "";  // 數入字串

    // 整數判斷
    bool setNumber() {

        int numX;  // 整數

        bool intSw = Int32.TryParse(x, out numX);

        return intSw;
    }

    void OnGUI() {

        inputNumber();
        if (GUI.Button(new Rect(UnityEngine.Screen.width/UnityEngine.Screen.width, UnityEngine.Screen.height/UnityEngine.Screen.height * 50, 100 , 30),"確定")) {
            if (x.Equals(""))
                MessageBox.Show("不能空白");
            else {
                if (setNumber().Equals(true)) MessageBox.Show("正確");
                else MessageBox.Show("只能輸入整數");
            }
        }
    }

    // GUILayout
    void inputNumber() {
        GUILayout.BeginArea(new Rect(UnityEngine.Screen.width/ UnityEngine.Screen.width, UnityEngine.Screen.height/ UnityEngine.Screen.height, 100, 50));
        GUILayout.BeginHorizontal();
        x = GUILayout.TextField(x, 100);
        GUILayout.EndHorizontal();
        GUILayout.EndArea();
    }
}
--------------------------------
執行結果:

     空白結果


    輸入錯誤


    輸入正確


Unity C# 取得滑鼠座標(螢幕座標,非遊戲裡面座標)

取得桌面滑鼠座標,非Unity 發佈 後遊戲座標。
請記得 using System.Drawing,如果開發者沒有這個類別。
請自行下載System.Drawing dll 檔案。
System.Drawing dll 下載
------------------------------------------

/*********************************************************************************
 * 模擬滑鼠 user32
 * 參考文獻 : http://pinvoke.net/default.aspx/user32.mouse_event
             https://msdn.microsoft.com/zh-tw/library/windows/desktop/ms646260(v=vs.85).aspx
 ********************************************************************************/

using UnityEngine;
using System.Collections;
using System.Threading;
using System.Drawing;
using System.Runtime.InteropServices;

class MouserClass {

    [DllImport("user32")]
    static extern bool GetCursorPos(ref Point getPoint);//取得滑鼠座標

    private Point getPoint;

    private bool getViewSw;

    // 取得滑鼠開關
    public bool getViewSwmassage(bool getViewSw)
    {
        return this.getViewSw = getViewSw;
    }

    //取得當前滑鼠偵測座標
    public string getMosuPointSwMessage()
    {
        string mosuPointSwMessage = (getViewSw.Equals(true)) ? "正在偵測" : "取消偵測";
        return mosuPointSwMessage;
    }

    //取得當前滑鼠座標
    public void GetmouserPostatic()
    {
        while (getViewSw.Equals(true))
        {
            GetCursorPos(ref getPoint);
            
        }
        Thread.Sleep(1000);
    }

    //取得滑鼠座標
    public string getMousePosistionMessage()
    {
        return getPoint.ToString();
    }

    // 終止所有執行緒
    public void Stop()
    {
        getViewSw = false;
    }
}


public class ThreadTest : MonoBehaviour {

    MouserClass mouserClass;
    GUIStyle guistyle;

    Thread GetmousePointTime;
    public bool getMousePosistionSw = true;

    void Start() {
        mouserClass = new MouserClass();
        guistyle = new GUIStyle();
    }

    void Update() {

        if (getMousePosistionSw.Equals(true))
        {
            // 取得當前滑鼠
            GetmousePointTime = new Thread(mouserClass.GetmouserPostatic);
            GetmousePointTime.Start();
        }

        mouserClass.getViewSwmassage(getMousePosistionSw);
    }

    void OnGUI() {

        guistyle.fontSize = 30;
        guistyle.normal.textColor = UnityEngine.Color.white;

        // 讀取執行緒當前滑鼠座標
        if (GUI.Button(new Rect(Screen.width / Screen.width * 5, Screen.height / Screen.height * 50, 100, 30), "當前滑鼠座標"))
            getMousePosistionSw = !getMousePosistionSw;
        GUI.Label(new Rect(Screen.width / Screen.width * 110, Screen.height / Screen.height * 50, 50, 20), mouserClass.getMosuPointSwMessage(), guistyle);
        GUI.Label(new Rect(Screen.width / Screen.width * 230, Screen.height / Screen.height * 50, 50, 20), mouserClass.getMousePosistionMessage(), guistyle);
    }

    // 關掉軟體
    void OnApplicationQuit()
    {
        mouserClass.Stop();
    }
}

---------------------------------------------------
執行結果:


Unity C# 執行緒 使用方法(Thread)

Thread (執行緒) 語法:

     using System.Threading;  // 匯入 Thread 類別

    Thread 變數名稱 = new Thread(執行緒執行方法);
    變數名稱.Start();

   void 執行續方法() {
        while (執行續開關) {
            //執行緒執行動作 ........ 
        }
        執行緒.Sleep(1000);
    }

C# 以下範例程式:
執行緒注意地方 紅色標記。

using UnityEngine;
using System.Collections;
using System.Threading;

public class A {

    bool sw;   // Thread sw (執行緒開關)

    // 給值開關
    public bool setSw(bool sw) {
        return this.sw = sw;
    }

    // 取值開關
    public bool getSw() {
        return this.sw;
    }

    // A Class Thread Message (A類別執行緒執行)
    public void Message() { 

        while (sw.Equals(true)){
            Debug.Log("這是A類別執行緒");
        }
        Thread.Sleep(1000); // 暫停一秒
    }

    // close Applicaction Thread close (關掉應用程式執行緒關掉)
    public void Stop() {
        sw = false;
    }
}

public class ThreadTest : MonoBehaviour {

    Thread test1, test2; // Thread declare (執行緒宣告)
    A a = new A();       // A class declare (A類別宣告)

    public bool testSw = false;  // Thread Sw (執行續開關)

    void Update() {

        if (a.setSw(testSw).Equals(true)) {

            test1 = new Thread(a.Message);
            test1.Start();

            test2 = new Thread(Message);
            test2.Start();
        }
    }

    // close Applicaction (關掉應用程式)
    void OnApplicationQuit() {
        a.Stop();
    }

    // ThreadTest class Thread Message (ThreadTest 類別執行緒)
    void Message() {

        while (a.getSw().Equals(true)){
            Debug.Log("這是本類別執行緒");
        }
        Thread.Sleep(1000); // 暫停一秒
    }
}

-----------------------------------------------

執行結果 :